Tree Shaking: bu nədir, ölü kodun silinmə mexanizmi və alətlər

Müəllif: IT Sectr Dərc olunub: 2026-05-18 Oxuma vaxtı: 8 dəq

Tree Shaking — tətbiqin qurulma mərhələsində istifadə olunmayan kodun silinmə mexanizmi (dead code elimination). Tree Shaking ES-modullarının statik strukturunu təhlil edir və heç bir yerdə idxal edilməyən ixrac edilmiş funksiyaları, sinifləri və dəyişənləri xaric edir. Webpack Documentation məlumatlarına görə, Tree Shaking-in düzgün konfiqurasiyası tətbiqin funksionallığını dəyişmədən bunt ölçüsünü 30–60% azalda bilər.

Əsas məqamlar

  • Tree Shaking — import/export statik təhlili əsasında ES-modullarından istifadə olunmayan ixracların silinməsi
  • ES-modulları (import/export) — Tree Shaking-i dəstəkləyən yeganə format; CommonJS dəstəklənmir
  • Webpack və Rollup — plaginlər vasitəsilə Tree Shaking dəstəyi olan əsas qurucular
  • Side effects — modullardakı yan təsirlər Tree Shaking-i bloklayır; package.json-da sideEffects: false flagı problemi həll edir
  • Used exports — dəqiq ölü kod silinməsi üçün Webpack-in production rejimində ixracların istifadə təhlili

Tree Shaking nədir?

Tree Shaking (ağacın silkələnməsi) — tətbiqdə istifadə olunmayan modul və funksiyaların yekun buntdan xaric edildiyi kod optimallaşdırma texnikası. Termin 2015-ci ildə Rollup komandası tərəfindən təqdim edilmişdir və prosesi metaforik olaraq təsvir edir: asılılıq ağacı silkələnir, istifadə olunmayan budaqlar düşür. Əl ilə optimallaşdırmadan fərqli olaraq, Tree Shaking qurulma mərhələsində avtomatik olaraq həyata keçirilir.

Tree Shaking yalnız ES-modulları (ECMAScript Modules) ilə işləyir, burada asılılıqlar import və export vasitəsilə statik olaraq müəyyən edilir. CommonJS (require/module.exports) Tree Shaking-i dəstəkləmir, çünki require dinamik olaraq işləyir — qurucu hansı funksiyaların həqiqətən istifadə edildiyini əvvəlcədən müəyyən edə bilmir. Müasir kitabxanalar (Lodash, Moment.js, RxJS) Tree Shaking dəstəyi üçün ES versiyalarını buraxır.

Rollup: Tree Shaking-in pioneri

Rollup — 2015-ci ildə Tree Shaking-i tətbiq edən ilk qurucu. Webpack-dən fərqli olaraq, Rollup əvvəldən ES-modulları üçün nəzərdə tutulmuşdur və ölü kodun daha aqressiv silinməsini həyata keçirir. Rollup təkcə ayrı-ayrı ixracları deyil, bütün modulları təhlil edir: əgər modulun yan təsirləri yoxdursa və heç bir ixrac istifadə edilmirsə, Rollup bütün modulu buntdan xaric edir.

Rollup xüsusilə hər kilobaytın əhəmiyyətli olduğu kitabxana və SDK-lar üçün effektivdir. Vue.js çərçivəsi production versiyasını qurmaq üçün Rollup-dan istifadə edir. React 2020-ci ildə Rollup-a keçmişdir. Tətbiqlər üçün daha çox Webpack istifadə olunur (zəngin plagin ekosisteminə görə — Hot Module Replacement, code splitting, CSS modules), lakin kitabxanaların qurulmasında maksimum Tree Shaking üçün Rollup sənaye standartı olaraq qalır.

Qənaət Tree Shaking-dən layihənin arxitekturasından güclü şəkildə asılıdır. React tətbiqində Ant Design kitabxanası ilə Tree Shaking UI komponentlərinin kodunun 70%-ə qədərini silə bilər. Bütün idxalların spesifik və dəqiq olduğu layihədə qənaət 5–15% təşkil edəcək. Webpack tədqiqatlarına görə orta qənaət bunt ölçüsünün 30–40%-ni təşkil edir.

Ölü kod nədir

Ölü kodun növüNümunəTree Shaking tərəfindən aşkarlanma
İstifadə olunmayan ixracexport function unusedHelper()Bəli
İstifadə olunmayan idxalimport { unused } from "lib"Bəli
Şərtin ölü budağıif (false) { ... }Xeyr (minifikator tərəfindən silinir)
DCE-dən sonra çağırılmayan funksiyafunction a(){} a() a çağırılmadıqdaQismən

Tree Shaking necə işləyir: modulların statik təhlili

Tree Shaking mexanizmi qurucunun layihədəki bütün import/export-dan qurduğu asılılıq qrafikinə (dependency graph) əsaslanır. Birinci mərhələdə qurucu giriş nöqtəsindən (entry point) bütün faylları gəzərək modul ağacını toplayır. İkinci mərhələdə hər moduldan hansı ixracların digər modullarda həqiqətən idxal edildiyi təhlil edilir.

Hər modul üçün Webpack və ya Rollup ixracları istifadə olunan və ya istifadə olunmayan kimi qeyd edir. İstifadə olunmayan ixraclar buntdan xaric edilir. Lakin modulun özü buntda qalır, əgər onun ən azı bir ixracı istifadə olunursa. Modulu tamamilə xaric etmək yalnız sideEffects flagı ilə və ya modulda heç bir yan təsir yoxdursa mümkündür.

Nümunə: Tree Shaking-dən əvvəl və sonra

js
// utils.js — funksiyaları olan 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, "-");
}
js
// app.js — giriş nöqtəsi
import { formatDate } from "./utils";

const today = formatDate(new Date());
console.log(today);
js
// Tree Shaking-dən sonra — buntda yalnız formatDate
function formatDate(date) {
  return date.toISOString().slice(0, 10);
}
const today = formatDate(new Date());
console.log(today);

Tree Shaking formatCurrency və slugify-i yekun buntdan xaric etdi, çünki onlar app.js-də idxal edilmir. utils.js modulunun ölçüsü 3 funksiyadan 1-ə düşdü. Əgər utils.js-də side effects varsa (məsələn, qlobal inisializasiya), Tree Shaking hətta istifadə olunmayan ixracları belə silə bilməyəcək.

Webpack-də Tree Shaking: konfiqurasiya və optimallaşdırma

Webpack production rejimində TerserPlugin plagin vasitəsilə Tree Shaking üçün daxili dəstək ehtiva edir. Tree Shaking-i işə salmaq üçün iki şərt kifayətdir: mode production (mode: "production") olaraq təyin edilməli və modullar ES sintaksisindən (import/export) istifadə etməlidir. Webpack avtomatik olaraq istifadə olunmayan ixracları qeyd edir və silinmək üçün Terser-ə ötürür.

Əlavə konfiqurasiya usedExports: true optimization.webpack.config.js-də modul daxilində ixracların istifadəsinin detallı təhlilini aktivləşdirir. Bu seçim hansı ixracların həqiqətən istifadə edildiyini (used) və hansıların yalnız ixrac edildiyini (provided) müəyyən edir. usedExports və Terser kombinasiyası ölü kodun silinməsində maksimum effektivlik verir.

Tree Shaking üçün Webpack konfiqurasiyası

js
// webpack.config.js — Tree Shaking konfiqurasiyası
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 }],
            ],
          },
        },
      },
    ],
  },
};

Əsas parametr — @babel/preset-env-də modules: false. Babel standart olaraq ES-modullarını CommonJS-ə çevirir ki, bu da Tree Shaking-i öldürür. modules: false Babel-ə import/export-u çevirməyi qadağan edir, Webpack üçün ES sintaksisini saxlayır. concatenateModules əlavə olaraq modulları ümumi görünmə sahəsində birləşdirir, IIFE sayını və bunt ölçüsünü azaldır.

Side effects problemi və sideEffects flagı

Side effects (yan təsirlər) — modulun idxal edildikdə ixrac edilən dəyərlərlə əlaqəli olmayan hərəkətləri: qlobal stillər (import "./styles.css"), polifillər (import "core-js/stable"), qlobal dəyişənlərin inisializasiyası və ya Service Worker qeydiyyatı. Əgər modulda side effects varsa, qurucu onu buntdan təhlükəsiz şəkildə silə bilməz, hətta heç bir ixrac istifadə edilməsə belə.

sideEffects flagı package.json-da qurucuya paketdəki hansı modulların yan təsirlərinin olmadığını bildirir. Bütün modulların təmiz olduğu paket üçün (yalnız funksiya ixracı) "sideEffects": false təyin edilməlidir. CSS və ya polifilləri olan paketlər üçün — yan təsirləri olan fayllara yollar massivi: "sideEffects": ["*.css"]. Bu flag olmadan Tree Shaking hətta istifadə olunmayan funksiyaları belə silməyəcək.

Öz kodunuzda side effects-i necə müəyyən etmək olar

Modulda yan təsirlərin olub-olmadığını yoxlamaq üçün sual verin: bu idxal dəyər ixracı ilə əlaqəli olmayan hər hansı bir hərəkət edəcəkmi? import "./styles.css" CSS-i DOM-a əlavə edir — bu side effect-dir. import { throttle } from "lodash-es" side effect-ə malik deyil — o, sadəcə throttle funksiyasını əlçatan edir. Polifillər (import "core-js/stable") side effect-ə malikdir — onlar qlobal prototipləri dəyişdirir.

Öz modullarınız üçün tövsiyə olunur: stilləri və polifilləri ayrı giriş nöqtələrinə çıxarmaq, təmiz alətləri (yan təsirsiz funksiyalar) yan təsirləri olan modullardan (inisializasiya, loglama, Service Worker qeydiyyatı) ayırmaq. Yuxarı səviyyəli layihənin package.json-da "sideEffects": false yalnız bütün modullar təmiz olduqda təyin edilməlidir. Stillər varsa — "sideEffects": ["*.css"] dəqiq təyin edilməlidir.

sideEffects konfiqurasiya nümunəsi

json
{
  "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"] o deməkdir: bütün CSS fayllarının yan təsirləri var (onlar silinə bilməz) və polyfills.js-nin də. Paketdəki bütün digər JS faylları təmizdir — onlar təhlükəsiz şəkildə shake-edilə bilər. module sahəsi qurucunun Tree Shaking üçün CommonJS versiyası (main) əvəzinə istifadə etməli olduğu ES versiyasına yolu göstərir.

React Native və Metro-da Tree Shaking

React Native Metro Bundler ilə məhdud Tree Shaking versiyasını dəstəkləyir. Metro Webpack kimi istifadə olunan ixracların (usedExports) tam statik təhlilini aparmır. Bunun əvəzinə Metro minifikasiya mərhələsində modulların istifadə olunmayan hissəsini silmək üçün Terser-ə etibar edir. Bu yanaşmanın effektivliyi Webpack-də tam Tree Shaking-dən aşağıdır.

Maksimum optimallaşdırma üçün React Native layihələrində tövsiyə olunur: ES modulları olan kitabxanalardan istifadə etmək (package.json-da module sahəsi), debug kodunu silmək üçün babel-plugin-transform-remove-console plaginlərini qoşmaq və Terser üçün Metro transformer.minifierConfig-i konfiqurasiya etmək. Əlavə olaraq Ram Bundle (buntun modullara bölünməsi) istifadə olunmayan ekranların yüklənməsini azaldır.

Tez-tez verilən suallar

Niyə Tree Shaking CommonJS ilə işləmir?

CommonJS (require/module.exports) statik təhlili dəstəkləmir — require şərtlər və funksiyalar daxilində dinamik olaraq çağırıla bilər. Qurucu modulun hansı hissələrinin həqiqətən istifadə edildiyini müəyyən edə bilmir. Yalnız statik import/export olan ES-modulları Tree Shaking-ə imkan verir.

Tree Shaking TypeScript ilə istifadə edilə bilərmi?

TypeScript Tree Shaking ilə tam uyğundur, tsconfig.json-un ES-modullarına konfiqurasiya edilməsi şərtilə: "module": "esnext". TypeScript kompilyatoru import/export-u CommonJS-ə çevirmədən saxlamalıdır. @babel/preset-typescript və modules: false olan Babel də ES-modullarını Webpack-ə düzgün ötürür.

Tree Shaking-in işlədiyini necə yoxlamaq olar?

Webpack Bundle Analyzer — buntun tərkibini interaktiv diaqram şəklində vizuallaşdıran plagin. Əgər kitabxana buntda mövcuddursa, lakin onun funksiyaları istifadə edilmirsə, Tree Shaking işləməyib. Həmçinin çıxış faylını təhlil etmək olar: grep vasitəsilə bunt mətnində istifadə olunmayan ixracı tapmaq.

Niyə Lodash default olaraq tree-shake-edilmir?

Lodash v4 CommonJS paketi kimi yayımlanır. Tree Shaking üçün lodash-es — kitabxananın ES versiyasından istifadə etmək lazımdır. import throttle from "lodash/throttle"-ni import { throttle } from "lodash-es" ilə əvəz edin və Webpack-də resolve.alias-ı lodash-ı lodash-es ilə əvəz etmək üçün konfiqurasiya edin.

Tree Shaking qurulma vaxtına təsir edirmi?

Tree Shaking qurulma vaxtını cüzi artırır (5–15%), çünki asılılıq qrafikinin təhlili və istifadə olunan ixracların qeyd edilməsi mərhələsini əlavə edir. Development rejimində Tree Shaking adətən sürət üçün söndürülür. Production-da əlavə vaxt bunt ölçüsünün əhəmiyyətli dərəcədə azalması ilə əsaslandırılır.

Xülasə

  • Tree Shaking — qurulma mərhələsində istifadə olunmayan ES ixraclarının avtomatik silinməsi, bunt ölçüsünü 30–60% azaldır
  • ES-modulları — statik təhlili dəstəkləyən yeganə format; CommonJS Tree Shaking üçün uyğun deyil
  • Webpack və Rollup production rejimində usedExports və Terser vasitəsilə Tree Shaking təmin edir
  • Side effects modulun silinməsini bloklayır; package.json-da sideEffects: false flagı təmiz kitabxanalar üçün problemi həll edir
  • Babel ES-modullarını CommonJS-ə çevirməmək üçün modules: false ilə konfiqurasiya edilməlidir
  • React Native Metro məhdud Tree Shaking-ə malikdir, minifikasiya mərhələsində Terser-ə etibar edir

Açar təslim mobil tətbiq hazırlayacağıq

IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.

Layihəni müzakirə et

Həm də oxuyun