一文搞懂网页资源请求优先级

先介绍几个概念

  1. Priority Hints优先级
  2. Chrome的5层优先级
  3. link标签的属性

了解Priority Hints

Priority Hints(优先级提示)是一种用于指导浏览器资源加载顺序的技术。它允许开发者向浏览器提供有关资源加载优先级的建议,以便浏览器更好地决定哪些资源应该优先加载。通过使用 Priority Hints,开发者可以提高关键资源的加载速度,从而改善页面性能和用户体验。

在 HTML 中,可以使用 <link> 元素的 rel 属性来添加 Priority Hints。具体来说,以下是一些常用的 Priority Hints 值:

  • preload:建议浏览器在页面加载过程中尽早加载该资源。
  • prefetch:建议浏览器在后台加载该资源,以备将来使用。
  • prerender:建议浏览器预渲染该资源,以提前生成即将展示给用户的页面。

例如,以下是一个使用 Priority Hints 的示例:

ini 复制代码
htmlCopy Code
<link rel="preload" href="path/to/resource" as="type" importance="high">

在这个示例中,rel="preload" 表示建议浏览器预加载资源,href 属性指定了要加载的资源路径,as 属性指定了资源的类型,importance="high" 表示该资源的优先级较高。

需要注意的是,浏览器对 Priority Hints 的支持程度可能有所不同,因此并非所有浏览器都会遵循开发者的建议。同时,开发者应该谨慎使用 Priority Hints,确保只对真正关键的资源进行优先加载指导,避免不必要的网络请求和带宽消耗。

最佳实践是结合其他性能优化技术(如资源合并、压缩、缓存等)来综合提高页面加载性能,并根据实际情况进行测试和优化。

Chrome的5层优先级

Chrome浏览器中的5层优先级指的是网络请求的优先级,这些优先级决定了浏览器在处理网络请求时的顺序和优先级。以下是Chrome浏览器中网络请求的5个优先级:

  1. 最高优先级(Highest): 该优先级通常用于处理关键资源,如页面的主要 HTML、JavaScript 和 CSS 文件。这些资源对于页面的加载和渲染至关重要。
  2. 较高优先级(High): 该优先级通常用于处理一些重要的资源,如页面中需要立即展示的图片、字体等。
  3. 默认优先级(Medium): 大多数网络请求的默认优先级,包括大多数的静态资源和异步加载的资源。
  4. 较低优先级(Low): 该优先级通常用于处理一些不太重要的资源,如异步统计脚本、广告等。
  5. 最低优先级(Lowest): 该优先级通常用于处理一些可延迟加载的资源,如某些后台任务、预取资源等。

这些优先级可以帮助浏览器更好地处理网络请求,确保关键资源能够尽快加载并渲染,提高用户的页面加载体验。在实际开发中,可以通过设置合适的资源加载优先级来优化页面加载性能。

我们可以Chrome浏览器的开发者工具,在Network面板中可以看到每一个请求的优先级,如下图所示。

如果你发现你的浏览器没有上图选中的列表,试试右键面板,然后访问下图所示的菜单项进行开启。

link属性

<link> 元素在 HTML 中用于定义文档与外部资源之间的关系。它支持多个属性,以下是常用的一些属性:

  1. rel:指定当前文档与所链接资源之间的关系类型。
  2. href:指定要链接的资源的 URL。
  3. type:指定被链接资源的 MIME 类型。
  4. media:指定样式表适用的设备或媒体类型。
  5. as:用于资源预加载时,指定链接资源的类型。
  6. crossorigin:表示是否跨域请求资源。
  7. integrity:指定链接资源的完整性校验值,用于验证资源的完整性。
  8. sizes:指定链接资源在不同显示设备上的尺寸。
  9. title:提供链接资源的标题或描述信息。

这些属性可以组合使用,以定义与链接资源之间的具体关系和特性。其中,relhrefas 属性对于资源预加载和预读取非常重要。

需要注意的是,不同的属性可能只适用于特定的链接资源类型(如样式表、图标、脚本等),并且浏览器对这些属性的支持程度也可能有所不同。在使用 <link> 元素时,建议参考相关文档和规范,了解每个属性的具体用法和兼容性要求。

加载资源优先级说明

  1. preload 使用 "as" 属性加载的资源将会获得与资源 "type" 属性所拥有的相同的优先级。比如说,preload as="style" 将会获得比 as="script" 更高的优先级
  2. 不带 "as" 属性的 preload 的优先级将会等同于异步请求

从上面了解到rel可以设置,预加载(preload)、预读取(prefetch)、预渲染prerender。那他们的区别?

预加载(preload)、预读取(prefetch)、预渲染prerender之间区别

  • preload:建议浏览器在页面加载过程中尽早加载该资源。
  • prefetch:建议浏览器在后台加载该资源,以备将来使用。
  • prerender:建议浏览器预渲染该资源,以提前生成即将展示给用户的页面。

预加载(preload)

资源预加载(preload)是一种浏览器优化技术,用于在页面加载过程中提前加载当前页面所需的关键资源,以加速页面渲染和提高用户体验。通过使用 preload,开发者可以指定一些重要资源在页面加载时优先获取,以便在需要时能够立即使用。

在 HTML 中,可以使用 <link> 元素来指定要预加载的资源。例如,以下是一个预加载 CSS 文件的示例:

ini 复制代码
htmlCopy Code
<link rel="preload" href="path/to/style.css" as="style">

在这个示例中,rel="preload" 指明了这是一个预加载资源,href 属性指定了要加载的资源路径,as="style" 表示该资源是一个样式表。类似地,可以使用不同的 as 属性值来指定不同类型的资源,如脚本、字体、图片等。

与资源预读取不同,资源预加载更强调的是对当前页面关键资源的提前获取,以确保页面渲染时能够立即使用这些资源,而不是等到用户交互或导航时再去请求加载。资源预加载通常用于加载那些对页面渲染至关重要的资源,如首屏所需的关键 CSS 和 JavaScript 文件、字体等。

类似资源预读取,资源预加载也需要慎重考虑,确保只对真正关键的资源进行预加载,避免不必要的网络请求和带宽消耗。同时,也需要考虑不同浏览器的支持情况以及网络环境的影响,综合考虑各种因素来确定是否使用资源预加载以及如何使用。

举个例子,从上面的优先级描述可以知道,字体属于高优先级的。默认情况下,Chrome会加载具有非常高优先级的字体,但如果某个用户的网络连接速度较慢,它会使用后备字体并降低优先级。

如下图:正常网络下的

弱网下的

我们可以通过预加载这个资源来覆盖浏览器的决定:

现在即使在弱网下它的优先级提高了:

另外,我们可以在 link上使用 fetchpriority,来让我们在一次预加载多个资源时发出更精准的请求优先级信号。

浏览器会根据我们的指令自动推断。

那前面看到了importance和这里提到的fetchpriority之间的区别是什么

ini 复制代码
htmlCopy Code
<link rel="preload" href="path/to/resource" as="type" importance="high">
fetchPriorityimportance

fetchPriorityimportance 是两个不同的概念,在使用 Priority Hints 时它们有着不同的作用。

  • fetchPriority:这是网页标准中定义的一个属性,用于指定资源请求的优先级。可以将该属性应用于 <link> 元素或者 fetch 请求中,以提示浏览器资源请求的优先级。fetchPriority 可以设置为 "low", "medium", "high" 或者 "auto" 等值,来告诉浏览器资源请求的相对重要程度。

    示例:

    ini 复制代码
    htmlCopy Code
    <link rel="stylesheet" href="styles.css" fetchPriority="high">
  • importance:这是在 HTTP/2 中定义的一个优先级标志,用于指定资源加载的重要性。它可以应用于 <link> 元素的 as 属性,用于指示资源的加载重要性级别。importance 的可选值有 "low", "high""auto"

    示例:

    ini 复制代码
    htmlCopy Code
    <link rel="preload" href="styles.css" as="style" importance="high">

虽然两者都涉及资源加载的优先级,但是 fetchPriority 主要用于指定资源请求的优先级,而 importance 则用于指定资源加载的重要性级别。在实际使用中,开发者可以根据具体情况选择合适的属性来指导浏览器资源加载的优先级和重要性。

预读取(prefetch)

资源预读取(Prefetch)是一种浏览器优化技术,用于在页面加载过程中提前请求并缓存未来可能需要的资源,以减少后续页面导航或操作时的延迟。其中,"prefetch" 是一种具体的预读取机制。

通过使用 prefetch,浏览器可以主动去加载和缓存当前页面附加资源(如脚本、样式表、图片等),以便在用户导航到下一个页面时能够更快地获取这些资源。这样可以提高用户体验,因为用户在导航到下一个页面时不需要等待资源的加载,而是能够立即渲染页面。

在 HTML 中,可以使用 <link> 元素来指定要预读取的资源。例如,以下是一个预读取 JavaScript 文件的示例:

ini 复制代码
htmlCopy Code
<link rel="prefetch" href="path/to/script.js">

类似地,可以使用 rel="prefetch" 属性来预读取其他类型的资源,如样式表、字体、图片等。

prefetch加载的是接下来页面可能会使用的资源,因此优先级最低,为Lowest。

preload加载的是本页即将要使用的资源,因此优先级要比prefetch高,但具体是多少,要看加载的资源的类型。

这个类型是as属性决定的,下面是一些类型示意。

ini 复制代码
<link rel="preload" href="main.js" as="script" />
<link rel="preload" href="myfont.ttf" as="font">
<link rel="preload" href="style.css" as="style" />
<link rel="preload" href="example.png" as="image" />

其中,JS、CSS和字体文件preload的优先级是High,而image类型的资源的优先级是Low(见下截图),这个和页面中JS资源的加载不同,对于页面内直连的JS文件,其加载优先级是Medium,而IMG图片则是High,CSS是Highest。

预渲染prerender

预渲染(prerender)是一种网页优化技术,它允许浏览器在用户导航到页面之前提前加载并渲染页面内容。这样做可以显著提高页面加载速度和用户体验。

预渲染通常适用于那些用户可能会浏览的页面,比如首页、常用的内容页等。当用户访问这些页面时,浏览器会预先加载并渲染页面内容,以便在用户真正导航到页面时可以立即展示内容,而不需要等待服务器响应和资源加载。

在 HTML 中,可以使用 <link> 元素的 rel 属性来指示浏览器对特定页面进行预渲染。例如:

ini 复制代码
htmlCopy Code
<link rel="prerender" href="http://www.example.com/page">

在这个例子中,rel="prerender" 表示建议浏览器对指定的页面进行预渲染,href 属性指定了要预渲染页面的 URL。

需要注意的是,预渲染可能会增加服务器和带宽的负担,因为浏览器会提前加载页面内容。因此,开发者应该谨慎使用预渲染,只对确实需要预渲染的页面进行指示,避免不必要的资源消耗。

另外,预渲染可能会与浏览器缓存和其他性能优化策略产生冲突,开发者在使用预渲染时需要综合考虑各种因素,并进行测试和优化,以确保能够达到预期的性能改善效果。

如何在项目中应用到构建打包中

可以借助preload-webpack-plugin

vue-cli3的配置

在 Vue CLI 3 中,你可以使用 webpack 的预加载(preload)和预获取(prefetch)功能来优化你的应用程序性能。

要设置预加载和预获取,你需要在项目的 vue.config.js 文件中进行配置。如果该文件不存在,请在项目根目录下创建该文件。

以下是一个示例的 vue.config.js 文件,展示了如何配置预加载和预获取:

ini 复制代码
javascriptCopy Code
module.exports = {
  chainWebpack: config => {
    // 配置预加载
    config.plugin('preload').tap(options => {
      options[0].as = 'script';
      options[0].include = 'allChunks';
      options[0].fileBlacklist = [/.map$/, /hot-update.js$/];
      return options;
    });

    // 配置预获取
    config.plugin('prefetch').tap(options => {
      options[0].fileBlacklist = [/.map$/, /hot-update.js$/];
      return options;
    });
  }
};

在上述示例中,我们使用 chainWebpack 方法来链式调用 webpack 配置。在 config.plugin('preload')config.plugin('prefetch') 中配置预加载和预获取的选项。

对于预加载,我们指定了将资源作为脚本(options[0].as = 'script')进行预加载,并且包括了所有的块(options[0].include = 'allChunks')。我们还通过 options[0].fileBlacklist 指定了不需要预加载的文件,比如 .map 文件和热更新脚本。

对于预获取,我们同样通过 options[0].fileBlacklist 指定了不需要预获取的文件。

配置完毕后,重新启动开发服务器或者重新构建项目,预加载和预获取的配置即可生效。

  • preload

默认情况下,一个Vue CLI应用会为所有初始化渲染需要的文件自动生成preload提示。这些提示会被@vue/preload-webpack-plugin注入,并且可以通过chainWebpack的config.plugin('preload')进行修改和删除。

  • prefetch

默认情况下,一个Vue CLI应用会为所有作为async chunk生成的JavaScript文件(通过动态import()按需code splitting的产物)自动生成prefetch提示。这些提示会被@vue/preload-webpack-plugin注入,并且可以通过chainWebpack的config.plugin('prefetch')进行修改和删除。

  • prerender

在 Vue CLI 3 中,你可以使用插件 @vue/cli-plugin-prerender-spa 来进行预渲染。

首先,确保你已经安装了 @vue/cli。然后,在你的项目根目录下打开终端,并执行以下命令安装 @vue/cli-plugin-prerender-spa 插件:

csharp 复制代码
shellCopy Code
vue add prerender-spa

安装完成后,会生成一个新的文件 vue.config.js,该文件用于配置 Vue CLI 的各种选项。

打开 vue.config.js 文件,并添加以下代码来配置预渲染:

yaml 复制代码
javascriptCopy Code
module.exports = {
  pluginOptions: {
    prerenderSpa: {
      registry: undefined,
      renderRoutes: [
        '/',
        '/about',
        '/contact'
        // 添加你需要进行预渲染的路由
      ],
      useRenderEvent: true,
      headless: true,
      onlyProduction: true
    }
  }
};

在上述示例中,我们通过 renderRoutes 配置项指定了需要进行预渲染的路由列表。你可以根据你的实际需求,添加需要进行预渲染的路由。这里只列举了三个示例路由,你可以根据自己的项目需求进行修改和扩展。

其他配置项的含义如下:

  • useRenderEvent:是否使用 render 事件来触发预渲染,默认为 true。这意味着在浏览器触发 render 事件后,会开始预渲染。
  • headless:是否以无头模式运行渲染器,默认为 true。这意味着预渲染将在后台运行。
  • onlyProduction:是否仅在生产环境中进行预渲染,默认为 true。这意味着在开发环境下不会进行预渲染。

配置完成后,你可以通过运行以下命令进行预渲染:

arduino 复制代码
shellCopy Code
npm run prerender

执行该命令后,Vue CLI 会根据配置对指定的路由进行预渲染,并生成静态 HTML 文件。这些文件将存储在默认的输出目录 dist 中。

请注意,预渲染是一种静态化技术,适用于那些内容相对稳定且不依赖于动态数据的页面。对于需要实时更新的页面或依赖于动态数据的页面,预渲染可能不适用。在使用预渲染前,请先评估你的项目需求和页面特性。

参考文章:

www.zhangxinxu.com/wordpress/2...

www.sohu.com/a/736449038...

codeleading.com/article/801...

blog.csdn.net/qq_34629352...

相关推荐
轻口味19 分钟前
命名空间与模块化概述
开发语言·前端·javascript
前端小小王1 小时前
React Hooks
前端·javascript·react.js
迷途小码农零零发1 小时前
react中使用ResizeObserver来观察元素的size变化
前端·javascript·react.js
娃哈哈哈哈呀1 小时前
vue中的css深度选择器v-deep 配合!important
前端·css·vue.js
旭东怪2 小时前
EasyPoi 使用$fe:模板语法生成Word动态行
java·前端·word
ekskef_sef3 小时前
32岁前端干了8年,是继续做前端开发,还是转其它工作
前端
sunshine6414 小时前
【CSS】实现tag选中对钩样式
前端·css·css3
真滴book理喻4 小时前
Vue(四)
前端·javascript·vue.js
蜜獾云4 小时前
npm淘宝镜像
前端·npm·node.js