弱网下首屏必须依赖初始html中靠前、无嵌套、带lang属性的文本节点和最小dom,禁用延迟加载与js补救,确保流式解析即刻渲染。

弱网下 HTML 结构本身就能决定首屏是否“有东西可看”——不是靠 JS 补救,而是初始 HTML 里有没有真正能渲染的文本节点和最小 DOM。
首屏文本必须写死在 HTML 最前面,不包裹、不延迟
浏览器解析 HTML 是流式的,<h1></h1>、<p></p>、<button></button> 这类文本级元素如果被包在五层 <div> 里,或用 <code>data-lazy 占位符包裹,它们就不会进入初始渲染路径。用户看到的就是白屏或骨架屏卡住。
- 首屏文本节点必须直接出现在
靠前位置,不嵌套在无语义容器中(如<div class="wrapper"><div><div> <h1>...) </h1> <li>禁用 <code>display: contents替代文本容器——Safari 15.4 之前不支持,会丢文本渲染上下文 - 所有文本元素必须带
lang属性(如<h1 lang="zh-CN"></h1>),避免弱网下字体回退引发重排 - 用
<div data-lazy="comments"></div>这类标记代替真实内容,不带子节点、不设innerHTML - 禁止任何
data-autoplay或data-init类自动触发逻辑;初始化必须显式控制,比如只在networkStatus === 'good'时调用initComments() - 深度 >3 的嵌套容器(如
div > div > div > article)用display: contents扁平化(注意兼容性),否则多余 wrapper 会触发额外 layout - 降级静态内容必须放在
内、紧贴对应区块之后,例如:<div id="product-list"></div> <noscript><section><h2>推荐商品</h2> <ul><li>无线耳机 — ¥199</li></ul></section></noscript> - 不能把
<noscript></noscript>放进<div id="product-list"> 里面——它不会替换该 div,而是作为兄弟节点插入 <li>务必加 <code>aria-label等辅助属性,否则屏幕阅读器无法识别这是降级内容 - 禁用内联样式;降级内容应继承全局 CSS,否则 JS 禁用时样式可能丢失
-
<main></main>内只保留 LCP 元素所需最小 DOM:标题、主图(带loading="eager")、核心按钮 - 关键 CSS 必须提取并内联进
<style></style>,仅含 layout/color/font-size 等基础样式;动画、媒体查询全部剥离延迟加载 - 所有
fetch必须配AbortController,超时设为1500ms,主动中断而非等待自然超时 - 连续两次响应时间 >
800ms就标记弱网,立刻注入降级样式(系统字体、14px、黑灰配色),这个逻辑必须由 JS 动态注入,不能写在 CSS 里
非首屏内容统一用语义化占位符,不挂载真实 DOM
弱网时 DOM 节点越多,layout thrashing 越严重,主线程越容易被阻塞。把评论区、推荐列表、侧边栏这些非 LCP 元素全部从初始 HTML 剥离,只留占位结构。
<noscript></noscript> 只用于 JS 彻底禁用场景,不能当降级模板用
<noscript></noscript> 不是响应式容器,它只在页面加载时 JS 被禁用才生效,且不会重渲染。把它当“备用 DOM 模板”写在 JS 启用的页面里,根本不会被解析。
DOMContentLoaded 不能成为首屏可用的依赖节点
这是最常被忽略的底层判断。弱网下 JS 执行严重滞后,但 HTML 解析很快。如果首屏依赖 DOMContentLoaded 后才插入文本或样式,用户就会等几秒白屏。
结构降级的关键不在“删多少”,而在“留什么”——留下的每个节点都得能独立参与首次渲染,且不依赖后续 JS 或样式注入。一旦开始用 JS 拼 DOM、用 CSS 控制显隐、用 defer 脚本等资源,就已脱离弱网友好结构的范畴。











