You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Preload本应不阻塞渲染,为何示例中脚本需等字体下载后执行?

嘿,这个问题我之前也碰到过,是个很容易踩的preload误区,我来给你理清楚为什么会这样:

核心原因拆解

  1. preload只是"预获取",不是"预解析"
    你用rel="preload"只是让浏览器提前下载了那个字体样式表资源,但并没有立刻把它当成样式表来处理——直到onload触发后把rel改成stylesheet,浏览器才会开始解析这个样式表,这时候才会触发里面Roboto和Material Icons字体的下载请求。

  2. 字体默认是阻塞性资源,且会延迟window.onload
    Chrome里字体默认的font-display值是block,这意味着浏览器会先隐藏文本,直到对应字体加载完成(避免FOIT,Flash Of Invisible Text)。更关键的是,window.onload事件的触发条件是所有页面关联资源(包括DOM、样式表、脚本、图片、字体等)全部加载完毕,所以哪怕页面已经显示了,只要字体还在下载,window.onload就不会执行。

验证与修复方案

如果你想让window.onload不用等字体加载完才触发,最简单的办法就是修改字体样式请求,加上font-display=swap参数,让浏览器先显示系统 fallback 字体,不阻塞渲染和window.onload:

<html>
<head>
  <!-- 添加&display=swap,改变字体的加载策略 -->
  <link rel="preload" onload="this.rel = 'stylesheet'" as="style" href='https://fonts.googleapis.com/css?family=Roboto:400,100,500,700,900,800|Material+Icons&display=swap'>
</head>
<body>
  Hello
  <script>
    window.onload = function () {
      console.log('Loaded')
    }
  </script>
</body>
</html>

切换到慢速网络测试的话,你会发现:

  • 页面会立刻显示用系统字体渲染的"Hello",不会空白等待
  • console.log('Loaded')会在页面基础资源加载完后立刻执行,不用等字体下载完成

另外补充个小知识点:如果你的需求是提前加载字体本身而非样式表,也可以直接preload字体文件,但需要拿到字体的具体URL(可以从开发者工具的网络请求里找),不过这种方式不如修改font-display来得便捷。

内容的提问来源于stack exchange,提问作者George Paouris

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 07:37:32