js延迟加载_性能优化之预加载资源

本文介绍preload技术在前端开发中的应用,包括如何使用preload预加载关键资源如CSS、JS和字体文件,以及如何避免滥用preload导致性能问题。还讨论了不同资源加载的优先级规则,以及preload在动态加载场景下的最佳实践。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

预加载资源 preload

优化下一个页面显示的其中一个步骤,是可以在当前页面提前加载资源。包括css/'js'/'image'等。这时我们就可以使用到preload了。

preload 提供了一种声明式的命令,让浏览器提前加载指定资源(加载后并不执行),在需要执行的时候再执行。提供的好处主要是

  • 将加载和执行分离开,可不阻塞渲染和 document 的 onload 事件
  • 提前加载指定资源,不再出现依赖的 font 字体隔了一段时间才刷出

一、如何使用 preload?


<link rel="preload" href="/path/to/style.css" as="style" />


<script>const link = document.createElement("link");
link.rel = "preload";
link.as = "style";
link.href = "/path/to/style.css";document.head.appendChild(link);script>

说明:preload 不仅仅支持 css 的预加载,上述只是使用 css,作为样例。那么具体支持哪些呢?

二、注意事项

  1. 避免滥用 preload: 若不确定资源是必定会加载的,则不要错误使用 preload,以免本末倒置,给页面带来更沉重的负担。

  2. 避免混用 preload 和 prefetch preload 和 prefetch 混用的话,并不会复用资源,而是会重复加载。

  3. 避免错用 preload 加载跨域资源。 crossorigin 属性在加载字体的时候是必须的,即便字体没有跨域是在自己公司的服务器上,因为用户代理必须采用匿名模式来获取字体资源。为什么?请见这里和阿里:preload 预加载资源

三、不同资源加载的优先级规则

我们先来看一张图:

111f5b28b406fe80a7b3c508717b3339.png一共分成五个级别:

  • Highest 最高
  • Hight 高
  • Medium 中等
  • Low 低
  • Lowest 最低

html 主要资源,其优先级是最高的

70225392cac8429776b524f09e06b782.png
810803ff52154e7fb30552549a39b8bd.png

css 样式资源,其优先级也是最高的

70225392cac8429776b524f09e06b782.png

script 脚本资源,优先级不一

06917ab393cf0c2d75bcbb48efd40d0e.png9dc0848cda6ef39614a0eb42af52520d.png前三个 js 文件是写死在 html 中的静态资源依赖,后三个 js 文件是根据首屏按需异步加载的组件资源依赖,这正验证了这个规则。

font 字体资源,优先级不一

70afd7a0614d7c4fa45064cb8491be67.png00a95aa719d31ebfa7f28eee5585b5db.pngcss 样式文件中有一个 @font-face 依赖一个 font 文件,样式文件中依赖的字体文件加载的优先级是 Highest;在使用 preload 预加载这个 font 文件时,若不指定 crossorigin 属性(即使同源),则会采用匿名模式的 CORS 去加载,优先级是 High

看下图对比:

第一条 High 优先级,也就是 preload 的请求:267bed5d36e6b916710b4c544baf9c73.png

第二条 Highest 也就是样式引入的请求:3c8dbaf9d98770553caac371372ec24e.png

可以看到,在 preload 的请求中,缺少了一个 origin 的请求头字段,表示这个请求是匿名的请求。让这两个请求能共用缓存的话,目前的解法是给 preload 加上 crossorigin 属性,这样请求头会带上 origin, 且与样式引入的请求同源,从而做到命中缓存:

<link rel="preload" as="font" crossorigin href="https://at.alicdn.com/t/font_zck90zmlh7hf47vi.woff" />

四、预加载使用场景

字体提前加载

eb 字体是较晚才能被发现的关键资源中常见的一种。但是在用户体验对前端来说至关重要的现阶段前端开发来说,web 字体对页面的渲染也是至关重要。字体的引用被深埋在 css 中,即便预加载器有提前解析 css,也无法确定包含字体信息的选择器是否会真正作用在 dom 节点上。所以为了减少 FOUT(无样式字体闪烁,flash of unstyled text )需要预加载字体文件,有了 preload,一行代码搞定。

<link rel="preload" href="font.woff2" as="font" type="font/woff2" crossorigin />

注意:crossorigin 属性在加载字体的时候是必须的,即便字体没有跨域是在自己公司的服务器上,因为用户代理必须采用匿名模式来获取字体资源(为什么会这样呢?)。

动态加载,但不执行

通常我们可能想在当前页去加载下一页的资源,但是在媒婆 preload 的情况下,我们常常使用动态创建 script 标签的形式,但是动态创建 script 标签的话,js 代码会立即执行。在有了preload之后,就可以做到动态加载,延迟执行

let link = document.createElement("link");
link.href = "myscript.js";
link.rel = "preload";
link.as = "script";
document.head.appendChild(link);

上面这段代码可以让你预先加载脚本,下面这段代码可以让脚本执行

let script = document.createElement("script");
script.src = "myscript.js";
document.body.appendChild(script);

基于标记语言的异步加载

<link rel="preload" as="style" href="asyncstyle.css" onload="this.rel='stylesheet'" />

preload 的 onload 事件可以在资源加载完成后修改 rel 属性,从而实现非常酷的异步资源加载。

脚本也可以采用这种方法实现异步加载

难道我们不是已经有了,虽好,但却会阻塞 window 的 onload 事件。某些情况下,你可能希望这样,但总有一些情况你不希望阻塞 window 的 onload 。

举个例子,你想尽可能快的加载一段统计页面访问量的代码,但又不愿意这段代码的加载给页面渲染造成延迟从而影响用户体验,关键是,你不想延迟 window 的 onload 事件。

有了 preload, 分分钟搞定。

<linkrel="preload"as="script"href="async_script.js"onload="let script = document.createElement('script'); script.src = this.href; document.body.appendChild(script);"
/>

五、浏览器兼容性检测

其浏览器支持如下:

const isPreloadSupported = () => {
const link = document.createElement("link");
const relList = link.relList;

if (!relList || !relList.supports) {
return false;
}

return relList.supports("preload");
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值