Tree shaking (hay “rung cây”) là một thuật ngữ trong phát triển web dùng để chỉ quá trình loại bỏ mã nguồn JavaScript không được sử dụng (dead code) khỏi bundle cuối cùng. Kỹ thuật này giúp giảm kích thước file, tăng tốc độ tải trang và cải thiện hiệu suất ứng dụng. Tree shaking hoạt động dựa trên cấu trúc ES modules (import/export tĩnh), cho phép các bundler như Webpack, Rollup hoặc esbuild phân tích và loại bỏ các export không dùng đến. Khái niệm này lần đầu được giới thiệu bởi Rollup.js, sau đó được các công cụ đóng gói khác áp dụng rộng rãi.
Tree Shaking Hoạt Động Như Thế Nào?

Tree shaking không phải là một tính năng “thông minh” tự động mà dựa vào cấu trúc tĩnh của ES modules. Không giống như CommonJS (require) có thể import động, ES modules yêu cầu khai báo import và export ở cấp độ tệp, giúp bundler xác định chính xác mã nào được dùng, mã nào không.
Cơ Chế Phân Tích Tĩnh (Static Analysis)
Bundler quét toàn bộ cây phụ thuộc từ điểm đầu vào. Mỗi module được kiểm tra: các export nào được import ở module khác, các biến, hàm nào thực sự được gọi. Những export không có bất kỳ tham chiếu nào sẽ được đánh dấu là dead code.
Đánh Dấu Export Không Dùng (Unused Harmony Export)
Webpack sử dụng plugin terser-webpack-plugin (hoặc các minifier khác) để thực hiện bước loại bỏ cuối cùng. Kết quả là các khai báo không dùng sẽ bị xoá khỏi bundle, chỉ giữ lại những phần cần thiết.
Ví Dụ Minh Hoạ Cụ Thể
Giả sử thư viện utils.js export 3 hàm: sum, multiply, divide. Trong app.js chỉ import sum. Sau khi tree shaking, bundle cuối chỉ chứa hàm sum, không có multiply và divide.
// utils.js
export function sum(a, b) { return a + b; }
export function multiply(a, b) { return a b; }
export function divide(a, b) { return a / b; } // app.js
import { sum } from './utils';
console.log(sum(2, 3));
Lợi Ích Của Tree Shaking Đối Với Hiệu Suất Web
- Giảm kích thước bundle: Loại bỏ dead code giúp file JS nhẹ hơn, đặc biệt quan trọng với các thư viện lớn như lodash, moment.js.
- Tốc độ tải trang nhanh hơn: Bundle nhỏ hơn đồng nghĩa với thời gian tải xuống ít hơn, nhất là trên mạng di động hoặc kết nối chậm.
- Cải thiện thời gian parse và compile: Trình duyệt phải phân tích và biên dịch ít mã hơn, giúp trang tương tác nhanh hơn (Faster Time to Interactive).
- Giảm dung lượng băng thông: Tiết kiệm chi phí hosting và cải thiện trải nghiệm người dùng ở những khu vực có giới hạn dữ liệu.
- Tối ưu hoá cho mobile: Thiết bị di động có tài nguyên hạn chế; tree shaking giúp giảm áp lực lên CPU và RAM.
- Webpack: Đặt mode: ‘production’, bật sideEffects: false hoặc liệt kê các file có side effect trong package.json.
- Rollup: Hỗ trợ tree shaking mặc định, cần plugin như @rollup/plugin-node-resolve.
- esbuild: Có sẵn tree shaking khi set minify: true.
- Vite: Dùng Rollup phía sau, tự động bật chế độ production.
So Sánh Tree Shaking Với Các Kỹ Thuật Tối Ưu Bundle Khác

| Kỹ thuật | Mục tiêu | Cách hoạt động | Tree Shaking khác gì? |
|---|---|---|---|
| Minification | Nén mã, xoá khoảng trắng, đổi tên biến | Terser, UglifyJS | Chỉ làm mã nhỏ hơn, không loại bỏ logic không dùng |
| Code Splitting | Chia bundle thành nhiều phần nhỏ tải theo nhu cầu | Dynamic import, React.lazy | Tree shaking loại bỏ mã, code splitting chia mã |
| Dead Code Elimination | Loại bỏ mã không bao giờ chạy | DCE trong trình biên dịch | Tree shaking là một dạng DCE trong bundle JS |
Điều Kiện Để Tree Shaking Hoạt Động Hiệu Quả
Sử Dụng ES Modules (import/export)
CommonJS với require() không hỗ trợ phân tích tĩnh vì có thể import theo điều kiện. Bundle cần cấu hình để chỉ dùng ES modules. Nếu thư viện bên thứ ba xuất bản cả hai định dạng, ưu tiên phiên bản ES module (field “module” trong package.json).
Cấu Hình Bundler Chính Xác
Khai Báo sideEffects Trong package.json
Bundler cần biết file nào có tác dụng phụ (side effect) như import CSS, polyfill. Nếu toàn bộ dự án không có side effect, đặt “sideEffects”: false. Nếu có, liệt kê cụ thể:
{ "name": "my-library", "sideEffects": [ "./src/polyfill.js", ".css" ]
}
Thực Hành Tree Shaking Với Webpack

Cấu Hình Cơ Bản
Trong webpack.config.js, đảm bảo mode là ‘production’ vì tree shaking chỉ hoạt động ở chế độ này. Sử dụng module.rules với test: /.m?js$/ và exclude: /node_modules/.
Tối Ưu Thư Viện Bên Thứ Ba
Với lodash, thay vì import toàn bộ, chỉ import hàm cần: import debounce from ‘lodash/debounce’. Hoặc dùng lodash-es phiên bản ES module hỗ trợ tree shaking. Tương tự, moment.js có thể thay bằng date-fns hoặc dayjs nhỏ gọn hơn.
Kiểm Tra Kết Quả Tree Shaking
Dùng Webpack Bundle Analyzer để xem bundle có còn mã chết không. Công cụ này hiển thị thành phần trong bundle dưới dạng biểu đồ, giúp phát hiện các module không cần thiết.
Hạn Chế Và Những Điều Cần Lưu Ý
- Side effects: Một số import có tác dụng phụ (ví dụ: import ‘core-js’) không thể bị loại bỏ dù không dùng trực tiếp. Cần khai báo đúng sideEffects.
- Dynamic import: Tree shaking không hoạt động với các import động qua đường dẫn biến.
- Thư viện không hỗ trợ ES modules: Một số thư viện cũ chỉ xuất bản CommonJS, không thể tree shake. Cần tìm bản thay thế hoặc wrap.
- Object destructuring: Import { a, b } from ‘lib’ có thể không được tối ưu nếu thư viện dùng default export hoặc có cấu trúc phức tạp.
- Export tái xuất (Re-export): Nếu một module re-export tất cả từ module khác, có thể gây khó khăn cho bundler. Nên re-export chọn lọc.
Sai Lầm Thường Gặp Khi Áp Dụng Tree Shaking
- Quên khai báo sideEffects trong package.json: Dẫn đến bundler loại bỏ nhầm các file cần thiết như CSS, polyfill.
- Import toàn bộ thay vì import chọn lọc: Ví dụ import * as _ from ‘lodash’ thay vì import { debounce } from ‘lodash-es’.
- Để chế độ development: Webpack chỉ thực hiện tree shaking ở production mode. Lưu ý khi deploy.
- Sử dụng transpiler không tương thích: Babel có thể chuyển đổi ES modules thành CommonJS nếu không cấu hình đúng. Thêm “@babel/preset-env” với modules: false để giữ nguyên ES module.
- Không kiểm tra bundle output: Nhiều dev nghĩ rằng tree shaking tự động xử lý mọi thứ, nhưng cần verify bằng phân tích thực tế.
Tree Shaking Trong Các Framework Frontend
React
Create React App (CRA) đã tích hợp Webpack với tree shaking. Khi import component từ thư viện, chỉ phần dùng mới được bundle. Cần tránh import kiểu import ‘antd/dist/antd.css’ toàn bộ, thay vào đó dùng import CSS component riêng.
Vue.js
Vue CLI cũng hỗ trợ tree shaking trong production. Với Vue 3, Composition API và các helper không dùng sẽ tự động bị loại bỏ nhờ cấu trúc ES module.
Angular
Angular CLI sử dụng Webpack và Tree Shaking có sẵn với –prod flag. Tuy nhiên do Angular dùng TypeScript và decorators, quá trình này phức tạp hơn, cần Ivy compiler để tối ưu.
Lưu Ý Quan Trọng Khi Tối Ưu Bundle Bằng Tree Shaking
- Luôn kiểm tra bundle ở chế độ production trước khi deploy.
- Sử dụng các công cụ phân tích như webpack-bundle-analyzer, Rollup Plugin Visualizer.
- Ưu tiên các thư viện nhỏ, hiện đại hỗ trợ ES modules (lodash-es, date-fns, immer, zustand thay vì Redux cũ).
- Cấu hình Babel để giữ nguyên ES modules: “modules”: false trong presets.
- Với monorepo hoặc workspace, đảm bảo sideEffects được khai báo ở cấp package.
- Đối với thư viện tự phát triển, viết code theo dạng ES module và xuất bản cả định dạng ESM lẫn CJS nhưng luôn ưu tiên ESM.
Câu Hỏi Thường Gặp Về Tree Shaking
Tree shaking có hoạt động với CSS không?
Tree shaking nguyên bản chỉ áp dụng cho JavaScript. Với CSS, có các công cụ như PurgeCSS để loại bỏ class không dùng, nhưng đây là kỹ thuật khác (dead CSS elimination). Một số bundler có plugin kết hợp cả hai.
Tại sao tree shaking không loại bỏ được hết dead code?
Nguyên nhân thường do side effects không được khai báo đúng, module dùng CommonJS, hoặc có mã gây ảnh hưởng phụ (ví dụ: thêm prototype vào global). Cần kiểm tra từng nguyên nhân.
Có nên luôn đặt “sideEffects”: false cho mọi package không?
Không. Nếu package có import các file CSS, polyfill, hoặc thay đổi global scope, việc đặt false sẽ làm mất các chức năng đó. Chỉ đặt false khi chắc chắn không có side effect.
Webpack tree shaking có giống Rollup không?
Giống về nguyên tắc, nhưng Rollup được đánh giá tốt hơn trong việc tree shake các thư viện nhờ cơ chế phân tích tĩnh mạnh mẽ. Webpack phụ thuộc nhiều vào plugin terser để loại bỏ cuối cùng.
Làm cách nào để biết tree shaking đang hoạt động?
Chạy lệnh build production, sau đó dùng Bundle Analyzer hoặc kiểm tra file đầu ra trong thư mục dist. Nếu thấy các hàm không import nhưng vẫn nằm trong bundle, tree shaking chưa hiệu quả.
Kết Luận
Tree shaking là kỹ thuật không thể thiếu trong phát triển web hiện đại, giúp tối ưu bundle JavaScript bằng cách loại bỏ mã không dùng. Để áp dụng hiệu quả, cần hiểu rõ cơ chế ES modules, cấu hình đúng bundler và thư viện, đồng thời kiểm tra thường xuyên bằng công cụ phân tích. Kết hợp tree shaking với code splitting và minification sẽ mang lại hiệu suất tối đa cho ứng dụng. Đầu tư thời gian vào việc tối ưu bundle không chỉ cải thiện trải nghiệm người dùng mà còn giảm chi phí băng thông và tăng điểm Lighthouse, Core Web Vitals.
- WordPress Email Sau Đổi Domain Bị Lỗi: Nguyên Nhân Và Cách Khắc Phục Toàn Diện
- Database WordPress là gì? Hướng dẫn toàn diện từ A-Z cho người mới bắt đầu
- Rank Tracker Keywords Là Gì? Bí Mật Đằng Sau Công Cụ Theo Dõi Thứ Hạng Từ Khóa Chuyên Nghiệp
- Average Position trong GSC là gì? Giải mã chỉ số vị trí trung bình và cách tối ưu hiệu quả
- SEO Metrics là gì trong Ahrefs? Bí kíp đọc vị mọi chỉ số để làm chủ SEO















