Tree Shaking — ilovani yig'ish bosqichida foydalanilmayotgan kodni olib tashlash mexanizmi (dead code elimination). Tree Shaking ES-modullarining statik tuzilishini tahlil qiladi va hech qayerda import qilinmagan eksport qilingan funksiyalar, sinflar va o'zgaruvchilarni chiqarib tashlaydi. Webpack Documentation ma'lumotlariga ko'ra, Tree Shaking-ni to'g'ri sozlash ilova funksionalligini o'zgartirmasdan bundle hajmini 30–60% kamaytirishi mumkin.
Asosiy
Tree Shaking (daraxtni silkitish) — ilovada foydalanilmaydigan modul va funksiyalar yakuniy bundle-dan chiqarib tashlanadigan kodni optimallashtirish texnikasi. Bu atama 2015-yilda Rollup jamoasi tomonidan kiritilgan va jarayonni metaforik tarzda tasvirlaydi: bog'liqlik daraxti silkitiladi va foydalanilmaydigan shoxlar tushadi. Qo'lda optimallashtirishdan farqli o'laroq, Tree Shaking yig'ish bosqichida avtomatik ravishda amalga oshiriladi.
Tree Shaking faqat ES-modullari (ECMAScript Modules) bilan ishlaydi, bunda bog'liqliklar import va export orqali statik ravishda aniqlanadi. CommonJS (require/module.exports) Tree Shaking-ni qo'llab-quvvatlamaydi, chunki require dinamik ravishda bajariladi — yig'uvchi qaysi funksiyalar haqiqatda ishlatilishini oldindan aniqlay olmaydi. Zamonaviy kutubxonalar (Lodash, Moment.js, RxJS) Tree Shaking-ni qo'llab-quvvatlash uchun ES versiyalarini chiqaradi.
Rollup — 2015-yilda Tree Shaking-ni joriy qilgan birinchi yig'uvchi. Webpack-dan farqli o'laroq, Rollup boshidanoq ES-modullari uchun mo'ljallangan va o'lik kodni yanada agressiv olib tashlashni amalga oshiradi. Rollup nafaqat alohida eksportlarni, balki butun modullarni tahlil qiladi: agar modulda yon ta'sirlar bo'lmasa va hech qanday eksport ishlatilmasa, Rollup butun modulni bundle-dan chiqarib tashlaydi.
Rollup, ayniqsa, har bir kilobayt muhim bo'lgan kutubxonalar va SDK-lar uchun samarali. Vue.js freymvorki production versiyasini yig'ish uchun Rollup-dan foydalanadi. React 2020-yilda Rollup-ga o'tgan. Ilovalar uchun ko'pincha Webpack ishlatiladi (boy plagin ekosistemasi tufayli — Hot Module Replacement, code splitting, CSS modules), lekin kutubxonalarni yig'ishda maksimal Tree Shaking uchun Rollup sanoat standarti bo'lib qolmoqda.
Tejamkorlik Tree Shaking-dan loyiha arxitekturasiga kuchli bog'liq. React ilovasida Ant Design kutubxonasi bilan Tree Shaking UI-komponentlar kodining 70% gacha olib tashlashi mumkin. Barcha importlar aniq va nuqtali bo'lgan loyihada tejamkorlik 5–15% ni tashkil qiladi. Webpack tadqiqotlariga ko'ra o'rtacha tejamkorlik bundle hajmining 30–40% ni tashkil qiladi.
| O'lik kod turi | Misol | Tree Shaking tomonidan aniqlanishi |
|---|---|---|
| Foydalanilmayotgan eksport | export function unusedHelper() | Ha |
| Foydalanilmayotgan import | import { unused } from "lib" | Ha |
| Shartning o'lik shoxi | if (false) { ... } | Yo'q (minifikator tomonidan olib tashlanadi) |
| DCE dan keyin chaqirilmagan funksiya | function a(){} a() a chaqirilmaganda | Qisman |
Tree Shaking mexanizmi yig'uvchi loyihadagi barcha import/export-lardan quradigan bog'liqlik grafigiga (dependency graph) asoslanadi. Birinchi bosqichda yig'uvchi kirish nuqtasidan (entry point) barcha fayllarni aylanib chiqib, modullar daraxtini yig'adi. Ikkinchi bosqichda har bir moduldan qaysi eksportlar boshqa modullarda haqiqatda import qilinishi tahlil qilinadi.
Har bir modul uchun Webpack yoki Rollup eksportlarni ishlatilgan yoki ishlatilmagan deb belgilaydi. Ishlatilmagan eksportlar bundle-dan chiqarib tashlanadi. Biroq modulning o'zi bundle-da qoladi, agar uning kamida bitta eksporti ishlatilsa. Modulni butunlay chiqarib tashlash faqat sideEffects flagi orqali yoki modulda hech qanday yon ta'sirlar bo'lmasa mumkin.
// utils.js — funksiyalari bo'lgan modul
export function formatDate(date) {
return date.toISOString().slice(0, 10);
}
export function formatCurrency(amount) {
return "$" + amount.toFixed(2);
}
export function slugify(text) {
return text.toLowerCase().replace(/\s+/g, "-");
}// app.js — kirish nuqtasi
import { formatDate } from "./utils";
const today = formatDate(new Date());
console.log(today);// Tree Shaking-dan keyin — bundle-da faqat formatDate
function formatDate(date) {
return date.toISOString().slice(0, 10);
}
const today = formatDate(new Date());
console.log(today);Tree Shaking formatCurrency va slugify-ni yakuniy bundle-dan chiqarib tashladi, chunki ular app.js-da import qilinmaydi. utils.js modulining hajmi 3 funksiyadan 1 ga kamaydi. Agar utils.js tarkibida side effects bo'lsa (masalan, global ishga tushirish), Tree Shaking hatto ishlatilmagan eksportlarni ham olib tashlay olmaydi.
Webpack production rejimida TerserPlugin plagini orqali Tree Shaking uchun o'rnatilgan qo'llab-quvvatlashni o'z ichiga oladi. Tree Shaking-ni yoqish uchun ikkita shart yetarli: mode production (mode: "production") qilib o'rnatilgan va modullar ES sintaksisidan (import/export) foydalanadi. Webpack avtomatik ravishda ishlatilmagan eksportlarni belgilab, ularni olib tashlash uchun Terser-ga uzatadi.
Qo'shimcha sozlash usedExports: true optimization.webpack.config.js da modul ichidagi eksportlardan foydalanishning batafsil tahlilini yoqadi. Bu parametr qaysi eksportlar haqiqatda ishlatilgan (used) va qaysilari faqat eksport qilingan (provided)ligini aniqlaydi. usedExports va Terser kombinatsiyasi o'lik kodni olib tashlashda maksimal samaradorlikni beradi.
// webpack.config.js — Tree Shaking sozlamasi
module.exports = {
mode: "production",
entry: "./src/app.js",
output: {
filename: "bundle.js",
},
optimization: {
usedExports: true,
minimize: true,
concatenateModules: true,
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules\/(?!(my-lib)\/).*/,
use: {
loader: "babel-loader",
options: {
presets: [
["@babel/preset-env", { modules: false }],
],
},
},
},
],
},
};Asosiy parametr — @babel/preset-env dagi modules: false. Babel sukut bo'yicha ES-modullarini CommonJS-ga o'tkazadi, bu esa Tree Shaking-ni o'ldiradi. modules: false Babel-ga import/export-ni o'zgartirishni taqiqlaydi, Webpack uchun ES sintaksisini saqlaydi. concatenateModules qo'shimcha ravishda modullarni umumiy ko'rinish sohasida birlashtiradi, IIFE sonini va bundle hajmini kamaytiradi.
Side effects (yon ta'sirlar) — modulni import qilishda uning eksport qilinadigan qiymatlar bilan bog'liq bo'lmagan harakatlari: global stillar (import "./styles.css"), polifilllar (import "core-js/stable"), global o'zgaruvchilarni ishga tushirish yoki Service Worker ro'yxatdan o'tkazish. Agar modulda side effects bo'lsa, yig'uvchi uni bundle-dan xavfsiz olib tashlay olmaydi, hatto hech qanday eksport ishlatilmasa ham.
sideEffects flagi package.json da yig'uvchiga paketdagi qaysi modullarda yon ta'sirlar yo'qligini bildiradi. Barcha modullar toza bo'lgan paket uchun (faqat funksiya eksporti) "sideEffects": false o'rnatilishi kerak. CSS yoki polifillari bo'lgan paketlar uchun — yon ta'sirlari bo'lgan fayllarga yo'llar massivi: "sideEffects": ["*.css"]. Bu flag bo'lmasa, Tree Shaking hatto ishlatilmagan funksiyalarni ham olib tashlamaydi.
Modulda yon ta'sirlar bor-yo'qligini tekshirish uchun savol bering: bu import qiymat eksporti bilan bog'liq bo'lmagan biron-bir harakatni bajaradimi? import "./styles.css" CSS-ni DOM-ga qo'shadi — bu side effect. import { throttle } from "lodash-es" side effect-ga ega emas — u faqat throttle funksiyasini mavjud qiladi. Polifilllar (import "core-js/stable") side effect-ga ega — ular global prototiplarni o'zgartiradi.
O'z modullaringiz uchun tavsiya etiladi: stillar va polifilllarni alohida kirish nuqtalariga chiqarish, toza vositalarni (yon ta'sirsiz funksiyalar) yon ta'sirlari bo'lgan modullardan (ishga tushirish, loglash, Service Worker ro'yxatdan o'tkazish) ajratish. Yuqori darajali loyihaning package.json ida "sideEffects": false faqat barcha modullar toza bo'lganda o'rnatilishi kerak. Agar stillar bo'lsa — "sideEffects": ["*.css"] aniq o'rnatilishi kerak.
{
"name": "my-ui-lib",
"version": "2.1.0",
"sideEffects": [
"*.css",
"polyfills.js"
],
"module": "dist/index.esm.js",
"main": "dist/index.cjs.js"
}"sideEffects": ["*.css", "polyfills.js"] degani: barcha CSS fayllari yon ta'sirlarga ega (ularni olib tashlab bo'lmaydi) va polyfills.js ham. Paketdagi boshqa barcha JS fayllari toza — ularni xavfsiz shake qilish mumkin. module maydoni yig'uvchi Tree Shaking uchun CommonJS versiyasi (main) o'rniga ishlatishi kerak bo'lgan ES versiyasiga yo'lni ko'rsatadi.
React Native Metro Bundler bilan cheklangan Tree Shaking versiyasini qo'llab-quvvatlaydi. Metro Webpack kabi ishlatilgan eksportlarning (usedExports) to'liq statik tahlilini bajarmaydi. Buning o'rniga Metro minifikatsiya bosqichida modullarning ishlatilmagan qismini olib tashlash uchun Terser-ga tayanadi. Bunday yondashuvning samaradorligi Webpack-dagi to'liq Tree Shaking-dan past.
Maksimal optimallashtirish uchun React Native loyihalarida tavsiya etiladi: ES-modullari bo'lgan kutubxonalardan foydalanish (package.json da module maydoni), debug kodini olib tashlash uchun babel-plugin-transform-remove-console plaginlarini ulash va Metro transformer.minifierConfig-ni Terser uchun sozlash. Qo'shimcha ravishda Ram Bundle (bundle-ni modullarga bo'lish) ishlatilmagan ekranlarning yuklanishini kamaytiradi.
Tez-tez beriladigan savollar
CommonJS (require/module.exports) statik tahlilni qo'llab-quvvatlamaydi — require shartlar va funksiyalar ichida dinamik ravishda chaqirilishi mumkin. Yig'uvchi modulning qaysi qismlari haqiqatda ishlatilishini aniqlay olmaydi. Faqat statik import/export ga ega ES-modullari Tree Shaking-ga imkon beradi.
TypeScript Tree Shaking bilan to'liq mos keladi, agar tsconfig.json ES-modullariga sozlangan bo'lsa: "module": "esnext". TypeScript kompilyatori import/export-ni CommonJS-ga o'zgartirmasdan saqlashi kerak. @babel/preset-typescript va modules: false bo'lgan Babel ham ES-modullarini Webpack-ga to'g'ri uzatadi.
Webpack Bundle Analyzer — bundle tarkibini interaktiv diagramma shaklida vizuallashtiruvchi plagin. Agar kutubxona bundle-da mavjud bo'lsa, lekin uning funksiyalari ishlatilmasa, Tree Shaking ishlamagan. Shuningdek, chiqish faylini tahlil qilish mumkin: grep orqali bundle matnida ishlatilmagan eksportni topish.
Lodash v4 CommonJS paketi sifatida tarqatiladi. Tree Shaking uchun lodash-es — kutubxonaning ES versiyasidan foydalanish kerak. import throttle from "lodash/throttle" ni import { throttle } from "lodash-es" bilan almashtiring va Webpack-da resolve.alias-ni lodash-ni lodash-es bilan almashtirish uchun sozlang.
Tree Shaking yig'ish vaqtini biroz oshiradi (5–15%), chunki bog'liqlik grafigini tahlil qilish va ishlatilgan eksportlarni belgilash bosqichini qo'shadi. Development rejimida Tree Shaking odatda tezlik uchun o'chirilgan. Production-da qo'shimcha vaqt bundle hajmining sezilarli darajada kamayishi bilan oqlanadi.
Xulosa
Biz kalit topshirig'i bilan mobil ilovani ishlab chiqamiz
IT Sectr 2017-yildan beri startaplar va korxonalar uchun iOS va Android ilovalarini yaratadi. Biz sizga maslahat beramiz va eng yaxshi yechimni taklif qilamiz.