预加载(Preload)是一种强大的优化技术,可以显着改进关键性能指标,例如Core Web Vitals。前面我们介绍过关于预取DNS查找甚至预连接到域的文章。预加载是这些概念的一个更强大的扩展,因为它使您能够提前下载整个资源。
在这篇文章中,我们来看看:
- 预加载资源提示如何工作
- 关于何时使用(以及何时不使用)的指南
- 在您自己的网站上实施预加载提示时要遵循的最佳实践清单。
预加载资源提示的工作原理
预加载是一种资源提示,它告诉浏览器在浏览器确定它需要发出请求之前请求内容。这可以提高性能,因为当浏览器确实意识到它需要请求一个已经预加载的资源时,它已经在那里了。
让我们从一个简化的示例开始,如瀑布图所示:
浏览器首先下载引用样式表style.css的HTML文档。在样式表中,我们指定应该使用的自定义字体,如下所示:
这是后期发现资源的完美示例。此浏览器在完成下载和解析style.css之前不知道它需要请求robots.woff。我们可以通过查看瀑布中的Initiator列来确认这一点,它告诉我们是什么文件导致浏览器发出请求。HTML文档有一个Other的启动器, 因为我们在地址栏中输入了它。style.css的发起者是HTML文档,因为浏览器在HTML中找到了<link>标签。启动器robots.woff是CSS文件,因为浏览器在HTML中使用的CSS文件中找到了样式的@font-face 声明。
我们可以通过在HTML文件的<head>中添加预加载资源提示来优化这一点:
<link href="resources/roboto.woff" as="font" crossorigin="anonymous" />
这指示浏览器主动下载roboto.woff,并创建这个瀑布:
有很多事情需要注意:
- 浏览器现在与style.css并行下载robots.woff。
- robots.woff的发起者是HTML文件而不是CSS。
- 所有主要性能指标都更快,并且我们减少了关键渲染路径的长度。
现实世界的例子
这非常适合演示——现在让我们看看使用预加载资源提示的实际好处。
Addy Osmani分享了Tinder如何提高其渐进式Web应用程序 (PWA) 的性能。作为PWA,Tinder拥有大型JavaScript包,可以动态加载到其他JavaScript包中。由于这些附加包是由执行的脚本动态加载的,因此浏览器在JavaScript代码运行之前无法发现它们。我在下面的Addy博客文章中注释了一个屏幕截图:
您可以看到主要供应商捆绑包如何加载3个额外的JavaScript文件。通过预加载这些附加脚本,Tinder:
- 加载时间减少1秒
- 将他们的第一个绘制指标降低了大约50%
Ivan Akulov对流行的网络应用Notion做了一些有趣的性能分析。Notion需要相同的基本API调用才能运行,并且这些API调用发生在主包加载之后。 预加载这些API调用将页面呈现指标提高了10%。
在Splunk,我们也有第一手经验。2020年初,我们与一家主要媒体客户合作,该客户拥有大量用于各种第三方域的 JavaScript。通过分析他们的站点并实施诸如预连接和预加载之类的资源提示,我们将交互时间缩短了4.9秒,即37%。
何时使用预加载资源提示
在上面的案例研究中,您会注意到一个模式:
与所有资源提示一样,预加载允许您利用您对应用程序的了解来优化资源的交付,这比浏览器本身无法做到的更好。
具体来说,您可以告诉浏览器在请求资源之前请求它。告诉浏览器下载它自己会发现的东西是很浪费的。例如,如果您在HTML的<head>顶部附近有style.css,则没有理由使用预加载资源提示。浏览器已经会发现它。
预加载是 后期发现资源的理想选择。后期发现的资源是需要在浏览器访问它们之前下载或执行一个或多个其他资源链的资源。例如:
- 在CSS文件中引用的字体
- JavaScript动态加载的关键资源
- 仅在进行API调用后出现的图像或内容
不正确地使用预加载会损害性能
鉴于上述令人印象深刻的收获,我知道您一定在想什么:
如果预加载资源提示可以提高整体性能和用户体验,我为什么不在页面上预加载所有关键资源?
不幸的是,错误地使用预加载实际上会损害性能。为什么?这很简单:浏览器使用大量复杂的逻辑来决定需要下载什么以及何时下载,因此页面可以尽快呈现并响应访问者。
使用预加载的站点本质上是要求覆盖浏览器通常会执行的操作。如果出于三个原因不小心使用,这可能是不同性能问题的根源:
- 预加载资源提示是强制性的。 虽然其他类型的资源提示,如预连接或 DNS 预取提示,浏览器可以选择遵循,但需要执行预加载提示。现代浏览器使用极其复杂的逻辑来下载关键资源。预加载——可能比任何其他类型的资源提示都多——对浏览器操作的干扰最大,必须小心使用。
- 预加载会耗尽资源。浏览器限制了它对单个域的并发请求数。预加载资源会“用完”您认为浏览器需要的请求槽和下载带宽,而不是浏览器原本用于下载它知道它需要的资源的资源。
- 预加载发生在最关键的时刻。预加载通常发生在页面加载开始附近,这是浏览器最关键的时间。它专注于下载关键渲染路径上的资源,即开始渲染页面所需的资源。太多或不必要的预加载会影响浏览器做正确的事情,从而降低性能。
现在让我们看看一些常见的错误。
过多的预加载提示
采用预加载提示的最常见错误之一是使用过多的提示。通常,网站预加载的资源不应超过3-4个。除此之外,您还试图超越浏览器,这很少是一个好主意。原因如下:
首先,预加载最适用于对页面也很重要的后期发现资源。拥有多个浏览器也不容易发现的关键资源通常是更大设计问题的征兆。
例如,一个站点可能正在预加载六种字体。首屏内容是否需要所有六种字体?一个可变粗细字体文件可以代替吗?另一种选择是通过 <style> 标记直接在HTML中包含font-face: 定义。使用这种方法,那些字体文件不再是后期发现的资源。浏览器可以立即查看需要六个字体文件中的哪一个(如果有)并快速获取它,而无需预加载提示。
避免过多预加载提示的第二个原因是技术债务。页面的预加载越多,这些预加载中的一个越有可能无助于加速页面的初始加载和交互性。每个都代表了更多的技术债务,以维护和确保预加载的资源对该页面仍然至关重要。
预加载未使用的内容
另一个常见的错误是看到页面甚至没有使用的内容的预加载。当网站在其模板中使用公共标头时,我经常会看到这种情况。开发人员可能正在优化他们的主页或关键登录页面,并为关键字体或 JavaScript 文件包含 <link rel=”preload”>。他们错误地将其放在公共标题中,即使这些资源没有在网站的其他地方使用。
幸运的是,现代浏览器会在控制台中显示警告:
在所有关键页面上查找这些警告可能很乏味。相反,一个好的代理是查看站点的CSS和JavaScript覆盖率分析。如果一个站点正在加载大量未使用的CSS或JS,这通常意味着站点所有者正在为整个站点使用大型、粗粒度的通用包,而不是为其特定模板使用较小的目标包。因此,任何预加载也可能过于粗略,并且在不需要时跨页面进行预加载。
预加载非关键内容
另一个常见错误是预加载对首屏内容的呈现和交互性不重要的内容。通常,如果您有太多预加载,那是因为您正在预加载非关键内容。
- 你是在预加载图像吗?除非它是英雄形象,而且那个英雄形象确实是后来发现的资源,否则可能没有必要。
- 你在预加载JavaScript吗?如果是这样,提供CTA点击等交互性是否至关重要?为什么 JavaScript 不能被延迟或异步加载?
- 您是否正在预加载字体?它是被这个页面使用的,还是这个预加载发生在一个通用的模板标题中并且字体没有在任何地方使用?
- 你是在预加载视频吗?为什么?预加载视频几乎总是一个坏主意,因为根据定义,它不是关键内容。考虑在 <video> 标签上使用poster属性。
一般来说,如果 <link rel=”preload” as=””> 属性是除了样式、脚本或字体之外的东西,它通常是非关键的,需要额外的审查。
预加载不存在的内容
预加载忽略的最终表现是预加载导致404 – 永远不会好。关键渲染路径中的404错误。但是,预加载内容的404是最差的。你篡夺了浏览器的正常行为,延迟了浏览器知道它需要的资源,全部用于下载无效内容。
预加载并不总是正确的工作提示
Preload 与其他资源提示的不同之处在于您指定了完整的URL。通常,您不能依赖该URL保持不变,或者无法知道完整的URL将是什么。例如:
- 如果页面正在加载来自其他部门的JavaScript库,则它下载的其他JavaScript库可能会发生变化。使用 preload 会创建依赖项,您需要在这些依赖项中与加载来自附加JavaScript的URL的更改保持同步。
- 如果您使用评论,您可能不知道加载了哪些用户头像图像,但您知道它们都来自www.gravatar.com。
- 如果您使用的是广告交易平台,您可能不知道广告竞价的路径,但您知道您会向ads.pubmatic.com发出请求
这些是使用预连接或DNS预取的绝佳机会。请记住:使用提前完成较少工作的资源提示比使用预加载和出错的性能要好得多。
预加载审计的最佳实践
正如我们所展示的,使用预加载资源提示有很多好处,但如果使用不当,也会出现许多损害性能的陷阱。这意味着审核页面如何使用资源提示以确保您遵循所有最佳实践非常重要。
首先,确定页面当前正在使用的所有预加载资源提示。您将需要在基本HTML页面中查找 <link rel=”preload”> 标记,以及Link: HTTP标头,其中也可以包含资源提示。还要记住,包含资源提示的链接标头可以出现在基于HTML页面之外的其他响应中!
获得预加载列表后,问自己以下问题:
- 该资源是后期发现的资源还是浏览器已经发现了它?
- 预加载的资源对于首屏内容的初始绘图或交互性是否至关重要?如果没有,请将其删除。
- 您是否预加载超过3-4个资源?如果是这样,您是否测试过这些预加载是否能提高性能指标?
- 预加载的资源是不是字体、CSS或JavaScript文件?如果是这样,它可能对页面并不重要,很可能应该被删除。
- 该页面是否使用了此预加载资源?如果没有,请将其删除。
- 此预加载资源是否返回4xx或5xx错误?如果是这样,请将其删除
- 资源提示是否包含在其他页面使用的公共标题中?该资源是否用于所有这些页面?如果没有,请仅在需要它的页面上包含预加载提示。
与所有性能优化一样,您应该始终在之前和之后进行测量,以确保更改实际上提高了性能。是的,理论上,预加载提示应该加快速度。但是现代网页非常复杂,包含数百种资源,而现代浏览器更加复杂,无法快速处理这些资源以提供最佳体验。信任但要验证。
评论留言