Tree Shaking — एप्लिकेशन बिल्ड चरण पर अप्रयुक्त कोड को हटाने (dead code elimination) की एक प्रक्रिया है। Tree Shaking ES-मॉड्यूल की स्थिर संरचना का विश्लेषण करता है और उन निर्यातित फ़ंक्शनों, क्लासों और वेरिएबलों को बाहर करता है जो कहीं भी आयात नहीं किए गए हैं। Webpack Documentation के अनुसार, Tree Shaking का सही कॉन्फ़िगरेशन एप्लिकेशन की कार्यक्षमता को बदले बिना बंडल आकार को 30–60% तक कम कर सकता है।
मुख्य बिंदु
Tree Shaking एक कोड अनुकूलन तकनीक है जो अंतिम बंडल से अप्रयुक्त मॉड्यूल और फ़ंक्शनों को बाहर करती है। यह शब्द Rollup टीम द्वारा 2015 में पेश किया गया था और प्रक्रिया का रूपक रूप से वर्णन करता है: निर्भरता पेड़ को हिलाया जाता है, और अप्रयुक्त शाखाएँ गिर जाती हैं। मैन्युअल अनुकूलन के विपरीत, Tree Shaking बिल्ड चरण पर स्वचालित रूप से निष्पादित होता है।
Tree Shaking केवल ES-मॉड्यूल (ECMAScript Modules) के साथ काम करता है, जहाँ निर्भरताएँ import और export के माध्यम से स्थिर रूप से निर्धारित की जाती हैं। CommonJS (require/module.exports) Tree Shaking का समर्थन नहीं करता क्योंकि require गतिशील रूप से निष्पादित होता है — बंडलर पहले से निर्धारित नहीं कर सकता कि कौन से फ़ंक्शन वास्तव में उपयोग किए जाते हैं। आधुनिक लाइब्रेरी (Lodash, Moment.js, RxJS) Tree Shaking का समर्थन करने के लिए ES संस्करण जारी करती हैं।
Rollup पहला बंडलर था जिसने 2015 में Tree Shaking लागू किया। Webpack के विपरीत, Rollup शुरू से ही ES-मॉड्यूल के लिए डिज़ाइन किया गया था और अधिक आक्रामक मृत कोड हटाने का कार्य करता है। Rollup न केवल व्यक्तिगत निर्यातों बल्कि पूरे मॉड्यूल का विश्लेषण करता है: यदि किसी मॉड्यूल में कोई दुष्प्रभाव नहीं है और कोई निर्यात उपयोग नहीं किया गया है, तो Rollup पूरे मॉड्यूल को बंडल से बाहर कर देता है।
Rollup विशेष रूप से लाइब्रेरी और SDK के लिए प्रभावी है जहाँ हर किलोबाइट मायने रखता है। Vue.js फ्रेमवर्क अपने प्रोडक्शन संस्करण के निर्माण के लिए Rollup का उपयोग करता है। React ने 2020 में Rollup पर स्विच किया। एप्लिकेशन के लिए, Webpack अधिक समृद्ध प्लगइन पारिस्थितिकी तंत्र (Hot Module Replacement, code splitting, CSS modules) के कारण अधिक सामान्यतः उपयोग किया जाता है, लेकिन लाइब्रेरी बनाते समय अधिकतम Tree Shaking के लिए, Rollup उद्योग मानक बना हुआ है।
Tree Shaking से बचत प्रोजेक्ट आर्किटेक्चर पर बहुत निर्भर करती है। Ant Design लाइब्रेरी वाले React एप्लिकेशन में, Tree Shaking UI घटकों के 70% तक कोड को हटा सकता है। ऐसे प्रोजेक्ट में जहाँ सभी आयात विशिष्ट और लक्षित हैं, बचत 5–15% होगी। Webpack अनुसंधान के अनुसार, औसत बचत बंडल आकार का 30–40% है।
| मृत कोड का प्रकार | उदाहरण | Tree Shaking पहचान |
|---|---|---|
| अप्रयुक्त निर्यात | export function unusedHelper() | हाँ |
| अप्रयुक्त आयात | import { unused } from "lib" | हाँ |
| मृत शर्त शाखा | if (false) { ... } | नहीं (मिनिफ़ायर द्वारा हटाया गया) |
| DCE के बाद अनकॉल किया गया फ़ंक्शन | function a(){} a() जहाँ a कॉल नहीं किया गया | आंशिक रूप से |
Tree Shaking तंत्र एक निर्भरता ग्राफ पर आधारित है जिसे बंडलर प्रोजेक्ट में सभी import/export स्टेटमेंट से बनाता है। पहले चरण में, बंडलर एंट्री पॉइंट से सभी फ़ाइलों को ट्रैवर्स करता है और मॉड्यूल ट्री एकत्र करता है। दूसरे चरण में, यह विश्लेषण करता है कि प्रत्येक मॉड्यूल से कौन से निर्यात वास्तव में अन्य मॉड्यूल में आयात किए गए हैं।
प्रत्येक मॉड्यूल के लिए, Webpack या Rollup निर्यातों को उपयोग किए गए या अप्रयुक्त के रूप में चिह्नित करता है। अप्रयुक्त निर्यात बंडल से बाहर कर दिए जाते हैं। हालाँकि, मॉड्यूल स्वयं बंडल में रहता है यदि उसका कम से कम एक निर्यात उपयोग किया जाता है। मॉड्यूल को पूरी तरह से केवल sideEffects फ़्लैग के माध्यम से या यदि मॉड्यूल में कोई दुष्प्रभाव नहीं है, तो बाहर किया जा सकता है।
// utils.js — फ़ंक्शनों वाला मॉड्यूल
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 — एंट्री पॉइंट
import { formatDate } from "./utils";
const today = formatDate(new Date());
console.log(today);// Tree Shaking के बाद — बंडल में केवल formatDate
function formatDate(date) {
return date.toISOString().slice(0, 10);
}
const today = formatDate(new Date());
console.log(today);Tree Shaking ने formatCurrency और slugify को अंतिम बंडल से बाहर कर दिया क्योंकि वे app.js में आयात नहीं किए गए हैं। utils.js मॉड्यूल का आकार 3 फ़ंक्शन से घटकर 1 हो गया। यदि utils.js में दुष्प्रभाव हैं (उदाहरण के लिए, वैश्विक आरंभीकरण), तो Tree Shaking अप्रयुक्त निर्यातों को भी नहीं हटा सकता।
Webpack में प्रोडक्शन मोड में TerserPlugin के माध्यम से अंतर्निहित Tree Shaking समर्थन शामिल है। Tree Shaking सक्षम करने के लिए, दो शर्तें पर्याप्त हैं: mode को production (mode: "production") पर सेट किया गया है और मॉड्यूल ES सिंटैक्स (import/export) का उपयोग करते हैं। Webpack स्वचालित रूप से अप्रयुक्त निर्यातों को चिह्नित करता है और उन्हें हटाने के लिए Terser को भेजता है।
optimization.webpack.config.js में अतिरिक्त usedExports: true कॉन्फ़िगरेशन मॉड्यूल के अंदर निर्यात उपयोग का विस्तृत विश्लेषण सक्षम करता है। यह विकल्प निर्धारित करता है कि कौन से निर्यात वास्तव में उपयोग किए गए हैं और कौन से केवल निर्यात किए गए हैं (provided)। usedExports और Terser का संयोजन अधिकतम मृत कोड हटाने की दक्षता देता है।
// webpack.config.js — Tree Shaking कॉन्फ़िगरेशन
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 }],
],
},
},
},
],
},
};मुख्य पैरामीटर @babel/preset-env में modules: false है। डिफ़ॉल्ट रूप से, Babel ES-मॉड्यूल को CommonJS में बदल देता है, जो Tree Shaking को खत्म कर देता है। modules: false Babel को import/export को बदलने से रोकता है, Webpack के लिए ES सिंटैक्स को संरक्षित करता है। concatenateModules अतिरिक्त रूप से मॉड्यूल को साझा दायरे में मर्ज करता है, IIFE की संख्या कम करता है और बंडल आकार घटाता है।
Side effects (दुष्प्रभाव) — मॉड्यूल द्वारा आयात किए जाने पर की गई कार्रवाइयाँ जो निर्यात मानों से संबंधित नहीं हैं: वैश्विक स्टाइल (import "./styles.css"), पॉलीफ़िल (import "core-js/stable"), वैश्विक चर आरंभीकरण या Service Worker पंजीकरण। यदि किसी मॉड्यूल में दुष्प्रभाव हैं, तो बंडलर इसे बंडल से सुरक्षित रूप से नहीं हटा सकता, भले ही उसके किसी भी निर्यात का उपयोग न किया गया हो।
package.json में sideEffects फ़्लैग बंडलर को बताता है कि पैकेज के कौन से मॉड्यूल में कोई दुष्प्रभाव नहीं है। एक पैकेज के लिए जहाँ सभी मॉड्यूल शुद्ध हैं (केवल फ़ंक्शन निर्यात), "sideEffects": false निर्दिष्ट किया जाना चाहिए। CSS या पॉलीफ़िल वाले पैकेज के लिए — दुष्प्रभाव वाली फ़ाइलों के पथों की एक सरणी: "sideEffects": ["*.css"]। इस फ़्लैग के बिना, Tree Shaking अप्रयुक्त फ़ंक्शनों को भी नहीं हटाएगा।
यह जाँचने के लिए कि क्या किसी मॉड्यूल में दुष्प्रभाव हैं, यह प्रश्न पूछें: क्या यह आयात मान निर्यात करने से संबंधित कोई कार्रवाई करेगा? import "./styles.css" DOM में CSS जोड़ता है — यह एक दुष्प्रभाव है। import { throttle } from "lodash-es" में कोई दुष्प्रभाव नहीं है — यह केवल throttle फ़ंक्शन को उपलब्ध कराता है। पॉलीफ़िल (import "core-js/stable") में दुष्प्रभाव हैं — वे वैश्विक प्रोटोटाइप को संशोधित करते हैं।
अपने स्वयं के मॉड्यूल के लिए, अनुशंसित है: स्टाइल और पॉलीफ़िल को अलग-अलग एंट्री पॉइंट में निकालें, शुद्ध उपयोगिताओं (बिना दुष्प्रभाव वाले फ़ंक्शन) को दुष्प्रभाव वाले मॉड्यूल (आरंभीकरण, लॉगिंग, Service Worker पंजीकरण) से अलग करें। शीर्ष-स्तरीय प्रोजेक्ट package.json में, "sideEffects": false केवल तभी निर्दिष्ट करें जब सभी मॉड्यूल शुद्ध हों। यदि स्टाइल हैं, तो "sideEffects": ["*.css"] सटीक रूप से निर्दिष्ट करें।
{
"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"] का अर्थ है: सभी CSS फ़ाइलों में दुष्प्रभाव हैं (उन्हें हटाया नहीं जा सकता) और polyfills.js में भी। पैकेज में अन्य सभी JS फ़ाइलें शुद्ध हैं — उन्हें सुरक्षित रूप से shake किया जा सकता है। module फ़ील्ड पैकेज के ES संस्करण का पथ निर्दिष्ट करता है जिसका उपयोग बंडलर को Tree Shaking के लिए CommonJS संस्करण (main) के बजाय करना चाहिए।
React Native Metro Bundler के साथ Tree Shaking का एक सीमित संस्करण समर्थन करता है। Metro Webpack की तरह उपयोग किए गए निर्यातों (usedExports) का पूर्ण स्थिर विश्लेषण नहीं करता। इसके बजाय, Metro मिनिफिकेशन के दौरान मॉड्यूल के अप्रयुक्त भागों को हटाने के लिए Terser पर निर्भर करता है। इस दृष्टिकोण की प्रभावशीलता Webpack में पूर्ण Tree Shaking से कम है।
React Native प्रोजेक्ट के अधिकतम अनुकूलन के लिए, अनुशंसित है: ES-मॉड्यूल वाली लाइब्रेरी का उपयोग करें (package.json में module फ़ील्ड), डीबग कोड हटाने के लिए babel-plugin-transform-remove-console जोड़ें, और Terser के लिए Metro transformer.minifierConfig कॉन्फ़िगर करें। इसके अतिरिक्त, Ram Bundle (बंडल को मॉड्यूल में विभाजित करना) अप्रयुक्त स्क्रीन की लोडिंग कम करता है।
अक्सर पूछे जाने वाले प्रश्न
CommonJS (require/module.exports) स्थिर विश्लेषण का समर्थन नहीं करता — require को शर्तों और फ़ंक्शनों के अंदर गतिशील रूप से कॉल किया जा सकता है। बंडलर यह निर्धारित नहीं कर सकता कि मॉड्यूल के कौन से भाग वास्तव में उपयोग किए जाते हैं। केवल स्थिर import/export वाले ES-मॉड्यूल Tree Shaking की अनुमति देते हैं।
TypeScript Tree Shaking के साथ पूरी तरह से संगत है बशर्ते कि tsconfig.json ES-मॉड्यूल के लिए कॉन्फ़िगर किया गया हो: "module": "esnext"। TypeScript कंपाइलर को import/export को CommonJS में बदले बिना संरक्षित करना चाहिए। @babel/preset-typescript और modules: false वाला Babel भी ES-मॉड्यूल को Webpack में सही ढंग से भेजता है।
Webpack Bundle Analyzer — एक प्लगइन जो बंडल संरचना को एक इंटरैक्टिव आरेख के रूप में विज़ुअलाइज़ करता है। यदि कोई लाइब्रेरी बंडल में मौजूद है लेकिन उसके फ़ंक्शन उपयोग नहीं किए गए हैं, तो Tree Shaking ने काम नहीं किया। आप आउटपुट फ़ाइल का भी विश्लेषण कर सकते हैं: grep के माध्यम से बंडल टेक्स्ट में अप्रयुक्त निर्यात खोजें।
Lodash v4 एक CommonJS पैकेज के रूप में वितरित किया जाता है। Tree Shaking के लिए, आपको lodash-es — लाइब्रेरी का ES संस्करण — का उपयोग करना होगा। import throttle from "lodash/throttle" को import { throttle } from "lodash-es" से बदलें और lodash को lodash-es से बदलने के लिए Webpack में resolve.alias कॉन्फ़िगर करें।
Tree Shaking बिल्ड समय को थोड़ा बढ़ाता है (5–15% तक) क्योंकि यह निर्भरता ग्राफ विश्लेषण और उपयोग किए गए निर्यात चिह्नित करने का चरण जोड़ता है। डेवलपमेंट मोड में, Tree Shaking आमतौर पर गति के लिए अक्षम किया जाता है। प्रोडक्शन में, अतिरिक्त समय बंडल आकार में महत्वपूर्ण कमी द्वारा उचित है।
सारांश
हम एक मोबाइल एप्लिकेशन टर्नकी विकसित करेंगे
IT Sectr 2017 से स्टार्टअप और व्यवसायों के लिए iOS और Android एप्लिकेशन बनाता है। हम आपको सलाह देंगे और सर्वोत्तम समाधान प्रस्तावित करेंगे।
यह भी पढ़ें