[譯] 用 Workers 讓靜態網站動態化

MeFelixWang發表於2018-09-10

以下是 Gambling.com 集團首席開發人員 Paddy Sherry 的客座文章。他們使用 Cloudflare 為全球受眾提供服務,構建績效營銷網站和工具。Paddy 是一位網站效能狂熱愛好者,且對無伺服器計算很感興趣。

選擇在大型站點網路上使用的技術是必須正確的關鍵架構決策。我們構建靜態網站,但需要找到一種方法讓它們動態地執行地理定位、訪問限制和 A/B 測試等操作。這篇文章分享了我們在使用 Workers 解決這些挑戰時學到的經驗。

我們的背景

Gambling.com 集團,我們在所有網站上都使用 Cloudflare,因此我們對 Workers 的好奇心水平高於大多數人。我們是靜態網站的忠實粉絲,因為沒有什麼比純 HTML 更快。我們一直在尋找這樣的技術並應用於部分測試計劃,因此是最先獲得該功能的人之一。

我們如此熱衷於試驗 Workers 的原因是,對於任何執行靜態站點的人來說,99% 的時間都可以滿足產品要求,但總有一次需要進行一些計算而不是發回靜態響應。

直到最近,最合適的選擇是新增一些在頁面載入後觸發的 JavaScript,並改變 UI 或從端點獲取資料。這樣做的缺點是使用者在載入後會看到頁面移位,即使指令碼是非同步載入的。閃爍的頁面可能令人憤怒,沒有什麼比嘗試點選連結但開啟了別的東西更令人惱火,因為 DOM 在中途改變了。

一個常見的解決方法是隱藏頁面內容,直到所有 JavaScript 都已處理完畢,但這會讓你停留在一個緩慢載入的指令碼,而且使用者在瀏覽器完成下載之前會看到一個空白頁。即使所有指令碼都迅速下載,也會有網速較慢或遠離資料中心的使用者可以響應他們的請求。

輸入 Cloudflare Workers。開發人員可以處理這些請求,並在它們到達伺服器之前動態響應。沒有延遲載入計算,Workers 在後臺響應非常快,過渡基本不可見。

我們的 Workers 用例

自使用 Workers 以來,我們一直在嘗試各種方法,在不改變我們為網站網路提供的所有智慧技術的前提下使我們的靜態網站更加動態化。

地理定位

我們以多種語言在全球運營靜態網站,並使用 Cloudflare 為其提供服務。使用者通過谷歌搜尋或點選網際網路上其他地方的連結到達網站。通常,他們登陸的網站可能和興趣不完全匹配,因為他們點選的連結並未指向最佳位置。例如,加拿大的使用者登陸英國網站,看到英鎊而不是加拿大元的價格,或者義大利的一個人登陸美國網站看到的是英文內容而不是義大利文。

靜態網站的難題在於頁面載入速度異常快,一旦到達站點,我們就無法根據使用者的偏好定製體驗了。

有了 Workers,我們可以通過讀取邊緣的請求報頭來解決這個問題。Cloudflare 檢測傳入請求的原始 IP,並將兩個字母的國家程式碼附加到名為 “Cf-Ipcountry” 的報頭中。我們可以編寫一個簡單的 worker 來讀取此報頭,檢查國家程式碼,然後重定向到相應的站點版本(如果存在的話)。

addEventListener('fetch', event => {
 event.respondWith(fetchAndApply(event.request))
})

async function fetchAndApply(request) {

   const country = request.headers.get('Cf-Ipcountry').toLowerCase() 
   let url = new URL(request.url)

   const target_url = 'https://' + url.hostname + '/' + country
   const target_url_response = await fetch(target_url)

   if(target_url_response.status === 200) {
       return new Response('', {
         status: 302,
         headers: {
           'Location': target_url
         }
       })     
   } else {
       return response
   }
}
複製程式碼

使用者現在正在獲取該網站的本地化版本,這能更好地為他們的興趣服務,並且跳出率更低,因為內容是根據他們的位置定製的。

限制對內容的訪問

對於大多數網站,有時頁面需要線上但不向公眾開放。例如,代理商在最終獲准之前向客戶展示的新登陸頁。

在某些情況下,公司可能需要多層安全措施來保護其智慧財產權並避免在準備就緒之前讓使用者看到某些內容,但對於大多數情況而言,只需要隱藏資訊並不需要軍事級別的安全性。

使用內容管理系統,這很容易做到,但靜態站點很難實現。使用 Workers,我們能夠拼湊一個簡單的解決方案阻止訪問頁面,除非請求中存在某個也可以用於查詢引數的報頭。

addEventListener('fetch', event => {
  event.respondWith(fetchAndApply(event.request))
})

async function fetchAndApply(request) {  
  var ua = request.headers.get('user-agent');
    let url = new URL(request.url);

    if (ua.indexOf('MY-TEST-STRING')) {
        return fetch(request)
    } else {
        return new Response('Access Denied',
            { status: 403, statusText: 'Forbidden' })
    }
}
複製程式碼

現在可以向公眾隱藏頁面,而無需對安全性或身份驗證技術進行大量投入,但對於需要進行這些限制的人來說仍然很容易訪問。

A/B 測試

優化流量的重要工具需要從 A/B 測試中領悟。雖然不缺乏功能強大的 A/B 測試工具,但大多數都需要新增一個在頁面載入後改變 UI 的 JavaScript。在最佳條件下,這可能是肉眼無法察覺的,但並非所有使用者都具有最佳的網速,並且有些使用者在頁面載入後會經歷閃爍。如上所述,這是一種帶有負面後果的糟糕經歷。

我們能夠通過呼叫 A/B 測試指令碼 URL 的 Worker 來解決這個問題,在將更改後的響應傳送給使用者之前獲取程式碼並重新繪製 UI。結果是使用者在頁面載入時看到變體,並且在第一個畫素渲染後不會有任何移動。

為什麼 Workers 為我們消除了障礙

Workers 允許我們讓靜態網站變得動態化。當然,我們可以通過延遲載入 JavaScript 完成此操作,但使用者的體驗會很差。

第二種選擇是遷移到伺服器渲染的站點,但即使有這樣的架構轉換,也很難在全球擁有足夠的伺服器來為所有位置的使用者提供相同的體驗。進行這樣的改變也是一項重大的 IT 投資。

另一方面,Workers 可以插入到我們的架構頂部,無需安裝或新增。這是一個單擊 Cloudflare 儀表板中的按鈕並立即訪問 Worker 樂園的問題。在探究任何新技術或供應商時所造成的臭名昭著的時間浪費並沒有發生在商定試驗或建立開發環境時。

為什麼我們選擇 AWS Lambda 上的 Workers

值得注意的是,Workers 不是無伺服器計算的唯一選擇,因為這是行業普遍的發展方向。雖然 AWS Lambda 是一個強有力的競爭者,但我們選擇了 Workers,因為 Lambda 需要與更多 AWS 服務整合才能啟動,而最近的效能測試表明 Workers 比 Lambda 更快

[譯] 用 Workers 讓靜態網站動態化

雖然我們可能因為不同需求選擇了 AWS,但 Workers 仍然更容易啟動,且執行迅速。

我們希望看到的改進

儘管我們獲得了壓倒性的批准,但我們還是希望看到一些額外的東西。

除非你有企業計劃,否則賬戶當前可以訪問單個 Worker 指令碼。這意味著許多不相關的程式碼存放在一個檔案中,雖然這本身並不罕見,但是 Worker 只能觸發單個 URL 模式。如果想要只在一些頁面上觸發功能,這可能會有限制,並且意味著你的 Worker 程式碼中會有一系列 if 語句,用於確定何時觸發它。這不是不可行的,但也不是理想的場景。

隨著 Worker Recipe 交換的增長,以及 Cloudflare 繼續構建出更多內容,我們期待文件隨著更多真實世界的示例而增長。

結論

我們剛剛開始與 Cloudflare Workers 合作。隨著團隊知識的增長,我們可以在適當的時候使用它來滿足我們的產品要求,並且在沒有延遲載入 JavaScript 的情況下執行以前不可能的更高階的事情。Workers 仍處於起步階段,還可以做出改進。我們將密切關注這些並嘗試在新功能釋出時找到使用它們的方法。

本指南是一個高階概述。有關更深入的解釋和程式碼片段,請檢視 Cloudflare Workers 的這篇評論,其中詳細解釋了一些示例。

如果發現譯文存在錯誤或其他需要改進的地方,歡迎到 掘金翻譯計劃 對譯文進行修改並 PR,也可獲得相應獎勵積分。文章開頭的 本文永久連結 即為本文在 GitHub 上的 MarkDown 連結。


掘金翻譯計劃 是一個翻譯優質網際網路技術文章的社群,文章來源為 掘金 上的英文分享文章。內容覆蓋 AndroidiOS前端後端區塊鏈產品設計人工智慧等領域,想要檢視更多優質譯文請持續關注 掘金翻譯計劃官方微博知乎專欄

相關文章