弱网下首屏白屏主因是dom未及时构建,需将文本节点直接置于body前部且无包裹;必须显式设置fetchpriority="high"与loading="eager"配对,并用js轻量探测真实网络状况后注入窄范围降级样式。

弱网下白屏,不是 JS 没加载完,而是浏览器压根没把 <h1></h1> 或 <p></p> 构建进 DOM 树——它们被包在五层 <div> 里,或塞进了 <code><template></template>,解析器流式读到时跳过不渲染。
首屏文本必须写死在 最前面
真正能立刻显示的,只有出现在 靠前位置、无包裹、无延迟标记的纯文本节点。常见错误包括:<div data-lazy="title"></div> 空容器、<section><div><div><h1>欢迎页</h1></div></div></section>、用 visibility: hidden 控制显隐。
-
<h1></h1>、<p></p>、<button></button>必须直接出现在内,不嵌套在<div class="wrapper"> 或 <code><section data-lazy="true"></section>中 - 禁用
display: contents替代文本容器——Safari 15.4 之前版本会丢文本渲染上下文 - 所有文本级元素必须带
lang属性,如<p lang="zh-CN"></p>,避免字体 fallback 引发重排(CLS) -
<img src="hero.jpg" fetchpriority="high" loading="eager">——首屏图片必须显式排除懒加载 -
<link rel="preload" href="text-font.woff2" as="font" type="font/woff2" crossorigin fetchpriority="high">——字体不加crossorigin会因 CORS 失败 - 非可视资源如广告 SDK、埋点脚本,统一设
fetchpriority="low" - 容易踩的坑:只加
fetchpriority="high"却漏掉loading="eager";给字体文件漏加crossorigin;对埋点脚本也设high,挤占文本通道 - 探测地址选静态资源,如
/ping?_t=123456789,超时设为1500ms - 降级样式不能写进 CSS 文件里,否则 SSR 会一并输出,污染 SEO 和爬虫
- 真正有效的做法是:JS 探测确认弱网后,立刻插入一段内联
<style></style>,仅覆盖文本类元素(<h1></h1>、<p></p>),确保至少以系统字体、14px、黑灰配色呈现 - 提示文案用
textContent插入,不是innerHTML
fetchpriority 和 loading 必须显式配对使用
fetchpriority="high" 不是锦上添花,是告诉浏览器“这个资源比其他所有东西都更早需要”。不加,它默认是 low,哪怕它是首屏 <h1></h1> 的背景图,也会和文本抢带宽,导致文字等样式就绪才出现。
弱网探测与降级必须由 JS 主动触发
弱网探测不能靠 navigator.onLine,它只返回 true/false,完全脱离真实体验。必须用轻量 fetch 探测静态资源响应时间,连续两次 >800ms 才触发降级。
最常被忽略的是:降级逻辑必须独立于任何 CSS 或 SSR 输出,且内联 <style></style> 的选择器范围要窄——只作用于文本节点,否则可能意外覆盖按钮、链接等交互元素的可点击区域。











