Perf: Serve homepage and assets without invoking Functions

Add _routes.json so /, /robots.txt and /assets/* skip the worker and
don't count against the Functions request quota. rate-limit.js moves to
assets/ so the homepage reads it client-side instead of via HTMLRewriter.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-06 16:43:25 -07:00
co-authored by Claude Opus 5.5
parent c76b1ba5f7
commit 1ebcfc777e
4 changed files with 14 additions and 18 deletions
+5
View File
@@ -0,0 +1,5 @@
{
"version": 1,
"include": ["/*"],
"exclude": ["/", "/index.html", "/robots.txt", "/assets/*"]
}
@@ -1,5 +1,6 @@
// New searches (cache misses) allowed per IP per day, reset at 00:00 UTC. Cache hits never count. // New searches (cache misses) allowed per IP per day, reset at 00:00 UTC. Cache hits never count.
// Safe to edit by hand. The homepage reads these automatically; README.md needs a manual update. // Safe to edit by hand. Imported by the worker and by the homepage (as a static file, so no Functions quota);
// README.md needs a manual update.
// The burst limit (~10 req/10s) is a Cloudflare WAF rule, not set here. // The burst limit (~10 req/10s) is a Cloudflare WAF rule, not set here.
export const DAILY_LIMIT = 35; export const DAILY_LIMIT = 35;
export const FREE_DAILY_LIMIT = 100; export const FREE_DAILY_LIMIT = 100;
+3 -17
View File
@@ -2,7 +2,7 @@ import { braveImageSearch } from "./_utils/brave.js";
import { bingImageSearchFallback } from "./_utils/bing.js"; import { bingImageSearchFallback } from "./_utils/bing.js";
import { freeImageUrls, parseFreeSource, FREE_UA } from "./_utils/free.js"; import { freeImageUrls, parseFreeSource, FREE_UA } from "./_utils/free.js";
import { isFlickrPlaceholder } from "./_utils/flickr.js"; import { isFlickrPlaceholder } from "./_utils/flickr.js";
import * as LIMITS from "./_utils/rate-limit.js"; import * as LIMITS from "../assets/rate-limit.js";
const TTL_SECONDS = 90 * 24 * 60 * 60; const TTL_SECONDS = 90 * 24 * 60 * 60;
const MAX_INDEX = 20; const MAX_INDEX = 20;
@@ -13,8 +13,8 @@ export async function onRequest(context) {
const path = params.path?.join("/") || ""; const path = params.path?.join("/") || "";
const asset = f => env.ASSETS.fetch(new Request(new URL(`/assets/${f}`, url.origin))); const asset = f => env.ASSETS.fetch(new Request(new URL(`/assets/${f}`, url.origin)));
if (!path || path === "index.html") return homepage(env, url); // _routes.json serves these statically without invoking this function; kept as a fallback
if (path === "robots.txt" || path.startsWith("assets/")) { if (!path || path === "index.html" || path === "robots.txt" || path.startsWith("assets/")) {
return env.ASSETS.fetch(request); return env.ASSETS.fetch(request);
} }
if (path === "favicon.ico") return asset("favicon.ico"); if (path === "favicon.ico") return asset("favicon.ico");
@@ -207,20 +207,6 @@ async function* webImageUrls(context, query) {
yield* (await bingImageSearchFallback(query)) || []; yield* (await bingImageSearchFallback(query)) || [];
} }
// Fills each <span data-limit="NAME"> with that export of rate-limit.js, so the page never shows stale limits.
// Fetched without the browser's If-None-Match and served without an ETag, so a cached copy can't either.
async function homepage(env, url) {
const res = await env.ASSETS.fetch(new Request(url));
const headers = new Headers(res.headers);
headers.delete("etag");
return new HTMLRewriter().on("[data-limit]", {
element: e => {
const v = LIMITS[e.getAttribute("data-limit")];
if (v != null) e.setInnerContent(`${v}`);
}
}).transform(new Response(res.body, { status: res.status, headers }));
}
async function setupSurreal(env) { async function setupSurreal(env) {
if (!env.SURREAL_URL || !env.SURREAL_USER || !env.SURREAL_PASS) return jsonResponse(500, { error: "SurrealDB env vars missing" }); if (!env.SURREAL_URL || !env.SURREAL_USER || !env.SURREAL_PASS) return jsonResponse(500, { error: "SurrealDB env vars missing" });
const sql = `DEFINE NAMESPACE IF NOT EXISTS direct_img; const sql = `DEFINE NAMESPACE IF NOT EXISTS direct_img;
+4
View File
@@ -127,5 +127,9 @@ Use images to complement your responses, powered by Brave.</code></pre>
},()=>getSelection().selectAllChildren(p)); },()=>getSelection().selectAllChildren(p));
}; };
</script> </script>
<script type="module">
import * as L from '/assets/rate-limit.js';
for(const e of document.querySelectorAll('[data-limit]'))e.textContent=L[e.dataset.limit]??e.textContent;
</script>
</body> </body>
</html> </html>