专栏名称: 前端早读课
我们关注前端,产品体验设计,更关注前端同行的成长。 每天清晨五点早读,四万+同行相伴成长。
目录
相关文章推荐
庆阳市场监管  ·  第三届消费者权益保护微视频作品展播(二) ·  昨天  
庆阳市场监管  ·  第三届消费者权益保护微视频作品展播(二) ·  昨天  
前端大全  ·  55 ... ·  2 天前  
前端早读课  ·  【第3470期】利用大型语言模型(LLMs) ... ·  昨天  
前端大全  ·  被骂了!腾讯道歉 + 立刻改正 ·  4 天前  
吉林省高级人民法院  ·  “只要是前往正义的路我都想走” ·  3 天前  
吉林省高级人民法院  ·  “只要是前往正义的路我都想走” ·  3 天前  
51好读  ›  专栏  ›  前端早读课

【第3428期】Speculation Rules的分层方法

前端早读课  · 公众号  · 前端  · 2024-12-06 08:00

主要观点总结

本文介绍了使用Speculation Rules API进行Web性能优化的分层方法,包括prefetch和prerender的使用,以及如何根据网站规模和需求进行定制化的策略选择。文章还讨论了如何通过data-prefetch属性实现更精细的控制,以及实验结果的令人信服的表现。

关键观点总结

关键观点1: Speculation Rules API的简介和关键概念

文章介绍了Speculation Rules API的基本概念,包括prefetch和prerender两种推测加载类型,以及它们的目标和用途。

关键观点2: 分层方法的实际应用

文章通过作者在实际项目中的经验,详细解释了如何将分层方法应用于Web性能优化,包括针对不同层次的需求选择合适的优化策略。

关键观点3: 使用data-prefetch属性进行精细化控制

文章强调了使用data-prefetch属性来精细控制推测加载的重要性,并提供了具体的实现方法和示例代码。

关键观点4: 实验结果的展示和分析

文章分享了一周的实验结果,并分析了使用分层方法进行Web性能优化的效果,强调了这种方法的优雅性和满意度。

关键观点5: 总结和展望

文章总结了使用分层方法进行Web性能优化的经验和教训,并展望了未来的发展方向和可能的改进点。


正文

前言

规范化规则的分层方法是一种将 Web 性能优化策略分解为不同层次的技术。每个层次都专注于特定类型的性能问题和优化策略,这样可以更有效地识别和解决性能瓶颈。今日前端早读课文章由 @飘飘翻译分享。


明天你会来前端 FEDay 吗?

译文从这开始~~

我一直喜欢使用简单的 Web 平台功能做一些不太常规和巧妙的事情,以最大限度地发挥它们的作用。从构建最小的兼容 LCP ,懒预加载 CSS,或者使用像素 GIF 来跟踪非 JS 的用户和失效的 CSS,我发现从有用的东西中创造出有用的东西很有乐趣。

最近,我一直在使用 Speculation Rules API 进行类似的游戏。

投机行为规则

我不想在这篇文章中深入讨论 Speculation Rules API,但需要了解的关键点是,它提供了两种推测加载类型 —— prefetch 和 prerender —— 其最终目标如下:

  • prefetch:预先支付下一页的 TTFB 费用

  • prerender:预先支付了下一页的 TTFB、FCP 和 LCP。

记住这两个常识将会非常有帮助 —— prefetch 用于减少 TTFB;prerender 用于 LCP。这使得 LCP 成为两者中较轻的选项,而 TTFB 则需要更多的资源。

对于本文的目的来说,这些就足够了。

对 csswizardry.com 的猜测

自从推测规则可用以来,我在这个网站上对其进行了一些不太令人满意的运用:

1、预渲染主页上的最新文章:

 <script type=speculationrules>
{
"prerender": [
{
"urls": [ "/2024/12/a-layered-approach-to-speculation-rules/" ]
}
]
}
script>

2、预渲染页面上的下一篇和上一篇文章,就像这样的页面:

 <script type=speculationrules>
{
"prerender": [
{
"urls": [
"/2024/12/a-layered-approach-to-speculation-rules/",
"/2024/11/core-web-vitals-colours/"
]
}
]
}
script>

在这种情况下,我明确预渲染了命名和已知的 URL,对潜在且可能的用户旅程有一个大致的设想 —— 我正在预热我认为可能是访客下一页的内容。

虽然这两点都是实用且有益的,但我想做得更多。我的网站虽然看起来不太明显,但实际上有两面性:面向像你这样的普通用户的博客部分,以及面向潜在客户的商业部分。虽然引导人们快速浏览文章内容很棒,但我能否为浏览网站其他部分的访客提供更多帮助呢?

我最近将我的 “猜测规则” 扩展为:

  • 不要在页面上添加任何内部链接,并且;

  • 在鼠标悬停时,不要显示任何其他内部链接。

这种相对不加选择的方法所覆盖的范围比列出的 URL 要广泛得多,它不是只关注页面上的链接地址,而是会留意页面上的任何内部链接。

 <script type=speculationrules>
{
"prefetch": [
{
"where": {
"href_matches": "/*"
},
"eagerness": "immediate"
}
],
"prerender": [
{
"where": {
"href_matches": "/*"
},
"eagerness": "moderate"
}
]
}
script>

这种稍显分层的方法使我们能够为页面上所有内部链接的 TTFB 成本进行合理支付,并为页面上任何我们悬停的内部链接的 LCP 成本进行合理支付( moderate )。这些是相当广泛的规则,因为它们适用于页面上任何匹配 /* 的链接 —— 所以任何根相对链接。

这种方法对我很有效,因为我的网站完全是静态生成的,并且由 Cloudflare 的边缘服务器提供服务。我也没有大量的流量,因此任何地方的服务器负载增加的风险都非常小。对于拥有大量流量且后端高度动态(数据库查询、API 调用、缓存不足)的网站来说,这种方法可能过于宽松。

多层次方法

在最近的一个客户项目中,我想将这个想法进一步深化。他们的网站规模庞大且相对复杂(许多不同的产品线都归属于同一个域名),拥有大量的流量和相当复杂的后端基础设施。因此,我们必须更加谨慎地考虑问题。

【第2875期】HTML性能优化-Prerender2.0机制解读

选择策略

他们是一个大型网站,因此采用用户同意的方式是更好的选择。这种类似通配符的匹配方式会过于贪婪,因为不同的页面包含的链接数量差异极大,很难预测在整个网站范围内增加的额外负担。

可以说,加入 Speculations 最简单的方法是使用选择器。例如,我们可以使用类:

 <a href class=prefetch>Prefetched Linka>
<a href class=prerender>Prerendered Linka>

相应的推测规则:

 <script type=speculationrules>
{
"prefetch": [
{
"where": {
"selector_matches": ".prefetch"
},
...
}
],
"prerender": [
{
"where": {
"selector_matches": ".prerender"
},
...
}
]
}
script>

需要注意的是,prerender 已经包含了 prefetch 阶段,因此你不需要同时使用 class="prefetch prerender" ;只需要其中一个就足够了。

然而,我喜欢这种模式的自我实现:

 <a href data-prefetch>Prefetched Linka>
<a href data-prefetch=prerender>Prerendered Linka>

而它们各自的猜测规则是:

 <script type=speculationrules>
{
"prefetch": [
{
"where": {
"selector_matches": "[data-prefetch]"
},
...
}
],
"prerender": [
{
"where": {
"selector_matches": "[data-prefetch=prerender]"
},
...
}
]
}
script>

它将所有逻辑都包含在一个 data-prefetch 属性中,且 data-prefetch=prerender 匹配的冗余性,根据定义,不是问题(与 dns-prefetch preconnect 的情况类似,尽管它们的韦恩图中有重叠,但它们仍然相处得很好)。

【第1053期】Preload,Prefetch 和它们在 Chrome 之中的优先级

分层

有了这个简单的用户选择机制后,我想看看是否有办法巧妙而有效地进一步增强其功能,而不需要进行任何额外的配置。仅凭这两个属性,我可以做些什么来最大化 “猜测规则” 的优势呢?

我的想法是,如果我们明确标记了 data-prefetch data-prefetch=prerender ,是否可以按需升级前者为后者?当页面加载时,浏览器立即满足其预取和预渲染,但如果有人将预加载的链接悬停并展开,是否可以将其升级为完整的预渲染操作?

简单。

然后,我们是否可以将任何其他内部链接从无到有,升级为按需预取?

也很容易!

以积极性由强至弱的顺序进行考虑,同时牢记我们提到的两个常识,我们思考我们正在实现的目标的最佳方式是:

1、立即为我们选择加入的任何链路支付 LCP 费用。

 "prerender": [
{
"where": {
"selector_matches": "[data-prefetch=prerender]"
},
"eagerness": "immediate"
},
...
]

2、立即为我们选择加入的任何链接支付 TTFB 费用。

 "prefetch": [
{
"where": {
"selector_matches": "[data-prefetch]"
},
"eagerness": "immediate"
},
...
],

3、按需支付 LCP 费用,以补偿我们已经支付了 TTFB 费用的任何链接:

 "prerender": [
...
{
"where": {
"selector_matches": "[data-prefetch]"
},
"eagerness": "moderate"
}
]

4、按需付费,为任何其他内部链接支付 TTFB 成本:

 "prefetch": [
...
{
"where": {
"href_matches": "/*"
},
"eagerness": "moderate"
}
],

现在,客户能够使用 data-prefetch=prerender 属性预渲染极有可能或被鼓励执行的导航操作。(例如在顶级导航或首页上的号召性用语)。

不太可能但还是比较合理的热身选项(例如子导航中的项目)可以简单地使用 data-prefetch

其余的都只是一些空荡荡的节点,所有链接(除了已经达到最大值的 data-prefetch=prerender 之外)会根据需要升级到下一个类别。

将它们按照所需的格式和顺序排列在一起后,我们的 “猜测” 规则如下所示:

 <script type=speculationrules>
{
"prefetch": [
{
"where": {
"selector_matches": "[data-prefetch]"
},
"eagerness": "immediate"
},
{
"where": {
"href_matches": "/*"
},
"eagerness": "moderate"
}
],
"prerender": [
{
"where": {
"selector_matches": "[data-prefetch=prerender]"
},
"eagerness": "immediate"
},
{
"where": {
"selector_matches": "[data-prefetch]"
},
"eagerness": "moderate"
}
]
}
script>

我们可以将这些规则应用到这个示例页面上:







请到「今天看啥」查看全文