Last active
February 3, 2022 22:38
-
-
Save dburles/21c1639388b2eb32ab004b30bf155063 to your computer and use it in GitHub Desktop.
Proof-of-concept Deno HTTP server that parallelises requests for JavaScript modules using `modulepreload` in a `link` header.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// A simple proof-of-concept Deno HTTP server that parallelises requests for JavaScript modules. | |
// This is achieved by resolving the module graph for each requested resource | |
// using Deno graph (https://github.com/denoland/deno_graph). | |
// The result is converted into a `link` header (https://developer.mozilla.org/en-US/docs/Web/HTML/Link_types/modulepreload). | |
// For example, if 'a.js' imports 'b.js' and 'b.js' imports 'c.js' (and so on..), | |
// a request for 'a.js' will yield the following `link` header: | |
// <http://domain/b.js>; rel="modulepreload", <http://domain/c.js>; rel="modulepreload", <http://domain/d.js>; rel="modulepreload" | |
// In turn, the requests for module a's dependencies are made together. | |
// A potential optimisation can be made by caching the result of `createGraph`. | |
import { createGraph } from "https://deno.land/x/[email protected]/mod.ts"; | |
import { Application } from "https://deno.land/x/[email protected]/mod.ts"; | |
import { extname } from "https://deno.land/[email protected]/path/mod.ts"; | |
const STATIC_ROOT = `${Deno.cwd()}/packages`; | |
const app = new Application(); | |
app.use(async (context, next) => { | |
if (context.request.method === "GET") { | |
context.response.headers.set("access-control-allow-origin", "*"); | |
try { | |
await context.send({ root: STATIC_ROOT }); | |
} catch { | |
return next(); | |
} | |
const url = new URL(context.request.url); | |
if (extname(url.pathname) === ".js") { | |
const packagePathUri = `file://${STATIC_ROOT}`; | |
const graph = await createGraph(`${packagePathUri}${url.pathname}`); | |
const { modules } = graph.toJSON(); | |
const response = []; | |
for (const { specifier } of modules) { | |
const path = specifier.replace(packagePathUri, ""); | |
if (path !== url.pathname) { | |
response.push(`<${url.origin}${path}>; rel="modulepreload"`); | |
} | |
} | |
if (response.length > 0) { | |
context.response.headers.set("link", response.join(", ")); | |
} | |
} | |
} | |
}); | |
app.listen({ port: 8000 }); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment