为什么preload预加载字体会阻塞浏览器页面渲染?
现象原因分析
这个表现是浏览器的首屏资源调度规则和preload的优先级机制共同作用的结果,具体逻辑如下:
- 未开启字体预加载时:
浏览器解析完DOM和CSSOM后,检测到当前页面没有用到你指定的woff字体,不会主动发起字体请求,此时body末尾的同步脚本还没开始加载执行,浏览器会先完成首屏渲染(也就是你看到的红色方块先渲染出来),之后再加载执行同步脚本。 - 新增字体预加载配置后:
<link rel="preload" as="font">会将标记的字体定义为首屏必需的高优先级资源,浏览器强制要求这类资源加载完成后,再触发首屏渲染,避免后续用到字体时出现样式闪动问题。- 你放在body末尾的
<script src="./index.js">是同步脚本,本身就具备阻塞DOM解析和首屏渲染的特性,优先级和preload字体属于同一调度层级。 - 此时浏览器会并行发起字体和脚本的请求,但首屏渲染必须同时满足「preload高优先级资源加载完成」、「同步脚本加载并执行完成」两个条件,自然就出现了渲染推迟到脚本执行结束的现象。
- 额外细节:即使是同域字体的preload也需要配置
crossorigin属性,这会让字体请求走CORS校验流程,一定程度上也会拉长资源加载耗时,进一步放大渲染滞后的感知。
可选优化方案
如果不需要字体在首屏立刻生效,可以去掉字体预加载配置;如果脚本不需要阻塞首屏渲染,可以给script标签添加defer或async属性,解除脚本对首屏渲染的阻塞。
内容的提问来源于stack exchange,提问作者kevin
相关产品推荐
相关产品推荐

