How Taro H5 Cut Bundle Size by 80% with Dead Code Elimination
This article explains how the Taro multi‑platform framework reduced its H5 bundle from over 450 KB to about 96 KB by applying dead code elimination, configuring sideEffects, converting core packages to ES modules, and using a custom Babel plugin to transform default imports into named imports.
Background
Taro is a multi‑platform development framework that has supported compiling to H5 since its inception. A typical Taro H5 project bundles the core dependencies @tarojs/components and @tarojs/taro-h5, which together exceed 400 KB on the first screen. Adding UI libraries such as Taro‑UI further inflates the payload.
Problem
Most of the bundled code is never used at runtime because a Taro H5 app does not need every component or API. Packing all dependencies without pruning leads to unnecessary payload size and hampers performance.
Solution Overview
The team applied dead‑code elimination (tree shaking) to remove unused modules and code, restructured the core packages as ES modules, and introduced a Babel plugin that rewrites default imports into named imports, enabling webpack to drop unused API code.
Effect
Using webpack-bundle-analyzer on a fresh project, the original bundle was 455 KB. After the optimizations, the bundle shrank to roughly 96 KB – about one‑fifth of the original size.
Dead Code Elimination Basics
Tree shaking, popularized by Rollup, removes code that does not affect the program’s output. Webpack performs static analysis to build a dependency graph, marks modules without side effects, and eliminates them.
Tree shaking is a form of dead code elimination. The term was popularized by Rollup, but the concept of dead code elimination has existed for some time. – Reduce JavaScript Payloads with Tree Shaking, Jeremy Wagner
Removing Unused Modules
Ensure the package.json of an npm module contains a correctly configured sideEffects field.
Use ES6 module syntax; set modules to false in babel-preset-env so that webpack handles module resolution.
Build in webpack’s production mode.
Webpack’s SideEffectsFlagPlugin tags side‑effect‑free modules with sideEffectFree. The ModuleConcatenationPlugin then excludes those modules from the final bundle. After module‑level pruning, Terser removes unused code at the file level.
Removing Unused Code
CommonJS modules ( require / module.exports) make static analysis difficult, so unused functions often remain in the bundle. Switching to ES6 import / export makes dependencies static, allowing webpack to drop code that is never imported.
// utils.js
export function add(a, b) { return a + b; }
export function minus(a, b) { return a - b; }
// index.js
import { add } from './utils.js';
add(1, 2);Component Library ES‑Moduleization
Previously, @tarojs/components was built into a UMD bundle ( dist/index.js) of 462 KB, which could not be tree‑shaken. The source itself uses ESM, so configuring webpack to resolve the source directly enables built‑in tree shaking. The same approach was applied to @tarojs/taro-h5, reducing its bundle from 262 KB to a minimal size after side‑effects marking and entry‑point adjustments.
Transforming Default Imports to Named Imports
Taro’s API was originally accessed via a default import ( import Taro from '@tarojs/taro-h5') and property access (e.g., Taro.setStorage()), preventing tree shaking. A custom Babel plugin babel-plugin-transform-taroapi rewrites specified API calls to named imports, preserving only the used APIs.
// Babel config snippet
babel: {
preset: ['babel-preset-env'],
plugins: [
['babel-plugin-transform-taroapi', {
packageName: '@tarojs/taro-h5',
apis: new Set(['navigateTo', 'navigateBack' /* ... */])
}]
]
}After transformation, code changes from:
// before
import Taro from '@tarojs/taro-h5';
Taro.setStorage();
Taro['getStorage']();
// after
import Taro, { setStorage as _setStorage, getStorage as _getStorage } from '@tarojs/taro-h5';
Taro.initPxTransform({});
_setStorage();
_getStorage();Future Work
Planned improvements include adding high‑demand APIs such as switchTab, onPageScroll, onPullDownRefresh, refining page‑transition animations, and stabilizing multi‑page mode.
Repository: https://github.com/NervJS/taro
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.
Aotu Lab
Aotu Lab, founded in October 2015, is a front-end engineering team serving multi-platform products. The articles in this public account are intended to share and discuss technology, reflecting only the personal views of Aotu Lab members and not the official stance of JD.com Technology.
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.
