在此 Codelab 中,您将通过两种方式实现预加载:使用 <link rel="prefetch">
和使用 HTTP Link
标头。
示例应用是一个网站,其宣传着陆页提供商店最畅销的 T 恤的特惠折扣。由于着陆页链接到单个商品,因此可以肯定,有很大比例的用户会前往商品详情页面。因此,商品页面非常适合在着陆页上预加载。
衡量性能
首先确定基准性能:
- 点击 Remix to Edit 即可修改项目。
- 如需预览网站,请按 View App(查看应用)。然后按 Fullscreen(全屏)。
- 按 `Control+Shift+J`(在 Mac 上为 `Command+Option+J`)打开 DevTools。
点击网络标签页。
在 Throttling 下拉列表中,选择 Fast 3G 以模拟慢速连接类型。
如需加载商品页面,请点击示例应用中的立即购买。
product-details.html
页面的加载用时约为 600 毫秒:
使用 <link rel="prefetch">
预提取商品页面
如需改进导航体验,请在着陆页中插入 prefetch
代码以预加载 product-details.html
页面:
- 将以下
<link>
元素添加到views/index.html
文件的标头:
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
<link rel="prefetch" href="/product-details.html" as="document">
...
</head>
as
属性是可选的,但建议使用该属性;该属性有助于浏览器设置正确的标头,并确定资源是否已在缓存中。此属性的示例值包括:document
、script
、style
、font
、image
和 others。
如需验证预提取功能是否正常运行,请执行以下操作:
- 如需预览网站,请按 View App(查看应用)。然后按 Fullscreen(全屏)。
- 按 `Ctrl+Shift+J`(在 Mac 上,按 `Command+Option+J`)打开开发者工具。
点击网络标签页。
在节流下拉列表中,选择快速 3G 以模拟连接类型较慢的情况。
清除“停用缓存”复选框。
重新加载应用。
现在,当着陆页加载时,product-details.html
页面也会加载,但优先级为最低:
网页会保留在 HTTP 缓存中五分钟,之后系统会应用文档的常规 Cache-Control
规则。在本例中,product-details.html
的 cache-control
标头值为 public, max-age=0
,这意味着该网页总共会保留 5 分钟。
重新评估效果
- 重新加载应用。
- 如需加载商品页面,请点击示例应用中的立即购买。
请查看 Network 面板。与初始网络轨迹相比,有两个区别:
- 大小列会显示“预提取缓存”,这表示相应资源是从浏览器的缓存而不是网络检索的。
- 时间列显示,现在文档加载时间约为 10 毫秒。
与之前的版本(大约需要 600 毫秒)相比,这大约减少了 98%。
额外提示:将 prefetch
用作渐进增强
最好将预提取作为渐进式增强功能来实现,以便为使用高速连接进行浏览的用户提供更好的体验。您可以使用 Network Information API 检查网络状况,并根据该状况动态注入预加载代码。这样,您可以最大限度地减少流量消耗,并为流量缓慢或流量费用较高的用户节省费用。
如需实现自适应预加载,请先从 views/index.html
中移除 <link rel="prefetch">
标记:
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
<link rel="prefetch" href="/product-details.html" as="document">
...
</head>
然后,将以下代码添加到 public/script.js
中,声明一个函数,以便在用户连接速度较快时动态注入 prefetch
标记:
function injectLinkPrefetchIn4g(url) {
if (window.navigator.connection.effectiveType === '4g') {
//generate link prefetch tag
const linkTag = document.createElement('link');
linkTag.rel = 'prefetch';
linkTag.href = url;
linkTag.as = 'document';
//inject tag in the head of the document
document.head.appendChild(linkTag);
}
}
该函数的工作原理如下:
- 它会检查 Network Information API 的 effectiveType 属性,以确定用户是否使用的是 4G(或更快)连接。
- 如果满足该条件,它会生成一个
<link>
标记,并将prefetch
作为提示类型,在href
属性中传递要预提取的网址,并在as
属性中指明资源是 HTMLdocument
。 - 最后,它会在网页的
head
中动态注入脚本。
接下来,将 script.js
添加到 views/index.html
中,紧挨结束 </body>
标记前面:
<body>
...
<script src="/script.js"></script>
</body>
在页面末尾请求 script.js
可确保在页面解析和加载后加载并执行它。
为确保预加载不会干扰当前网页的关键资源,请添加以下代码段,以便对 window.load
事件调用 injectLinkPrefetchIn4g()
:
<body>
...
<script src="/script.js"></script>
<script>
window.addEventListener('load', () => {
injectLinkPrefetchIn4g('/product-details.html');
});
</script>
</body>
着陆页现在仅在连接速度较快时预加载 product-details.html
。如需验证这一点,请执行以下操作:
- 如需预览网站,请按 View App(查看应用)。然后按 Fullscreen(全屏)。
- 按 `Control+Shift+J`(在 Mac 上为 `Command+Option+J`)打开 DevTools。
- 点击网络标签页。
- 在节流下拉列表中,选择在线。
- 重新加载应用。
您应该会在“网络”面板中看到 product-details.html
:
如需验证系统不会在网速较慢时预提取商品页面,请执行以下操作:
- 在“节流”下拉列表中,选择3G 网络(速度缓慢)。
- 重新加载应用。
广告网络面板应仅包含着陆页的资源,且不含 product-details.html
:
使用 HTTP Link
标头预提取商品页面的样式表
HTTP Link
标头可用于预提取与 link
标记相同类型的资源。确定何时使用哪种方法主要取决于您的偏好,因为两者的性能差异不大。在本例中,您将使用它预加载商品页面的主要 CSS,以进一步改进其呈现效果。
在着陆页的服务器响应中为 style-product.css
添加 HTTP Link
标头:
- 打开
server.js
文件,然后查找根网址/
的get()
处理脚本。 - 在处理程序的开头添加以下行:
app.get('/', function(request, response) {
response.set('Link', '</style-product.css>; rel=prefetch');
response.sendFile(__dirname + '/views/index.html');
});
- 如需预览网站,请按 View App(查看应用)。然后按 Fullscreen(全屏)。
- 按 `Ctrl+Shift+J`(在 Mac 上,按 `Command+Option+J`)打开开发者工具。
- 点击网络标签页。
- 重新加载应用。
现在,系统会在着陆页加载后以最低优先级预提取 style-product.css
:
如需前往商品页面,请点击立即购买。查看 Network 面板:
系统会从“预提取缓存”中检索 style-product.css
文件,并且只需 12 毫秒即可加载。