Lazy loading

延迟加载 (懒加载) 是一种将资源标识为非阻塞(非关键)资源并仅在需要时加载它们的策略。这是一种缩短关键渲染路径长度的方法,可以缩短页面加载时间。

延迟加载可以在应用程序的不同时刻发生,但通常会在某些用户交互(例如滚动和导航)上发生。

概览

随着网络的发展,我们已经看到发送给用户的资产数量和规模都在急剧增加。从 2011 年到 2019 年,台式机的资源中位数从 ~100KB 增至 ~400KB,移动版的资源中位数从 ~50KB 增至**~350KB**。图像大小已从台式机上的**~250KB** 增至 ~900KB,而移动设备上的 ~100KB增至**~850KB**。

解决这个问题的方法之一是延迟加载对第一次渲染并不重要的资源来缩短关键渲染路径的长度。一个实际例子是,当用户打开一个电商网站的主页时,该页面有一个指向购物车页面/区域的链接,并且只有在用户导航到购物车页面/区域时才会下载其所有资源(JS、CSS、images……)。

策略

延迟加载可以通过多种策略应用于多个资源。

综述

代码拆分 可以将 JavaScript、CSS 和 HTML 分割成小块,以发送最少的代码提供关键信息,以优化页面加载时间。其余的部分可以在需要时加载。

  • Entry point splitting: separates code by entry point(s) in the app
  • Dynamic splitting: separates code where dynamic import() statements are used

JavaScript

脚本类型模块 任何类型为 type="module" 的脚本标签都被视为一个 JavaScript 模块,并且默认情况下会被延迟。

CSS

默认情况下,CSS 被视为渲染阻塞资源,因此,在 CSSOM 被构造完成之前,浏览器不会渲染任何已处理的内容。CSS 必须很薄,才能尽快交付,建议使用媒体类型和查询实现非阻塞渲染。

<link href="style.css"    rel="stylesheet" media="all">
<link href="portrait.css" rel="stylesheet" media="orientation:portrait">
<link href="print.css"    rel="stylesheet" media="print">

可以执行一些 CSS 优化来实现这一目标。

Fonts

默认情况下,字体请求会延迟到构造渲染树之前,这可能会导致文本渲染延迟。

It is possible to override the default behaviour and preload web font resources using <link rel="preload">, the CSS font-display property, and the Font Loading API.

See also: Element Link

Images and iframes

Very often, webpages contain many images that contribute to data-usage and how fast a page can load. Most of those images are off-screen (non-critical), requiring user interaction (an example being scroll) in order to view them.

Loading 属性 The loading attribute on an <img> element (or the loading attribute on an <iframe>) can be used to instruct the browser to defer loading of images/iframes that are off-screen until the user scrolls near them.

<img src="image.jpg" alt="..." loading="lazy">
<iframe src="video-player.html" title="..." loading="lazy"></iframe>

The load event fires when the eagerly-loaded content has all been loaded; at that time, it's entirely possible (or even likely) that there may be lazily-loaded images that are within the visual viewport (en-US) that haven't yet loaded.

You can determine if a given image has finished loading by examining the value of its Boolean complete property.

Polyfill Include this polyfill to provide support for older and currently incompatible browsers: loading-attribute-polyfill

交叉观察者 API Intersection Observers allow the user to know when an observed element enters or exits the browser's viewport.

事件处理程序 当浏览器的兼容性至关重要时,有以下几种选择:

规范

Specification
HTML Standard
# lazy-loading-attributes

查看更多