前端性能优化之预加载和预渲染

预加载和预渲染

        • 预加载
          • 用例:字体
          • 用例:关键路径 CSS 和 JavaScript
        • 预渲染
        • 预提取
          • 预提取不会替换内容

浏览器基于自身对资源重要性的判断,为不同类型的资源分配相应的优先级。当您发现任何资源标记的优先级不是您想要的优先级时,您能做什么?

预加载

告知浏览器当前导航需要某个资源,应尽快开始提取。 以下为相关使用示例:

1
2
<link rel="preload" as="script" href="super-important.js">
<link rel="preload" as="style" href="critical.css">

您可能已经想到除“as”属性以外的大部分语法结构。 该属性允许您告知浏览器您将加载的资源类型,以便浏览器可以正确处理该资源。 除非资源类型设置正确,否则浏览器不会使用预加载的资源。 浏览器将以同样的优先级加载资源,但提前了解了该资源,可以尽早开始下载。

请注意, 是强制浏览器执行的指令;与我们将探讨的其他资源提示不同,它是浏览器必须执行的指令,而不只是可选提示。 因此,为确保使用该指令时不会偶然重复提取内容或提取不需要的内容,对其进行仔细测试尤其重要。

使用 提取的资源如果 3 秒内未被当前页面使用,将在 Chrome 开发者工具的控制台中触发警告,请务必留意这些警告!

在这里插入图片描述

用例:字体

字体是典型的必须提取且次序靠后的资源示例,通常位于页面加载的若干 CSS 文件的最末尾处。

为了减少用户等待网站文本内容加载的时间,并避免系统字体与您偏好的字体发生冲突,您可以在您的 HTML 中使用 ,让浏览器立即了解需要某种字体。

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

请注意,此处 crossorigin 的使用非常重要,该属性如果缺失,浏览器将忽略预加载的字体,并执行不同的提取 这是因为浏览器预计将以匿名方式提取字体,只有使用 crossorigin 属性才能以匿名方式发出预加载请求。

用例:关键路径 CSS 和 JavaScript

讨论页面性能时,了解“关键路径”这一概念十分有用。 关键路径是指在首次渲染之前必须加载的资源。 这些资源(如 CSS)对于在用户的屏幕上呈现出首个画面至关重要。

以前,建议的做法是将此类内容内联到 HTML 中。 然而,对于多页面、服务器端渲染的情况,这种做法会很快导致带宽大量浪费。 此外,由于关键代码的任意更改会导致其中内联的页面无效,因此这种做法会使版本控制难度加大。

允许您继续利用单个文件版本控制和缓存的优势,同时为您提供尽快请求资源的机制。

1
2
<link rel="preload" as="script" href="super-important.js">
<link rel="preload" as="style" href="critical.css">

采用预加载有一个缺点:您仍然将受额外往返的约束。 造成额外往返的原因在于浏览器首先需要提取 HTML,然后才能了解后续资源。

解决额外往返的一种方式是使用 HTTP/2 推送,您可以在发送 HTML 的相同连接上抢占式附加关键资产。 这种做法可以确保用户浏览器检索 HTML 和开始下载关键资产之间不存在休息时间。 使用 HTTP/2 推送时请务必谨慎,因为这种方式能有效控制用户的带宽使用量(“服务器最了解”),为浏览器留下很小的自我决策空间,例如不检索已在其缓存中的文件。

预渲染

可以通过预渲染将下载的文件预先在后台渲染,可以使用以下代码开启预渲染

1
<link rel="prerender" href="http://example.com">

预渲染虽然可以提高页面的加载速度,但是要确保该页面大概率会被用户在之后打开,否则就是白白浪费资源去渲染。

预提取

以及 略有不同,它并不试图使关键操作更快发生,而是利用机会使非关键操作更早发生。

这一过程的实现方式是通过告知浏览器未来导航或用户互动将需要的资源,例如,如果用户做出我们期望的行为,则表示其可能稍后才需要某资源。 当前页面完成加载后,且带宽可用的情况下,这些资源将在 Chrome 中以 Lowest 优先级被提取。

这意味着,prefetch 最适合抢占用户下一步可能进行的操作并为其做好准备,例如检索结果列表中首个产品的详情页面或检索分页内容的下一页。

1
<link rel="prefetch" href="page-2.html">

请记住,预提取不可递归使用。 在上方示例中,您仅可以检索 HTML;page-2.html 需要的任何资源将不会提前下载,除非您针对这些资源也设置明确的预提取。

预提取不会替换内容

值得注意的是,您不可使用 来降低现有资源的优先级。 在以下 HTML 中,您可能认为在预提取中声明 optional.css 将会降低随后的 的优先级:

1
2
3
4
5
6
7
8
9
<html>
  <head>
    <link rel="prefetch" href="optional.css">
    <link rel="stylesheet" href="optional.css">
  </head>
  <body>
    Hello!
  </body>
</html>

但是,实际上,这将导致您的样式表被提取两次(虽然第二次可能导致缓存命中),一次是以默认的 Highest 优先级,另一次是以 Lowest 优先级,因为预提取将启动单独的提取:
在这里插入图片描述
两次提取对于用户来说不是好事。 在这种情况下,用户不但需要等待阻塞渲染的 CSS,还可能因为下载文件两次而浪费带宽。 请谨记,用户的带宽可能是按量计费。 请确保全面分析您的网络请求,并留意是否存在两次提取的情况。