使用 Cloudflare 的 HTMLRewriter 实现核心 Web Vitals 策略的函数
已发表: 2022-02-04我们的核心 Web Vitals A/B 测试指南解释了一系列小步骤,其中包含两个服务和一个浏览器扩展,用于为前端代码策略编写测试。 30 年前,我们会复制页面的原始源代码以运行查找和替换操作,直到我们可以管理放置在启用 Web 的文件夹中的页面的传真,以展示相同类型的推荐。
我们不必再这样做了。
二十年前设置反向代理和编写用于执行 SEO 的软件仅限于少数自己构建和托管基础设施的公司。 Cloudflare 现在为我们提供了交钥匙解决方案。 您可以使用免费帐户启动并运行。 要更改前端代码,请使用 Cloudflare 的HTMLRewriter() JavaScript API。
代码相对容易理解。
使用 Core Web Vitals,它是即时性、感知到的需求和能够循环通过各种测试的快速性,最终显示出价值并给人留下深刻印象。 通过我们指南中概述的步骤,您可以使用基本平台。 我们将编写用于进行常见更改的函数,以便您可以立即开始测试真正的策略。
HTMLRewriter()
如果您一直在关注,您可能知道我们的脚本提供了预加载元素的选项,您可以在 LCP 的请求参数中指定该选项。 当缺少值时,我们会返回一个表单,只是为了方便添加您的参考。 还有一个称为重要性的占位符,我们也将解决这个问题。 重要的是了解我们将要做什么。
HTMLRewriter() API 使我们能够使用 jQuery 样式的元素选择器附加到原始页面源中的 HTML 元素,以便从该立足点运行 JavaScript。 您将能够以强大的方式修改元素、整个元素组甚至基础文档。 例如,您可以编辑页面的标题。 在生产中,您的编辑成为标题,并在 Google 和 Bing 中被编入索引。
您将遇到的一个复杂情况是您只能编辑原始源,而不是水合文档对象模型 (DOM)。 查看原始源代码的一种快速方法是使用浏览器的内置查看源代码功能。 例如,对于 Firefox,查看源代码会以红色突出显示验证错误。 即使浏览器“修复”损坏的 HTML,通常也可以使用我们的 Worker 修复。
在 DevTools 中,“Sources”选项卡提供对原始源代码的访问。 使用首选项设置始终“漂亮打印”源,这将对其进行格式化,以便您可以扫描代码以寻找优化。 另一个偏好提示是在 DevTools 打开时绕过缓存的设置。 此工作流程将随时为您提供帮助,因此您的优化不会导致参考错误。
元素选择器
当您发现要使用HTMLRewriter()修复的内容时,您将需要缩小更改范围并隔离元素以避免更改超出您预期的代码。 尽可能使用最独特的选择器,这在元素具有唯一 ID 时非常容易。 否则,找到一个标志,例如对href或src属性中唯一位置的引用。
您会发现使用通配符和“命令模式”vim 风格的正则表达式匹配属性值的能力。 您还可以提供多个条件,即使具有相同的属性名称。 使用您的 vim 功能将匹配范围缩小到单个元素,或者使用更广泛的表达式匹配一组元素。 然后,逻辑可以分离更改之间的关注点。
示例匹配通配符“fonts.g”预取链接元素以删除:fonts.googleapis.com。
.on(`link[rel="dns-prefetch"][href*="fonts.g"]`, removeEl()) 显示href属性的两个匹配项的示例,将其缩小为多个文件中的单个文件。
.on('link[href^="https://example.com/static/version"][href$="/print.css"]', unblockCSS()) 上面的第一个示例使用通配符匹配,其中字符串“fonts.g”可以出现在链接元素的href属性中的任何位置。 这是一个广泛匹配的示例,它可能附加到多个链接元素以执行适当的操作,例如删除匹配的元素(如果有)。
上面的第二个示例显示了如何选择以字符串开头并以另一个字符串结尾的特定链接元素,但两者之间可以有任何内容。 这对于选择作为构建系统一部分的单个元素很有用,其中可能存在用于动态命名的浏览器缓存清除的版本控制令牌目录。
链接元素
链接元素由于它们的几个属性而具有多面性。 因此,它们可以用于多种目的。 不要与链接(如锚点)混淆,链接元素通常是您开始寻找快速表现策略的地方。 一些预加载和预连接链接元素实际上可能会妨碍或完全没有必要。
您最多只能同时连接六台主机。 您的第一个策略是充分利用它们。 尝试删除所有优先提示链接元素语句并测试结果。 如果时间安排错误,则一次添加一个,并测试每个的真正影响。 您将需要学习如何深入阅读 WebpageTest 瀑布图。
在此之后,策略转向资源加载,这也非常多地涉及链接元素,但不仅限于此。 在这一点上,我们也想看看脚本。 资源加载的顺序会对事情产生非常负面的影响。 我们的测试平台非常适合尝试通过阅读瀑布图收集到的各种策略。 保持 DevTools 的控制台抽屉打开,以便在工作时检查错误。
移除元素
删除元素非常简单。 一旦您选择了一个元素或一组元素, HTMLRewriter().on()语句中的下一个字段就是您编写脚本块的地方。 您可以使用花括号来执行此操作。 您可以引用命名函数。 或者您可以为之前定义的对象构建一个新的class实例,在这种情况下,这可能是过度设计的。
当您遇到示例 Worker 代码时,您可能会看到class初始值设定项。 删除元素真正需要的是以下函数。 使用命名类对象完成的任何事情都可以使用普通函数(对象)完成,使用更少的代码,更少的错误,更易读的语法和更易教。 当我们深入研究持久对象时,我们将重新访问class构造函数。
element: (el) => { el.remove(); } 简而言之,这个块定义了一个引用元素实例的变量“el”,并且代码块调用内置的remove()元素方法,您将在相应的文档中找到详细信息。 您可以使用所有HTMLRewriter()元素方法来与元素匹配的实例一起使用。 删除元素是更容易理解的元素之一。
解除阻塞渲染阻塞资源
解除对script元素的阻塞比解除对样式表资源的阻塞要容易得多。 幸运的是,我们有一个布尔属性,用于向浏览器发出我们想要异步加载脚本或完全推迟它的信号(当有空闲时间时)。 这是理想的! 另一方面,样式表需要一点“破解”才能让它们畅通无阻——它们需要一些内联的 Javascript。

本质上,我们将样式表链接元素引用转换为预加载以解除阻塞。 但这会将链接元素的性质更改为不会应用样式规则的性质。 Preload 下载资源以将它们存储在本地缓存中,以备需要时使用,仅此而已。 DevTools 会在预加载资源并且不方便使用时向您发出警告 — 那时您知道可以删除它!
预加载然后使用onload属性运行 JavaScript 以将其从预加载更改回样式表是 CSS“破解”,以解除对原本自然呈现阻塞资源的阻塞。 使用 JavaScript 的this关键字允许您更改其属性,包括rel属性(以及onload属性本身)。 该模式还为非 JavaScript 会话提供了回填。
这是我们的unblockCSS()函数,它使用现成的元素方法来实现策略。
const unblockCSS = () => ({ element: (el) => { el.removeAttribute('media'); el.setAttribute('rel', 'preload'); el.setAttribute('as', 'style'); el.setAttribute('onload', "this.onload=null;this.rel='stylesheet';this.media='all'"); el.after(` `, { html: true }); }}); 选择呈现阻塞的链接元素样式表引用并在它们上调用此函数。 它允许浏览器通过预加载来开始下载样式表。 加载后, rel属性切换回样式表并立即应用 CSS 规则。 如果在此更改后出现样式问题,则需要按正常请求顺序加载一个或多个工作表。
该函数充当可重用的代码块。 使用HTMLRewriter()切换您的元素选择,并根据您的方法一次或一组测试解锁 CSS 表的差异。 利用该策略尽可能多地实现整体策略畅通。 但是,请始终记住查找因更改 CSS 和脚本资源而导致的问题。
脚本优先级
加载样式的顺序可能会影响设计。 出乎意料的快速加载样式表规则将被加载较慢的样式表规则覆盖。 您还必须在以交替顺序加载脚本时进行观察,以便在评估文档时它们被评估并驻留在内存中。 引用错误可以级联成几十个或几百个脚本错误。
检查问题的最佳方法是观察控制台抽屉并模拟慢速网络连接。 这可能会将问题夸大到在 DevTools 中应该很明显的程度。 如果使用更强大的 CPU 处理脚本资源并以电缆调制解调器速度或更快的速度加载,您可能会错过一个严重错误。 请求也得到很好的间隔。
这是我们更改或添加异步和延迟属性的函数。
const makeAsyncJS = () => ({ element: (el) => { el.removeAttribute("defer"); el.setAttribute("async", "async"); } }); const makeDeferJS = () => ({ element: (el) => { el.removeAttribute("async"); el.setAttribute("defer", "defer"); } }); 如果脚本最初没有异步或延迟,则运行removeAttribute()元素方法以获得更可重用的代码块是无害的。 如果您在一个一次性项目上快速工作,您可以放心地忽略这一点,您可能正在内联编写此代码,而不是调用您之前在脚本中定义的函数。
SEO 的 Alt 属性
如前所述,我们的 A/B 核心 Web Vitals 策略指南在设计上旨在让我们拥有一个功能齐全的边缘计算测试平台并运行,以展示未来 SEO 的内容,供开发人员文章和未来事件使用。 在去年(2021 年)的 SMX West 活动中,我们演示了使用 Cloudflare Workers 构建网站,实现了 Lighthouse 烟花(在所有测试中得分 100)。
有很多东西需要到位才能得到烟花。 一个重要方面是所有图像都必须具有有效的alt属性。 该测试可以检测alt属性中的文本何时“无法描述”或存在但为空。 您需要描述相关图像中内容的词语。 一种方法可能是从src属性解析文件名。
这是一个从img src属性中提取文本以从带有连字符的文件名中提取alt文本的函数。
const img_alt = element.getAttribute('alt'); const img_src = element.getAttribute('src'); if (!img_alt) { element.setAttribute('alt', img_src.replace('-', ' ')); } 简而言之,这将在没有alt属性值的图像上查找条件。 当它的src属性文件名有可能被连字符时,它将用空格替换连字符以制定可能是合适的值。 此版本不适用于大多数情况。 它不会替换正斜杠或协议和域。 这仅作为一个起点。
测试更好的性能和更高的可见性
拥有一个用于尝试各种 Core Web Vitals 性能优化策略的测试平台对网站所有者来说令人印象深刻。 你应该在你的机构库中拥有这种能力。 通过我们将讨论和演示的策略,对于大多数网站来说,通过良好的分数略微提升 Google 排名是可以衡量的,并且在很大程度上是可以实现的。 收听 3 月 8 日至 9 日的现场表演。
SEO 技术人员长期以来一直建议提高搜索引擎排名的性能。 排名的好处从未如此清晰。 谷歌从字面上定义了这些指标并公布了它们的影响。 我们有 Cloudflare Workers 来实施 Edge SEO 补救措施,如此处所示,图像的alt属性。 我们借助 Cloudflare 的反向代理测试平台为与开发人员的丰富沟通奠定了基础。
