Utilize OG Edge Functions Reduced 90% OG Build Time

使用 Edge Function 生成 OG 圖,建構時間縮短 90%

前言

隨著這個部落格的文章逐漸增多,靜態生成的壓力也隨之上升,舉例來說在日常開發會需要花費近 10 分鐘的時間🔗 建構網站所有內容:

明顯這個問題還會隨著網站規模擴大持續惡化,特別費時的預覽圖建構數量是:(語言 x 文章數量)

發現問題

WebDong🔗 是個上百篇文章的靜態生成部落格。

07:31:30 ├─ /post/build-product-from-scratch-tokens/og.png (+691ms)

如果查看建構 log,會發現先前設立的 OG 圖片靜態生成端點🔗 佔據最多建構時間,光是一篇文章三種語系的圖就要花費近 2 秒渲染,而現在有上百篇文章,很明顯算上圖片渲染網站已經大到要等的地步了。

解決問題

由於全站一次性 SSG🔗 渲染代價越來越大,可以考慮把渲染改為即時在伺服端執行如: SSR🔗 或是混合 ISR🔗。鑑於部落格內容不常更動,加上成本考量,延續最大程度的靜態渲染是合理的選擇,而針對 OG 圖片渲染可以包成 Serverless Function 在需要時呼叫。

考量依據是:

  1. 無須大幅度改動現成架構就能解決問題
  2. 乾淨俐落的解決擴展問題
  3. 低運行成本,盡量避免開設伺服器

Serverless Function 如何幫上忙

Serverless Function 是指你只需撰寫程式邏輯,不需要管理伺服器基礎架構的雲端運算模型,而 Edge Function 是一種運行在離用戶最近的邊緣節點(Edge)上的伺服器無伺服器函數(Serverless Function)。簡單來說,代碼不會部署在單一伺服器,而是會在全球多個資料中心上分布執行,讓用戶能夠更快地獲得回應。

平台Edge Function 服務名稱
CloudflareWorkers / Pages Functions
VercelEdge Functions
NetlifyEdge Functions
AWSLambda@Edge
DenoDeno Deploy

由於部屬靜態網站原先是用 Cloudflare Pages🔗 服務,因此自然而然的使用它們的全家桶服務:Pages Functions🔗

Cloudflare Functions 動手做

Cloudflare Functions🔗 的文件算是詳盡且整合得很好,甚至它們預寫好了多個常見用途的 package 供你馬上引用,像是能運用事先整合好的 @cloudflare/pages-plugin-vercel-og🔗 背後使用 @vercel/og🔗 生成圖像:

import React from "react";
import { ImageResponse } from "@cloudflare/pages-plugin-vercel-og/api";
export const onRequest: PagesFunction = async () => {
return new ImageResponse(
<div style={{ display: "flex" }}>Hello, world!</div>,
{
width: 1200,
height: 630,
}
);
};
  1. 創建路由 :會需要了解一下 Routing 的規則🔗,創建新端點。
  2. 型別 :使用 TypeScript 會需要根據文件🔗配置並生成對應的型別。
  3. 部屬與本地實驗 :要了解一下 Wrangler CLI 如何管理 Cloudflare 的服務。
  4. 自動化部屬 :不同平台同樣有 詳盡的配套🔗 自動化部屬 Cloudflare 服務。

感謝前人鋪路,一個生成圖片的端點三兩下就能遷移到雲上即時根據需求渲染與擴張,想要看我具體替部落格建設的過程可以參考該 PR:feat: og-page-function-api🔗。很大程度也感謝 og-image-generator-cloudflare-worker🔗 倉庫有很不錯的範例展示進階設置,像是:在 Edge 環境用各種方式載入字體、載入圖片、快取……等

總結

在技術選擇時也須特別考慮服務的極限,舉例來說 Pages Function 免費版 每請求最高就 10ms 的 CPU 運算🔗,複雜的圖像生成隨便都會超過造成超時。可能會需要升級並調高運算時間設定🔗 才能正確運作……

在移除建構網站時預渲染本地 OG 圖的工作後可以看到 CD 建構時間從原先的快 10 分鐘🔗 進步為 1 分鐘多一點🔗,透過規劃合適的架構,成功達到了快 10 倍的效能且保留同樣的功能。

上方為新 OG 圖,下方為舊 OG 圖
上方為新 OG 圖,下方為舊 OG 圖

延伸閱讀