How We Cut CodeSandbox Sandbox Build Time from 2 Minutes to 1 Second
This article details the background, architecture, and step‑by‑step performance optimizations—including Packager caching, request reduction, Service‑Worker caching, and Webpack‑style externals—that reduced a CodeSandbox sandbox build from around two minutes to roughly one second.
Background
More than a year after the article "Building Your Own Online IDE" introduced a private deployment of CodeSandbox, the internal low‑code platform at NetEase Cloud Music needed a real‑time front‑end build sandbox. The in‑house sandbox suffered from poor flexibility, limited compatibility, and lack of isolation, prompting a switch to the mature, open‑source CodeSandbox.
Sandbox Build Process
CodeSandbox runs a simplified Webpack in the browser, consisting of an online Bundler and a Packager service. The host page embeds a Sandbox component that creates an iframe loading the sandbox page. The component sends a compile command via postMessage to the Bundler, which first fetches npm dependencies from the Packager.
Dependency Pre‑load Phase (NPM Preload)
Because browsers cannot install node_modules, the sandbox fetches a Manifest JSON for each npm package from the Packager. The Manifest contains a map of module URLs, allowing the bundler to resolve imports without a waterfall of HTTP requests.
Example Manifest URL for React 17.0.2:
https://prod-packager-packages.codesandbox.io/v2/packages/react/17.0.2.jsonThe Manifest is merged for all dependencies, so the later compilation phase can look up modules locally.
Compilation Phase (Transpilation)
The bundler parses the entry file, builds an AST, resolves CommonJS dependencies recursively, and produces a dependency graph.
Evaluation Phase
After compilation, the sandbox evaluates the modules in order, again following CommonJS semantics.
Improving Sandbox Build Speed
The author optimized a simple admin app that depends on antd from ~2 minutes to ~1 second by addressing four key areas.
Caching Packager Results – Store the Manifest generated by the Packager so subsequent builds read it from cache instead of re‑packing large packages like antd. First‑time pre‑fetching of common packages further reduces latency, cutting build time to ~70 seconds.
Reducing Per‑Module Requests in the Compilation Phase – Align the entry‑file resolution strategy between the Packager and the sandbox. For packages where the module field points to a non‑existent file or omits an extension, the Packager previously omitted needed files, causing extra CDN requests. The fix involved adjusting the resolver logic (see packages/sandpack-core/src/resolver/utils/pkg-json.ts) and, for packages without a proper entry, manually including required directories (e.g., @babel/runtime) in the Manifest.
Enabling Service‑Worker + CacheStorage – Use SWPrecacheWebpackPlugin to generate a service worker that caches sandbox static assets, Packager Manifest files, and individual module files. The worker checks CacheStorage before fetching from the network, stabilizing build time around 12 seconds.
Implementing Webpack‑style Externals – Skip compilation of large libraries (e.g., antd) by loading their UMD builds via script tags and exposing them on window. The bundler’s require logic is patched (see
packages/sandpack-core/src/transpiled-module/transpiled-module.ts) to return the global object for externalized packages, eliminating unnecessary module traversal. The sandbox configuration adds an externals map and externalResources URLs.
Sample Configuration
{
"externals": {
"react": "React",
"react-dom": "ReactDOM",
"antd": "antd"
},
"externalResources": [
"https://unpkg.com/[email protected]/umd/react.development.js",
"https://unpkg.com/[email protected]/umd/react-dom.development.js",
"https://unpkg.com/[email protected]/dist/antd.min.js",
"https://unpkg.fn.netease.com/[email protected]/dist/antd.css"
]
}After applying all four optimizations, the sandbox builds the sample app in about 1 second, as shown in the GIF below.
Future Plans
The current approach still compiles the entire dependency graph before execution, which will become a bottleneck for larger applications. Inspired by Vite’s on‑demand ES‑module compilation, the author plans to explore a browser‑based Vite sandbox that compiles modules lazily, further reducing build times.
Reference implementations and related code will be published in the next article.
References
Building Your Own Online IDE – https://github.com/mcuking/blog/issues/86
CodeSandbox How It Works? (Part 1) – https://bobi.ink/2019/06/20/codesandbox/
Dependency Packager PR – https://github.com/codesandbox/dependency-packager/pull/38
babel-plugin-import – https://www.npmjs.com/package/babel-plugin-import
Webpack Externals – https://webpack.docschina.org/configuration/externals/
UMD Overview – https://www.cnblogs.com/snandy/archive/2012/03/19/2406596.html
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
