Tree Shaking: mi ez, a holt kód eltávolításának mechanizmusa és eszközök

Szerző: IT Sectr Megjelenés: 2026-05-18 Olvasási idő: 8 perc

Tree Shaking — a nem használt kód eltávolításának mechanizmusa (dead code elimination) az alkalmazás buildelési szakaszában. A Tree Shaking elemzi az ES-modulok statikus szerkezetét és kizárja az exportált függvényeket, osztályokat és változókat, amelyek sehol sincsenek importálva. A Webpack Documentation szerint a Tree Shaking megfelelő konfigurációja 30–60%-kal csökkentheti a bundle méretét anélkül, hogy megváltoztatná az alkalmazás funkcióit.

Főbb pontok

  • Tree Shaking — a nem használt exportok eltávolítása ES-modulokból az import/export statikus elemzése alapján
  • ES-modulok (import/export) — az egyetlen formátum, amely támogatja a Tree Shakinget; a CommonJS nem támogatott
  • Webpack és Rollup — a fő buildelők Tree Shaking támogatással plugineken keresztül
  • Side effects — a modulok mellékhatásai blokkolják a Tree Shakinget; a sideEffects: false jelző a package.json-ben megoldja a problémát
  • Used exports — az exportok használatának elemzése a Webpack production módjában a holt kód pontos eltávolításához

Mi az a Tree Shaking?

Tree Shaking (fa megrázása) — kódoptimalizálási technika, amely során a nem használt modulok és függvények kikerülnek a végső bundle-ből. A kifejezést a Rollup csapat vezette be 2015-ben, és metaforikusan írja le a folyamatot: a függőségi fát megrázzák, és a nem használt ágak lehullanak. A kézi optimalizálással ellentétben a Tree Shaking automatikusan történik a buildelési szakaszban.

A Tree Shaking csak ES-modulokkal (ECMAScript Modules) működik, ahol a függőségek statikusan kerülnek meghatározásra import és export útján. A CommonJS (require/module.exports) nem támogatja a Tree Shakinget, mert a require dinamikusan fut — a buildelő nem tudja előre meghatározni, mely függvényeket használják ténylegesen. A modern könyvtárak (Lodash, Moment.js, RxJS) ES-verziókat adnak ki a Tree Shaking támogatásához.

Rollup: a Tree Shaking úttörője

Rollup — az első buildelő, amely 2015-ben bevezette a Tree Shakinget. A Webpackkal ellentétben a Rollupot kezdettől fogva ES-modulokra tervezték, és agresszívebb holt kód eltávolítást végez. A Rollup nemcsak az egyes exportokat elemzi, hanem a teljes modulokat is: ha egy modulnak nincs mellékhatása és egyetlen export sem használt, a Rollup az egész modult kizárja a bundle-ből.

A Rollup különösen hatékony könyvtárak és SDK-k esetében, ahol minden kilobájt számít. A Vue.js keretrendszer a Rollupot használja a production verzió buildeléséhez. A React 2020-ban váltott Rollupra. Alkalmazásokhoz gyakrabban használják a Webpackot a gazdagabb plugin-ökoszisztéma miatt (Hot Module Replacement, code splitting, CSS modules), de a maximális Tree Shakinghez könyvtárak buildelésekor a Rollup marad az ipari szabvány.

A megtakarítás a Tree Shakingtől erősen függ a projekt architektúrájától. Egy React alkalmazásban az Ant Design könyvtárral a Tree Shaking akár 70%-kal is csökkentheti az UI komponensek kódját. Egy olyan projektben, ahol minden import specifikus és pontos, a megtakarítás 5–15% lesz. Az átlagos megtakarítás a Webpack kutatásai szerint a bundle méretének 30–40%-a.

Mi az a holt kód

Holt kód típusaPéldaFelderítés Tree Shakingkel
Nem használt exportexport function unusedHelper()Igen
Nem használt importimport { unused } from "lib"Igen
Feltétel holt ágaif (false) { ... }Nem (a minifikátor eltávolítja)
Nem hívott függvény DCE utánfunction a(){} a() ahol a nincs meghívvaRészben

Hogyan működik a Tree Shaking: modulok statikus elemzése

A Tree Shaking mechanizmusa a függőségi gráfon (dependency graph) alapul, amelyet a buildelő a projekt összes import/exportjából épít fel. Az első szakaszban a buildelő végigjárja az összes fájlt a belépési ponttól (entry point) és összegyűjti a modulok fáját. A második szakaszban elemzi, hogy mely exportok az egyes modulokból ténylegesen importálva vannak más modulokban.

Minden modul esetében a Webpack vagy Rollup az exportokat használtként vagy nem használtként jelöli meg. A nem használt exportok kikerülnek a bundle-ből. Maga a modul azonban a bundle-ben marad, ha legalább egy exportja használatban van. Egy modul teljes kizárása csak a sideEffects jelzőn keresztül lehetséges, vagy ha a modul nem tartalmaz mellékhatásokat.

Példa: előtte és utána Tree Shaking

js
// utils.js — modul függvényekkel
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 — belépési pont
import { formatDate } from "./utils";

const today = formatDate(new Date());
console.log(today);
js
// Tree Shaking után — a bundle-ben csak formatDate
function formatDate(date) {
  return date.toISOString().slice(0, 10);
}
const today = formatDate(new Date());
console.log(today);

Tree Shaking kizárta a formatCurrency és slugify függvényeket a végső bundle-ből, mert nem importálják őket az app.js-ben. Az utils.js modul mérete 3 függvényről 1-re csökkent. Ha az utils.js side effects-et tartalmaz (pl. globális inicializálás), a Tree Shaking még a nem használt exportokat sem tudja eltávolítani.

Tree Shaking a Webpackban: konfiguráció és optimalizálás

Webpack beépített támogatást tartalmaz a Tree Shakinghez a TerserPlugin-on keresztül production módban. A Tree Shaking bekapcsolásához két feltétel elegendő: a mode productionre van állítva (mode: "production") és a modulok ES szintaxist használnak (import/export). A Webpack automatikusan megjelöli a nem használt exportokat és továbbítja őket a Terser-nek eltávolításra.

További konfiguráció usedExports: true az optimization.webpack.config.js-ben bekapcsolja az exportok használatának részletes elemzését a modulon belül. Ez az opció meghatározza, hogy mely exportok ténylegesen használtak (used), és melyek csak exportáltak (provided). A usedExports és Terser kombinációja maximális hatékonyságot nyújt a holt kód eltávolításában.

Webpack konfiguráció Tree Shakinghez

js
// webpack.config.js — Tree Shaking konfiguráció
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 }],
            ],
          },
        },
      },
    ],
  },
};

A kulcs paraméter — modules: false a @babel/preset-env-ben. A Babel alapértelmezés szerint ES-modulokat CommonJS-re alakítja, ami megöli a Tree Shakinget. A modules: false megtiltja a Babel-nek, hogy átalakítsa az import/export-ot, megtartva az ES szintaxist a Webpack számára. A concatenateModules emellett egyesíti a modulokat egy közös láthatósági tartományba, csökkentve az IIFE-k számát és a bundle méretét.

A side effects probléma és a sideEffects jelző

Side effects (mellékhatások) — a modul műveletei az importáláskor, amelyek nem kapcsolódnak az exportált értékekhez: globális stílusok (import "./styles.css"), polyfill-ek (import "core-js/stable"), globális változók inicializálása vagy Service Worker regisztráció. Ha egy modul mellékhatásokat tartalmaz, a buildelő nem távolíthatja el biztonságosan a bundle-ből, még akkor sem, ha egyetlen export sincs használatban.

A sideEffects jelző a package.json-ben tájékoztatja a buildelőt arról, hogy a csomag mely moduljainak nincsenek mellékhatásai. Egy olyan csomag esetében, ahol minden modul tiszta (csak függvények exportálása), "sideEffects": false értéket kell beállítani. CSS-t vagy polyfill-eket tartalmazó csomagok esetén — a mellékhatásokkal rendelkező fájlok elérési útjainak tömbje: "sideEffects": ["*.css"]. E jelző nélkül a Tree Shaking még a nem használt függvényeket sem távolítja el.

Hogyan azonosítsuk a side effects-eket a saját kódunkban

Annak ellenőrzéséhez, hogy egy modulnak vannak-e mellékhatásai, tegye fel a kérdést: végrehajt-e ez az import bármilyen műveletet, amely nem kapcsolódik az értékek exportálásához? import "./styles.css" CSS-t ad a DOM-hoz — ez egy side effect. import { throttle } from "lodash-es" nem rendelkezik side effects-szel — csak elérhetővé teszi a throttle függvényt. A polyfill-ek (import "core-js/stable") side effects-szel rendelkeznek — módosítják a globális prototípusokat.

Saját modulokhoz ajánlott: a stílusok és polyfill-ek külön belépési pontokba helyezése, a tiszta segédprogramok (mellékhatások nélküli függvények) elkülönítése a mellékhatásokkal rendelkező moduloktól (inicializálás, naplózás, Service Worker regisztráció). A felső szintű projekt package.json-jában "sideEffects": false csak akkor állítson be, ha minden modul tiszta. Ha vannak stílusok — "sideEffects": ["*.css"] pontosan állítson be.

Példa sideEffects konfigurációra

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"] azt jelenti: az összes CSS fájlnak vannak mellékhatásai (nem távolíthatók el), és a polyfills.js-nek is. A csomag összes többi JS fájlja tiszta — biztonságosan shake-elhetők. A module mező a csomag ES-verziójának elérési útját jelzi, amelyet a buildelőnek használnia kell a CommonJS verzió (main) helyett a Tree Shakinghez.

Tree Shaking a React Native-ben és Metróban

React Native a Metro Bundlerrel korlátozott Tree Shaking verziót támogat. A Metro nem végez teljes statikus elemzést a használt exportokról (usedExports) mint a Webpack. Ehelyett a Metro a Terser-re támaszkodik a modulok nem használt részének eltávolításához a minifikációs szakaszban. Ennek a megközelítésnek a hatékonysága alacsonyabb, mint a teljes Tree Shaking a Webpackban.

A maximális optimalizáláshoz React Native projektekben ajánlott: ES-modulokkal rendelkező könyvtárak használata (module mező a package.json-ben), babel-plugin-transform-remove-console pluginek csatlakoztatása a hibakereső kód eltávolításához, és a Metro transformer.minifierConfig konfigurálása a Terser számára. Ezenkívül a Ram Bundle (a bundle modulokra bontása) csökkenti a nem használt képernyők betöltését.

Gyakran Ismételt Kérdések

Miért nem működik a Tree Shaking a CommonJS-szel?

CommonJS (require/module.exports) nem támogatja a statikus elemzést — a require dinamikusan hívható feltételek és függvények belsejében. A buildelő nem tudja meghatározni, hogy a modul mely részei használatosak ténylegesen. Csak az ES-modulok statikus import/export-tal teszik lehetővé a Tree Shakinget.

Használható-e a Tree Shaking TypeScript-tel?

TypeScript teljes mértékben kompatibilis a Tree Shakinggel, feltéve hogy a tsconfig.json ES-modulokra van konfigurálva: "module": "esnext". A TypeScript fordítónak meg kell őriznie az import/export-ot CommonJS-re való átalakítás nélkül. A Babel @babel/preset-typescript-tel és modules: false-szal szintén helyesen továbbítja az ES-modulokat a Webpacknak.

Hogyan ellenőrizhető, hogy a Tree Shaking működött-e?

Webpack Bundle Analyzer — egy plugin, amely interaktív diagram formájában vizualizálja a bundle összetételét. Ha egy könyvtár jelen van a bundle-ben, de függvényei nincsenek használatban, a Tree Shaking nem működött. A kimeneti fájl is elemezhető: keresse meg a nem használt exportot a bundle szövegében grep segítségével.

Miért nem tree-shake-elődik a Lodash alapértelmezés szerint?

Lodash v4 CommonJS csomagként kerül terjesztésre. A Tree Shakinghez használja a lodash-es-t — a könyvtár ES-verzióját. Cserélje ki az import throttle from "lodash/throttle"-t import { throttle } from "lodash-es"-re, és konfigurálja a resolve.alias-t a Webpackban a lodash lodash-es-re cseréléséhez.

Befolyásolja-e a Tree Shaking a buildelési időt?

Tree Shaking enyhén növeli a build időt (5–15%-kal), mert hozzáadja a függőségi gráf elemzésének és a használt exportok megjelölésének szakaszát. Fejlesztési módban a Tree Shaking általában ki van kapcsolva a sebesség érdekében. Production-ben a többletidőt a bundle méretének jelentős csökkenése indokolja.

Összefoglalás

  • Tree Shaking — a nem használt ES exportok automatikus eltávolítása a buildelési szakaszban, a bundle méretének 30–60%-os csökkentése
  • ES-modulok — az egyetlen formátum, amely támogatja a statikus elemzést; a CommonJS nem alkalmas Tree Shakingre
  • Webpack és Rollup a usedExports és Terser segítségével biztosítja a Tree Shakinget production módban
  • Side effects blokkolják a modul eltávolítását; a sideEffects: false jelző a package.json-ben megoldja a problémát tiszta könyvtárak esetén
  • Babel modules: false-szal kell konfigurálni, hogy ne alakítsa át az ES-modulokat CommonJS-re
  • React Native Metro korlátozott Tree Shakinggel rendelkezik, a minifikációs szakaszban a Terser-re támaszkodik

Kulcsrakész mobilalkalmazást fejlesztünk

Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.

Projekt megbeszélése

Olvassa el is