前端性能优化:使用 preload 和 prefetch 预加载关键资源

2023-04-2420:54:05WEB前端开发Comments1,457 views字数 5245阅读模式

前端性能优化,我们通常会想到启用压缩,压缩资源文件大小。或者启用浏览器缓存,可以起到较少 HTTP 请求,优化资源加载速度的效果,但这些手段主要提升重复访问相同资源时的加载速度。默认情况下,浏览器只会先加载 HTML 中声明的资源。如果没有声明,浏览器是不会提前加载资源的。那有没有什么办法能提前加载页面所需资源,优化首次的加载速度呢?文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/37103.html

很幸运,随着 Web 技术的发展,现代的浏览器可以做到提前加载页面所需资源了。使用资源提示伪指令(https://www.w3.org/TR/resource-hints/):prefetch 和 preload,可以提前告知浏览器加载资源,从而可以缩短网站的(首次)加载速度,优化页面性能。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/37103.html

什么是<link rel=”prefetch“>?

prefetch (预取用),它可以利用浏览器的空闲时间来预取用(下载)用户可能在不久的将来会访问的资源。换句话说,浏览器将提前加载用户将来可能要访问的页面资源。浏览器将这些提前下载的资源存储在本地缓存中,以便在用户最终访问该页面的资源时能更快地发送请求的信息,并非常快速的加载资源。所以,使用 prefetch 技术,不会减少 HTTP 请求,但会提升使用资源时的资源加载速度。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/37103.html

前端性能优化:使用 preload 和 prefetch 预加载关键资源文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/37103.html

Prefetch 使用场景和注意事项

prefetch 预取用的资源在加载完成后,并不会像加载普通的资源那样,加载完成后浏览器不会马上解析资源,而只是缓存到本地。不立即执行解析,特别是不立即解析脚本文件,就意味着不会阻塞页面加载其它资源。只有用户访问了调用这些资源的 页面的时候,才会立刻解析。也就是说,prefetch 的使用场景是用来提前加载那些用户将来会访问的页面资源,优化将来会访问页面资源的首次加载速度。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/37103.html

具体的场景例如:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/37103.html

  • 当一系列页面很像幻灯片时,请加载接下来的1-3页,之前的1-3页(假设它们不占很大)。
  • 加载要在网站上大多数页面上使用的图像。
  • 将搜索结果的下一页加载到您的网站上。

当然,使用 prefetch 预取用技术也有需要注意的事项。那就是当用户始终都没有访问 prefetch 预期在将来可能访问的页面资源时,使用 prefetch 就可能会花费额外的带宽(流量)。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/37103.html

Prefetch 浏览器支持情况

前端性能优化:使用 preload 和 prefetch 预加载关键资源文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/37103.html

浏览器对 prefetch 的支持情况还是不错的,除了 Safari 浏览器目前还不支持,其余的主流浏览器都已经支持了,甚至连 IE11 都支持了。而且在不支持 prefetch 的浏览器中,浏览器只会忽略它,不会带来额外的影响。所以使用 prefetch 优化性能,遵循了渐进式用户体验提升的原则。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/37103.html

Prefetch 资源如何选择?

前文提到了,使用 prefetch 用来加载稍后会用到的资源,如果用户没有访问期望的页面,使用 prefetch 就可能会花费额外的带宽。那么我们应该怎么选择要加载的资源,避免额外消耗呢?文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/37103.html

首先,我们需要知道,浏览器对 HTML 页面中调用的各种资源是有着不同级别的优先级(Priorty )区分的。在 Chrome 浏览器中,我们可以按 F12 键,打开 DevTools 工具面板,然后点击 Network 标签,接着右键点击 Name 标题栏,在弹出的菜单中选择 Priorty 选项(默认是不展示的),这样就可以看到浏览器的资源优先级的列数据了。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/37103.html

前端性能优化:使用 preload 和 prefetch 预加载关键资源文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/37103.html

如图所示,我们可以看到优先级高的资源(显示为 Highest 或者 High 的资源)基本都是 CSS、JS和字体资源。那么我们使用 prefetch 加载资源也应该选择这些优先级高的资源。应该使用 prefetch 加载那些用户使用比较频繁的模块资源,这样用户接下来大概率会使用到这些资源,从而避免 prefetch 加载的资源用户没有使用,而造成额外的带宽消耗。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/37103.html

什么是<link rel=”preload“>?

前端性能优化:使用 preload 和 prefetch 预加载关键资源文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/37103.html

preload (预加载),它告诉浏览器如何将特定资源提前提取到当前页面中。本质上,它会在当前页面开始加载之前在浏览器后台提前下载资源。并且,浏览器通常以中等优先级,而不是布局阻塞的方式来获取此资源。使用 preload 提前加载的资源,不会花费额外的带宽。也就是不会产生额外的 HTTP 请求,这个是 preload 与 prefetch 不同的地方之一。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/37103.html

Preload 使用场景和注意事项

preload 和 prefetch 类似,使用 preload 加载的资源在加载完成后浏览器也不会立刻解析。preload 预加载加载资源的使用场景是 preload 预加载当前访问页面会立刻使用到的资源。虽然使用 preload 提前加载的资源,不会花费额外的带宽,但如果 preload 预加载的资源,在加载完成后3秒钟后还未被使用,这时(Chrome)浏览器在控制台中会显示警告,提示预加载的资源在当前页面没有被引用。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/37103.html

Preload 浏览器支持情况

前端性能优化:使用 preload 和 prefetch 预加载关键资源文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/37103.html

preload 比 prefetch 的 Web 标准更新(https://w3c.github.io/preload/)来得更晚,但可以看到,浏览器对 preload 的支持也是不错的,目前主流浏览器只有 IE11 不支持。同 prefetch 的情况一样,在不支持的浏览器中,也是直接忽略 preload 的,也不会产生任何负面的影响。也遵循了渐进式用户体验提升的原则。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/37103.html

Preload 资源如何选择?

preload 资源的选择规则就简单很多, prload 预加载当前页面就要用到的资源。当然,也是选择优先级高的资源。使用过 lighthouse 前端性能分析工具的同学应该都知道,在 lighthouse 性能优化指导规则中就有一项是“预加载关键请求”。指的就是使用 preload 预加载当前页面的优先级高(关键)的资源。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/37103.html

Preload 和 Prefetch 的调用方式

preload 和 prefetch 的使用方式一样,采用 <link rel=”prefetch“> 或者 <link rel=”preload“> 方式加载资源文件,废话不多说,直接上代码:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/37103.html

<head>
    <meta charset="utf-8">
    <title>JS and CSS preload example</title> 
    <!-- 在 header 区域加入 -->
    <link rel="preload" href="style.css" as="style">
    <link rel="preload" href="main.js" as="script">
    <link rel="prefetch" href="news.js" as="script">
    <link rel="stylesheet" href="style.css">
</head>

<body>
    <h1>bouncing balls</h1> <canvas></canvas>
    <script src="main.js" defer></script>
</body>

可以看到,prefetch 和 preload 调用方式很简单。使用 <link> 标签,设置 rel 属性设置值为 preload 或者 prefetch, 标签成为我们想要的任何资源的预加载器。另外,还需要指定:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/37103.html

  • href:资源的路径;
  • as:资源的类型;

示例代码中 preload 和 prefetch 了 CSS 和 JavaScript 文件,并且在页面中就立刻调用了 preload 加载的资源。而 prefetch 的资源,在页面中则没有立刻被调用,prefetch 的 news.js 文件只是提前加载下来,保存到了浏览器的缓存中,以便稍后在访问 news (相关)页面时可以立即解析它。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/37103.html

Preload 和 Prefetch 支持哪些类型的资源?

除了 prefetch 和 preload CSS 和 JS 外,还可以加载很多其它类型的资源文件。prefetch 和 preload 可以支持许多不同的资源类型,在 <link> 元素中使用 as 属性设置资源类型,可选的值为:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/37103.html

  • audio:音频文件,通常在中使用<audio>。
  • document:打算由<frame>或嵌入的HTML文档<iframe>。浏览器未实现
  • embed:要嵌入<embed>元素内的资源。
  • fetch:通过提取或XHR请求访问的资源,例如ArrayBuffer或JSON文件。
  • font:字体文件。
  • image: 图像文件。
  • object:要嵌入<object>元素内的资源。
  • script:JavaScript文件。
  • style:CSS样式表。
  • track:WebVTT文件。
  • worker:JavaScript网络工作者或共享工作者。
  • video:视频文件,通常在中使用<video>。 浏览器未实现

另外,<link> 元素可以接受 type 属性,该属性包含元素指向的资源的 MIME 类型。这在预加载资源时特别有用,浏览器将使用 type 属性值来计算是否支持该资源,并且仅在支持的情况下才下载该属性,否则将忽略该属性。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/37103.html

<head>
    <meta charset="utf-8">
    <title>Video preload example</title>
    <link rel="preload" as="image" href="/favicon.ico" type="image/x-icon">
    <link rel="preload" as="image" href="/static/images/app.svg" type="image/x-svg">
    <link rel="preload" as="image" href="/static/images/logo.png" type="image/png">
    <link rel="preload" href="sintel-short.mp4" as="video" type="video/mp4">
    <link rel="preload" href="sintel-short.webm" as="video" type="video/webm">
</head>

<body> 
    <video controls>
        <source src="sintel-short.mp4" type="video/mp4">
        <source src="sintel-short.webm" type="video/webm">
        <p>Your browser doesn't support HTML5 video. Here is a <a href="sintel-short.mp4">link to the video</a> instead.
        </p>
    </video> 
</body>

在上面 DEMO 页面的使用场景下,支持 MP4 的浏览器将预加载并使用 MP4 格式的文件,从而有望使视频播放器对用户更流畅/响应更快。而不支持 MP4 的浏览器则仍然可以加载 WebM 版本的资源,但是无法获得预加载的优势。这个示例列举了如何将预加载的内容与渐进增强的原理相结合。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/37103.html

启用 CORS 资源提取

除了提取相同域名下的资源, preload 和 prefetch 还支持预加载其它域名的资源。启用 CORS 资源提取,例如:fetch(),XMLHttpRequest 或字体。这个时候,就需要特别注意,需要设置 crossorigin 属性到 <link> 标签。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/37103.html

<head>
    <meta charset="utf-8">
    <title>Web font example</title>
    <link rel="preload" href="fonts/cicle_fina-webfont.woff2" as="font" type="font/woff2" crossorigin>
    <link rel="preload" href="fonts/zantroke-webfont.woff2" as="font" type="font/woff2" crossorigin>
    <link href="style.css" rel="stylesheet">
</head>

<body></body>

需要特别注意的是,在调用跨域的字体资源的时候,即使获取的字体资源不是跨源的,也需要将属性设置为匹配资源的 CORS 和凭据模式。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/37103.html

使用 Preload 可以提升多少性能?

最后让我们来看看使用预加载可以带来多少性能提升?文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/37103.html

前端性能优化:使用 preload 和 prefetch 预加载关键资源文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/37103.html

无预载链接,styles.css并且ui.js只要求后,app.js已被下载,解析和执行。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/37103.html

如图所示,在没有使用 preload 加载资源前,浏览器在下载,解析和执行完页面中的 .js 文件(app.js)后,才会开始加载它之后的 2 个资源。也就是说下载解析 .js 文件,会阻碍浏览器加载在它之后的其它资源的加载解析。但是我们知道,图中 ui.js 和 style.css 这些资源也很重要,应该尽快下载。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/37103.html

前端性能优化:使用 preload 和 prefetch 预加载关键资源文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/37103.html

带有预加载链接,styles.css、ui.js 和 app.js 同时请求。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/37103.html

如图所示,使用 preload 潜在的性能提升是基于声明了预加载链接,浏览器将能够在多早之前启动资源请求。例如,如果 app.js 花费 200 毫秒来下载,解析和执行,则每个资源的潜在节省为200毫秒,因为 app.js 它不再是每个请求的瓶颈,在加载 app.js 的时候不会阻塞其它资源的下载。而是会几乎同时加载这些资源文件,也就是这里至少能够节省200毫秒的资源加载速度。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/37103.html

  • 本站内容整理自互联网,仅提供信息存储空间服务,以方便学习之用。如对文章、图片、字体等版权有疑问,请在下方留言,管理员看到后,将第一时间进行处理。
  • 转载请务必保留本文链接:https://www.cainiaoxueyuan.com/gcs/37103.html

Comment

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定