首屏文本必须写死在html最前面,即等直接位于靠前位置、无嵌套、无延迟标记;弱网下白屏主因是文本未进入初始渲染路径,而非js未加载。

首屏文本必须写死在 HTML 最前面
弱网下用户看到白屏,往往不是因为 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" - 探测地址选静态资源,如
/ping?_t=123456789,超时设为 1500ms - 提示文案用
textContent插入,不是innerHTML,防 XSS - 降级样式只作用于文本元素,避免误改布局;消失后立刻移除
<style></style>节点
关键资源必须显式提权,不能靠默认调度
fetchpriority="high" 不是锦上添花,是告诉浏览器“这个资源比其他所有东西都更早需要”。不加,它默认是 low,哪怕它是首屏 <h1></h1> 的背景图,也会和文本抢带宽,导致文字等样式就绪才出现。
容易踩的坑:只加 fetchpriority="high" 却漏掉 loading="eager";给字体文件漏加 crossorigin 导致 CORS 失败;对埋点脚本也设 high,挤占文本通道。
前端设计与 UI/UX 全方位优化专家。覆盖视觉层次、排版系统、色彩理论、响应式布局、交互体验、动画动效、无障碍访问、性能优化八大维度,帮助开发者将普通页面升级为高品质产品级界面。前端设计与 UI/UX 全方位优化专家。覆盖视觉层次、排版系统、色彩理论、响应式布局、交互体验、动画动效、无障碍访问、性能优化八大维度,帮助开发者将普通页面升级为高品质产品级界面。
降级逻辑必须由 JS 主动触发,不能依赖 CSS 或 SSR
弱网探测不能靠 navigator.onLine,它只返回 true/false,完全脱离真实体验。必须用轻量 fetch 探测静态资源响应时间,连续两次 >800ms 才触发降级。降级样式也不能写进 CSS 文件里,否则 SSR 会一并输出,污染 SEO 和爬虫。
真正有效的做法是:JS 探测确认弱网后,立刻插入一段内联 <style></style>,仅覆盖文本类元素(<h1></h1>、<p></p>、<span></span>),确保至少以系统字体、14px、黑灰配色呈现。
HTML 结构本身决定容错上限
很多团队花大量精力优化 JS 加载、拆包、SSR hydration,却忽略一个事实:弱网下用户能否看到字,取决于 HTML 是否足够“原始”——有没有冗余 wrapper、是否用了语义错误的标签、DOM 是否扁平、<main></main> 是否真的在最前。结构一旦写错,再好的 JS 降级也救不回首屏空白。
最难的不是加几个属性,而是把“文本可读”这件事从样式层剥离出来,变成 HTML 结构、资源调度、JS 降级三层协同的确定性流程。任何一层断掉,弱网用户看到的就是白屏。
尤其要注意:<main></main> 必须且只能出现一次,不能嵌套在 <header></header> 或 <nav></nav> 内;<section></section> 必须自带标题,否则优先用 <div>;标题层级不能跳级,<code><h1></h1> 后直接 <h4></h4> 会让辅助技术误判内容结构。










