Chrome Prerender2.0 - 新一代 Web 预渲染技术

如何在 Chrome 浏览器中更快地加载网站? 这是本篇文章即将讨论的主题。

📃前言

Chrome浏览器在ver.103中引入了许多新功能,例如 Journeys、新的隐私指南界面、扩展入门等,仔细查看 Chrome 的隐藏标志,我们发现了另一个可以显着加快网站加载速度的功能。 这项技术功能可用于预加载和渲染内容,可以大大的提高用户访问网站的体验,取代了旧版 Chrome 中的 NoState Prefetch 预渲染 并且消耗资源更少。

❔如何启用

确保你的Chrome版本在 103+ 查看 chrome://flags 输入 prerender 确保相关项 是 Enabled 状态 根据系统提示进行重启动浏览器。

enabled

❔Prerender2.0的使用

使用 Prerender2.0 机制需要使用新增的 Speculation Rules API,此API可同时支持触发 Prefetch、NSP、Prerender 机制。

1、Prefetch(预取)机制: 预取是一种优化策略,通过在用户点击链接之前提前获取相关资源,以减少加载时间。这可以包括预先加载链接指向的页面的CSS、JavaScript、图像等内容,提高用户体验。
2、NSP(Next Scheduled Prefetch)机制: NSP 是一种进一步的优化,它预定了将来可能发生的预取操作。系统会根据用户行为和网站的预取策略,提前获取可能被访问的页面资源,以减少未来导航时的加载时间。
3、Prerender(预渲染)机制: 预渲染是一种更进一步的优化技术,它不仅预取资源,还预先渲染整个页面。这意味着浏览器在用户导航到页面之前会预先加载、执行 JavaScript 和渲染页面,以便在用户实际导航到该页面时可以立即呈现。这有助于显著缩短页面加载时间。

可以通过 ('supports' in HTMLScriptElement && HTMLScriptElement.supports('speculationrules')) 来查看当前运行环境的支持情况

API 使用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<script type="speculationrules">
{
"prerender": [
{"source": "list",
"urls": ["next.html", "./PrefetchTestNew.html"]}
],
"prefetch": [
{"source": "list",
"urls": ["next.html"],
"requires": ["anonymous-client-ip-when-cross-origin"]}
],
"prefetch_with_subresources": [
{"source": "list",
"urls": ["next.html"],
"requires": ["anonymous-client-ip-when-cross-origin"]}
]
}
</script>

API 主要参数说明:

类型 含义 备注
prerender 使用预渲染机制 /
prefetch 使用预加载机制,仅预加载主文档(Document) 内部使用 SimpleURLLoader 实现主文档的预加载
prefetch_with_subresources 使用预加载机制,预加载主文档 + 关键子资源。功能效果类似于NSP 内部使用 SimpleURLLoader 实现主文档的预加载
requires 在确保客户端IP对服务端不可见时,可预加载跨域资源 value只能为 anonymous-client-ip-when-cross-origin,且 只支持 key为 prefetchprefetch_with_subresources 的场景下使用

根据支持情况使用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Prerendering with web-vitals: index</title>
<link id="favicon" rel="icon" href="https://glitch.com/favicon.ico" type="image/x-icon" />
<meta http-equiv="Content-Security-Policy" content="script-src 'strict-dynamic' 'sha256-kBytAlkzbRIYPXxDAM/I6PhcHCfaLyEcc48s76/JtOI='">
</head>
<body>

<h1>Start page</h1>

<p><a href="next.html">This link should be prerendered</a></p>
<p><a href="next2.html">This link should also be prerendered</a></p>

<hr>

<pre id="output1"></pre>
<pre id="output2"></pre>

<hr>

<p><a href="https://glitch.com/edit/#!/prerender-demos">View the code on Glitch</a></p>

<script>
function trackAction(selector, actionName, args) {
document.querySelector(selector).textContent = `${actionName}: ${JSON.stringify(args, 0, 2).replaceAll('\\"','"')}`;
}
function addSpeculationRules() {
const specScript = document.createElement("script");
specScript.id = "speculationrules";
specScript.type = "speculationrules";
specScript.textContent = `
{
"prerender": [
{
"source": "list",
"urls": ["next.html", "next2.html"]
}
]
}`;
document.body.appendChild(specScript);
}
if (!('supports' in HTMLScriptElement && HTMLScriptElement.supports('speculationrules'))) {
trackAction('#output1', 'Speculation Rules supported on your browser', 'false');
} else {
trackAction('#output1', 'Speculation Rules supported on your browser', 'true');
addSpeculationRules();
trackAction('#output2', 'Added speculationrules', document.querySelector('#speculationrules').text.replaceAll('\n','').replace(/ +/g,' '));
}
window.addEventListener('pageshow', (event) => {
// on bfcache restore, reinitialise the speculation rules to force another prerender
const navigationType = performance.getEntriesByType('navigation')[0].type;
if (event.persisted || navigationType == 'back_forward' ) {
document.querySelector('#speculationrules')?.remove();
addSpeculationRules();
trackAction('#output2', 'Page reactivated: re-added speculationrules', document.querySelector('#speculationrules').text.replaceAll('\n','').replace(/ +/g,' '));
}
});
</script>
</body>
</html>

由于 Speculation Rules API 的灵活性较好,Chromium预言此API将逐步替代规则,成为开发者使用较多的API。

❔我根据代码提示使用了Prerender2.0技术,那么如何客观的体现呢?

如何知道用户打开了已Prerender的页面呢?

  1. 可以打开F12控制台,通过输入 performance.getEntriesByType('navigation')[0].type 可以获取到当前页面的加载类型,如果是 ‘prerender’ 则表示当前页面是通过 Prerender2.0 技术加载的。
  2. 同上,但是输入performance.getEntriesByType('navigation')[0].activationStart; 如果大于0 则表示当前页面是通过 Prerender2.0 技术加载的。
  3. 同上
    1
    2
    3
    4
    5
    6
    let wasActivated = false;
    document.addEventListener('prerenderingchange', (event) => {
    wasActivated = true;
    });
    // wasActivated = true 则表示当前页面是通过 Prerender2.0 技术加载的。
    console.info(wasActivated);
    提供了三种方式去验证当前页面是否是通过 Prerender2.0 技术加载的,当然还可以通过任务管理器查看 带有预渲染的网页 会有预渲染: 开头。

❔效果如何?

根据 Chromium 提供的视频示例(视频演示),不使用 Prerender 能力可以明显的看到页面中内容从0到1展示的过程,而使用Prerender后页面几乎是即时展示的。效果对比 非常明显

quick

❔体验地址

Prerender Demo: 前往体验demo

Prerender Demo源代码: 前往查看源代码

❔应用场景

由于预渲染页面对于设备的资源消耗较大,是个需要谨慎使用的机制能力,若肆无忌惮的使用此能力,不仅无法提高用户的浏览体验,还会耗尽用户的宝贵资源,可能带来卡顿、崩溃等负向影响。Chromium推荐用法中表示当用户加载某些页面的可能性很高时才推荐使用Prerender机制,此时可将Prerender机制带来的正向收益最大化。

Chromium将预测技术与Prerender2.0机制结合使用,利用预测技术提高预渲染页面的准确性。通过 chrome://predictors 页面可看出Chromium对用户行为的预测,如下图。

predictors

其中 绿色高亮 表示有足够信心触发预渲染。以上示例可看出,当用户在输入框中输入”aliy”/“aliyu”/“aliyun”字符后,Chrome 将对 “https://www.aliyundrive.com/" 站点发起预渲染,因为经过多次统计有足够的信心认为用户将进入目标站点。

Chromium会根据用户输入和选择不断的更新预测结果。

当置信度>50%(图中黄色),Chromium会发起预链接
当置信度>80%(图中绿色),Chromium会发起预渲染

同时Chromium会将预测的结果呈现在Sug选项栏中,辅助用户进入目标站点。

进入站点后,开发者可以通过上面提到的验证方式,来确认当前是否是 Prerender2.0 技术预加载的。

总结

本文主要介绍了 Prerender 机制的发展过程和现状,并对 Prerender2.0 技术进行介绍。其中重点介绍了 Prerender2.0 技术的使用、实现流程和应用场景。Prerender2.0 机制还在初级阶段,目前为止Chromium还在对 Prerender2.0 技术进行完善,故文档中内容可能和最新方案有些许差异。但是我们仍将持续关注 Prerender2.0 技术发展,发掘其应用于业务的可行场景,持续优化页面上屏性能,提升用户体验。

—END—


参考文档:


❤ enjoy it.