使用 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 時非常容易。 否則,找到一個標誌,例如對hrefsrc屬性中唯一位置的引用。

您會發現使用通配符和“命令模式”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 的反向代理測試平台為與開發人員的豐富溝通奠定了基礎。