edge-rendering
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseEdge Rendering
Edge Rendering
Part of Agent Skills™ by googleadsagent.ai™
属于 Agent Skills™,由 googleadsagent.ai™ 提供
Description
描述
Edge Rendering generates and serves dynamic pages at the network edge, eliminating origin round-trips for content that varies by city, service, or user segment. This skill powers googleadsagent.ai™'s system of 18,000+ pages generated from a matrix of 116 services across 155+ cities, each with unique content, structured data, and SEO metadata—all rendered at the edge with sub-50ms TTFB globally.
The city × service page matrix demonstrates the power of edge rendering at scale. Rather than pre-building 18,000 static pages or routing every request to a centralized origin, Workers generate each page on demand using templates, city-specific data from KV, and service metadata from D1. Rendered pages are cached at the edge with stale-while-revalidate semantics, providing instant responses while keeping content fresh.
This pattern extends beyond SEO landing pages to any content that follows a combinatorial template: product × location pages, event × venue pages, or service × industry pages. The edge rendering pipeline handles template resolution, data injection, structured data generation (JSON-LD), meta tag construction, and cache management as a unified system.
边缘渲染在网络边缘生成并提供动态页面,消除了针对因城市、服务或用户细分而不同的内容的源站往返请求。该技能为googleadsagent.ai™的系统提供支持,该系统基于155+城市的116项服务矩阵生成了18000+个页面,每个页面都有独特的内容、结构化数据和SEO元数据——所有这些都在边缘渲染,全球范围内首字节时间(TTFB)低于50毫秒。
城市×服务页面矩阵展示了大规模边缘渲染的能力。无需预构建18000个静态页面或将每个请求路由到中心化源站,Workers会按需使用模板、KV中的城市特定数据以及D1中的服务元数据生成每个页面。渲染后的页面会在边缘缓存,并采用stale-while-revalidate语义,在保持内容新鲜的同时提供即时响应。
这种模式不仅适用于SEO落地页,还适用于任何遵循组合模板的内容:产品×位置页面、活动×场地页面或服务×行业页面。边缘渲染流水线将模板解析、数据注入、结构化数据生成(JSON-LD)、元标签构建和缓存管理整合为一个统一系统。
Use When
适用场景
- Generating pages from a combinatorial matrix (city × service, product × category)
- Serving SEO-critical content that must have fast TTFB globally
- Building landing page systems with thousands of unique URLs
- Replacing static site generation that takes hours to build
- Implementing stale-while-revalidate caching at the edge
- Rendering structured data (JSON-LD) dynamically per page
- 从组合矩阵(城市×服务、产品×分类)生成页面
- 提供对SEO至关重要且需全球范围内快速TTFB的内容
- 构建包含数千个唯一URL的落地页系统
- 替代需要数小时构建的静态站点生成(SSG)
- 在边缘实现stale-while-revalidate缓存
- 为每个页面动态渲染结构化数据(JSON-LD)
How It Works
工作原理
mermaid
graph TD
A[Request: /google-ads/chicago] --> B[Worker: Parse city + service]
B --> C{Edge Cache Hit?}
C -->|Hit| D[Return Cached HTML]
C -->|Miss| E[Fetch City Data from KV]
E --> F[Fetch Service Data from D1]
F --> G[Render Template]
G --> H[Inject JSON-LD Structured Data]
H --> I[Generate Meta Tags]
I --> J[Cache at Edge]
J --> K[Return Fresh HTML]
D --> L[Background: Revalidate if Stale]Every request resolves to a (city, service) tuple. The Worker checks the edge cache first. On miss, it fetches city and service data in parallel, renders the template, injects structured data, and caches the result. Stale entries trigger background revalidation without blocking the response.
mermaid
graph TD
A[Request: /google-ads/chicago] --> B[Worker: Parse city + service]
B --> C{Edge Cache Hit?}
C -->|Hit| D[Return Cached HTML]
C -->|Miss| E[Fetch City Data from KV]
E --> F[Fetch Service Data from D1]
F --> G[Render Template]
G --> H[Inject JSON-LD Structured Data]
H --> I[Generate Meta Tags]
I --> J[Cache at Edge]
J --> K[Return Fresh HTML]
D --> L[Background: Revalidate if Stale]每个请求都会解析为(城市,服务)元组。Worker首先检查边缘缓存。如果未命中,则并行获取城市和服务数据,渲染模板,注入结构化数据,并缓存结果。过期的条目会触发后台重新验证,不会阻塞响应。
Implementation
实现代码
typescript
export default {
async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
const url = new URL(request.url);
const [, service, city] = url.pathname.split("/");
const cacheKey = new Request(url.toString());
const cache = caches.default;
let response = await cache.match(cacheKey);
if (response) {
const age = parseInt(response.headers.get("age") ?? "0");
if (age > 3600) {
ctx.waitUntil(revalidate(env, cache, cacheKey, service, city));
}
return response;
}
return revalidate(env, cache, cacheKey, service, city);
},
} satisfies ExportedHandler<Env>;
async function revalidate(
env: Env, cache: Cache, cacheKey: Request, service: string, city: string
): Promise<Response> {
const [cityData, serviceData] = await Promise.all([
env.CITY_KV.get<CityData>(city, "json"),
env.DB.prepare("SELECT * FROM services WHERE slug = ?").bind(service).first<ServiceData>(),
]);
if (!cityData || !serviceData) {
return new Response("Not Found", { status: 404 });
}
const html = renderPage(cityData, serviceData);
const response = new Response(html, {
headers: {
"Content-Type": "text/html;charset=UTF-8",
"Cache-Control": "public, s-maxage=86400, stale-while-revalidate=3600",
},
});
await cache.put(cacheKey, response.clone());
return response;
}
function renderPage(city: CityData, service: ServiceData): string {
const jsonLd = {
"@context": "https://schema.org",
"@type": "LocalBusiness",
name: `${service.name} in ${city.name}`,
address: { "@type": "PostalAddress", addressLocality: city.name, addressRegion: city.state },
geo: { "@type": "GeoCoordinates", latitude: city.lat, longitude: city.lng },
url: `https://googleadsagent.ai/${service.slug}/${city.slug}`,
};
return `<!DOCTYPE html>
<html lang="en">
<head>
<title>${service.name} in ${city.name} | googleadsagent.ai</title>
<meta name="description" content="${service.description} for businesses in ${city.name}, ${city.state}." />
<script type="application/ld+json">${JSON.stringify(jsonLd)}</script>
</head>
<body>${service.template.replace("{{city}}", city.name)}</body>
</html>`;
}typescript
export default {
async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
const url = new URL(request.url);
const [, service, city] = url.pathname.split("/");
const cacheKey = new Request(url.toString());
const cache = caches.default;
let response = await cache.match(cacheKey);
if (response) {
const age = parseInt(response.headers.get("age") ?? "0");
if (age > 3600) {
ctx.waitUntil(revalidate(env, cache, cacheKey, service, city));
}
return response;
}
return revalidate(env, cache, cacheKey, service, city);
},
} satisfies ExportedHandler<Env>;
async function revalidate(
env: Env, cache: Cache, cacheKey: Request, service: string, city: string
): Promise<Response> {
const [cityData, serviceData] = await Promise.all([
env.CITY_KV.get<CityData>(city, "json"),
env.DB.prepare("SELECT * FROM services WHERE slug = ?").bind(service).first<ServiceData>(),
]);
if (!cityData || !serviceData) {
return new Response("Not Found", { status: 404 });
}
const html = renderPage(cityData, serviceData);
const response = new Response(html, {
headers: {
"Content-Type": "text/html;charset=UTF-8",
"Cache-Control": "public, s-maxage=86400, stale-while-revalidate=3600",
},
});
await cache.put(cacheKey, response.clone());
return response;
}
function renderPage(city: CityData, service: ServiceData): string {
const jsonLd = {
"@context": "https://schema.org",
"@type": "LocalBusiness",
name: `${service.name} in ${city.name}`,
address: { "@type": "PostalAddress", addressLocality: city.name, addressRegion: city.state },
geo: { "@type": "GeoCoordinates", latitude: city.lat, longitude: city.lng },
url: `https://googleadsagent.ai/${service.slug}/${city.slug}`,
};
return `<!DOCTYPE html>
<html lang="en">
<head>
<title>${service.name} in ${city.name} | googleadsagent.ai</title>
<meta name="description" content="${service.description} for businesses in ${city.name}, ${city.state}." />
<script type="application/ld+json">${JSON.stringify(jsonLd)}</script>
</head>
<body>${service.template.replace("{{city}}", city.name)}</body>
</html>`;
}Best Practices
最佳实践
- Fetch city and service data in parallel with , never sequentially
Promise.all - Use to serve cached content while refreshing in the background
stale-while-revalidate - Generate JSON-LD structured data for every page to maximize search engine visibility
- Keep KV values under 25MB and D1 queries under 100ms for consistent edge performance
- Implement a sitemap generator that reflects the current city × service matrix
- Monitor cache hit ratios—target above 95% for production traffic
- 使用并行获取城市和服务数据,切勿串行获取
Promise.all - 使用在后台刷新内容的同时提供缓存内容
stale-while-revalidate - 为每个页面生成JSON-LD结构化数据,以最大化搜索引擎可见性
- 保持KV值在25MB以下,D1查询在100ms以内,以确保稳定的边缘性能
- 实现一个能反映当前城市×服务矩阵的站点地图生成器
- 监控缓存命中率——生产流量目标应高于95%
Platform Compatibility
平台兼容性
| Platform | Support | Notes |
|---|---|---|
| Cursor | Full | Worker development + deployment |
| VS Code | Full | Wrangler integration |
| Windsurf | Full | Edge-first development |
| Claude Code | Full | Template + Worker generation |
| Cline | Full | Edge architecture support |
| aider | Partial | Template generation only |
| 平台 | 支持情况 | 说明 |
|---|---|---|
| Cursor | 完全支持 | Worker开发与部署 |
| VS Code | 完全支持 | Wrangler集成 |
| Windsurf | 完全支持 | 边缘优先开发 |
| Claude Code | 完全支持 | 模板与Worker生成 |
| Cline | 完全支持 | 边缘架构支持 |
| aider | 部分支持 | 仅模板生成 |
Related Skills
相关技能
- Cloudflare Workers
- CI/CD Pipelines
- Observability
- CodeQL & Semgrep
- Cloudflare Workers
- CI/CD 流水线
- 可观测性
- CodeQL & Semgrep
Keywords
关键词
edge-renderingcity-service-pagescloudflare-workersseojson-ldstale-while-revalidatedynamic-pagesstructured-data© 2026 googleadsagent.ai™ | Agent Skills™ | MIT License
edge-renderingcity-service-pagescloudflare-workersseojson-ldstale-while-revalidatedynamic-pagesstructured-data© 2026 googleadsagent.ai™ | Agent Skills™ | MIT License