Utilize OG Generation by Edge Functions Reduced 90% 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 图

延伸阅读