How Baidu’s New Mini‑Program Compiler Boosted Build Speed by Up to 7×
Baidu’s mini‑program compiler was completely rebuilt with a self‑designed architecture, multi‑threading, full‑process caching and sourcemap optimizations, delivering 2‑7× faster builds, lower memory usage and smaller output while keeping compatibility with the old system.
Introduction
The mini‑program compiler in Baidu Developer Tools converts mini‑program source code into runtime code. The legacy compiler, based on Webpack 4, suffered from slow builds and high memory consumption, prompting a large‑scale refactor that introduced a self‑built architecture, multi‑threading, code caching and sourcemap improvements.
Framework Selection
Performance was identified as the primary pain point. The new compiler’s design goals were:
Much faster full‑build speed, eliminating ineffective build steps in the old Webpack‑based flow.
Full caching to accelerate first‑time and incremental builds.
Real‑time compilation to reduce dev‑server start‑up and re‑compile time.
Multi‑threaded compilation and page hot‑reload support.
Optimized output structure to shrink bundle size.
Survey of Mainstream Build Tools
We examined common front‑end bundlers to inform the new design:
Webpack – Feature‑rich and extensible but complex to configure, slow builds, difficult for custom extensions.
Parcel – Zero‑config, fast builds, built‑in multi‑threading and full caching via LMDB, but smaller ecosystem and limited customisation.
Vite – Simple configuration, on‑demand compilation, fast dev start‑up, but separate dev and production pipelines.
Other mini‑program platforms were also reviewed: WeChat uses Gulp + C++ modules, Alipay builds on Webpack with esbuild acceleration, and Douyin employs a self‑built compiler.
New Compiler Architecture
The redesigned compiler consists of four core modules:
CompileEntry – Entry point handling CLI, dev‑server communication and command invocation.
CompileManager – Manages dependency downloading, resource management and coordination of multiple Compilers.
Compiler – Transforms project source into runtime code; a project may contain several Compiler instances.
Processor – Performs individual transformation tasks such as code conversion and bundling.
The overall workflow mirrors Parcel’s pipeline, with a
illustrating the control flow.
Compiler Details
Full‑process cache saves over 90% of re‑build time.
On‑demand compilation for single‑page builds during development.
Multi‑threaded Babel and SWC transforms provide 2‑7× speedup for full builds.
New sourcemap protocol removes unnecessary parsing, drastically cutting bundle time.
JS, CSS and Swan template compilation all benefit from cache‑aware processing.
Preview builds use esbuild for fast compression; release builds use terser with sourcemap preservation.
Processor Details
Processors guarantee deterministic output when inputs are identical, storing both input parameters and results as JSON for cache lookup. Each Processor receives a uri (e.g., js:app.js) that uniquely identifies the build unit, and a contextFreeData object containing immutable configuration such as app.json values.
Processor types include:
JS Processor – Transforms ES6 to ES5 (the most time‑consuming step).
Swan Processor – Converts Swan template code to view‑layer JS.
CSS Processor – Uses PostCSS for unit conversion and dependency collection.
Bundle Processor – Merges transformed assets according to a custom bundling algorithm.
The processing pipeline follows a transform → bundle sequence, allowing JS, CSS and Swan bundles to run in parallel, unlike Webpack’s single graph.
Multi‑Core Compilation Optimization
Two multi‑threading strategies were evaluated:
Processor‑level scheduling (complex communication, limited gain – ~10‑15% improvement).
JS‑only multi‑threaded transform (minimal communication, higher gain).
We adopted strategy 2. Using jest‑worker with Babel yields >1× speedup on four threads; using SWC on four threads yields >4× speedup.
SWC Optimization
Two custom SWC plugins were created: @swanide/swc-require-rename – Extracts module paths from require/import/export statements for dependency analysis. @swanide/swc-web-debug – Instruments code to enable breakpoint debugging on real devices.
SWC delivers large performance gains but introduces challenges:
Memory leaks during prolonged dev sessions require manual restarts.
Limited API surface compared to Babel, making some transformations difficult.
Rust‑based plugins must be rebuilt for each @swc/core version, complicating deployment.
When SWC cannot handle a case, the pipeline falls back to Babel.
Code Compression and Runtime Cache
Three compressors were benchmarked:
terser – Highest compression, slowest.
swc – Fast, but limited mangling.
esbuild – Fastest (10× faster than terser), decent mangling.
We chose esbuild for preview builds (no sourcemap needed) and terser for release builds (with sourcemap). Runtime caching stores intermediate Processor results and compressed code in memory, cutting re‑build time dramatically and reducing memory usage by 40‑60% compared with the old Webpack‑based compiler.
Swan Template Processing Optimization
The legacy Swan loader inlined <template> tags and filter functions, inflating bundle size. The new compiler corrects import scopes, emits require calls for templates and filters, and performs deduplication during bundling, shrinking output by roughly 30% for Taro‑generated projects.
Processing results for a Swan file include component modules, template modules, filter functions, and transformed intermediate code.
Sourcemap Optimization
Both dev and release stages need sourcemaps for debugging. Traditional Webpack merges multiple sourcemap files, which is time‑consuming. By adopting the index‑map protocol, the new compiler generates an offset map and concatenates content, fixing the total sourcemap generation time to under 3 seconds regardless of project size.
Future Work
The rollout follows three phases:
Co‑existence of old and new compilers – dev/preview use the new compiler, release uses the old one.
Internal pipelines switch entirely to the new compiler for preview and release.
Full migration of the developer tool to the new compiler.
Remaining enhancements include hot‑module replacement (HMR), tree‑shaking for ES6 modules, and scope‑hoisting. Further bundle‑level optimisations are planned in collaboration with the runtime framework.
Conclusion
The self‑built compiler replaces the Webpack‑based predecessor, delivering 2‑7× faster builds, lower memory consumption and smaller bundles. Techniques such as multi‑threaded SWC transforms, esbuild compression and index‑map sourcemap generation are applicable to other front‑end build systems, offering broad performance benefits.
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.
