कोडलैब के इस आसान ऐप्लिकेशन की मदद से, इस आसान ऐप्लिकेशन की परफ़ॉर्मेंस को बेहतर बनाएं. इसकी मदद से उपयोगकर्ता, रैंडम बिल्लियों को रेटिंग दे सकते हैं. ट्रांसपिल किए जाने वाले कोड को कम से कम करके, JavaScript बंडल को ऑप्टिमाइज़ करने का तरीका जानें.
सैंपल के तौर पर दिए गए ऐप्लिकेशन में, कोई शब्द या इमोजी चुनकर बताया जा सकता है कि आपको हर बिल्ली कितनी पसंद है. किसी बटन पर क्लिक करने पर ऐप्लिकेशन, बिल्ली की मौजूदा इमेज के नीचे बटन की वैल्यू दिखाता है.
दूरी मापें
कोई भी ऑप्टिमाइज़ेशन जोड़ने से पहले, वेबसाइट की जांच करके शुरुआत करना हमेशा बेहतर रहता है:
- साइट की झलक देखने के लिए, ऐप्लिकेशन देखें दबाएं. इसके बाद, फ़ुलस्क्रीन दबाएं.
- DevTools खोलने के लिए, `Control+Shift+J` (या Mac पर `Command+Option+J`) दबाएं.
- नेटवर्क टैब पर क्लिक करें.
- कैश मेमोरी बंद करें चेकबॉक्स चुनें.
- ऐप्लिकेशन को फिर से लोड करें.
इस आवेदन के लिए 80 केबी से ज़्यादा का इस्तेमाल किया गया है! अब पता लगाएं कि बंडल के कुछ हिस्से इस्तेमाल नहीं हो रहे हैं या नहीं:
Command मेन्यू खोलने के लिए,
Control+Shift+P
या Mac परCommand+Shift+P
दबाएं.कवरेज टैब देखने के लिए,
Show Coverage
डालें औरEnter
दबाएं.कवरेज कैप्चर करते समय, ऐप्लिकेशन को फिर से लोड करने के लिए, कवरेज टैब में, फिर से लोड करें पर क्लिक करें.
देखें कि मुख्य बंडल के लिए कितने कोड का इस्तेमाल किया गया और कितना लोड किया गया:
आधे से ज़्यादा बंडल (44 केबी) का भी इस्तेमाल नहीं होता. इसकी वजह यह है कि कई कोड में पॉलीफ़िल मौजूद होते हैं, ताकि यह पक्का किया जा सके कि ऐप्लिकेशन पुराने ब्राउज़र पर काम करे.
@bbel/preset-env का इस्तेमाल करें
JavaScript भाषा का सिंटैक्स ECMAScript या ECMA-262 नाम के स्टैंडर्ड के मुताबिक होता है. इस स्पेसिफ़िकेशन के नए वर्शन हर साल रिलीज़ किए जाते हैं. इनमें ऐसी नई सुविधाएं शामिल की जाती हैं जिन्होंने प्रस्ताव की प्रक्रिया को पास कर लिया है. हर प्रमुख ब्राउज़र, इन सुविधाओं के साथ काम करने के एक अलग स्टेज पर होता है.
ऐप्लिकेशन में, ES2015 की इन सुविधाओं का इस्तेमाल किया जाता है:
ES2017 की इस सुविधा का भी इस्तेमाल किया जा रहा है:
इन सभी का इस्तेमाल कैसे किया जाता है, यह देखने के लिए src/index.js
में सोर्स कोड देखें.
ये सभी सुविधाएं Chrome के सबसे नए वर्शन में काम करती हैं, लेकिन क्या उन ब्राउज़र का भी इस्तेमाल किया जा सकता है जो Chrome के नए वर्शन पर काम नहीं करते? ऐप्लिकेशन में शामिल Babel सबसे लोकप्रिय लाइब्रेरी है, जिसका इस्तेमाल कोड को कंपाइल करने के लिए किया जाता है. इसमें ऐसे नए सिंटैक्स वाले कोड होते हैं, जिन्हें पुराने ब्राउज़र और एनवायरमेंट समझ सकते हैं. यह इन दो तरीकों से करता है:
- Polyfill को नए ES2015+ फ़ंक्शन को एम्युलेट करने के लिए शामिल किया गया है, ताकि इनके एपीआई इस्तेमाल किए जा सकें. भले ही, वह ब्राउज़र पर काम न करता हो. यहां
Array.includes
तरीके के polyfill का एक उदाहरण दिया गया है. - प्लग इन का इस्तेमाल ES2015 कोड (या बाद के वर्शन) को पुराने ES5 सिंटैक्स में बदलने के लिए किया जाता है. ये बदलाव सिंटैक्स से जुड़े हैं, जैसे कि ऐरो फ़ंक्शन. इसलिए, इन्हें पॉलीफ़िल की मदद से एम्युलेट नहीं किया जा सकता.
यह देखने के लिए package.json
देखें कि कौन सी बेबल लाइब्रेरी शामिल हैं:
"dependencies": {
"@babel/polyfill": "^7.0.0"
},
"devDependencies": {
//...
"babel-loader": "^8.0.2",
"@babel/core": "^7.1.0",
"@babel/preset-env": "^7.1.0",
//...
}
@babel/core
, कोर बेबल कंपाइलर है. इसके साथ, सभी बेबल कॉन्फ़िगरेशन को प्रोजेक्ट के रूट में.babelrc
में तय किया जाता है.babel-loader
में वेबपैक की बिल्ड प्रोसेस में बेबल को शामिल किया जाता है.
अब webpack.config.js
देखें कि babel-loader
को नियम में कैसे शामिल किया गया है:
module: { rules: [ //... { test: /\.js$/, exclude: /node_modules/, loader: "babel-loader" } ] },
@babel/polyfill
किसी भी नई ECMAScript सुविधाओं के लिए सभी ज़रूरी पॉलीफ़िल उपलब्ध कराता है, ताकि वे ऐसे एनवायरमेंट में काम कर सकें जो उनके साथ काम नहीं करते. इसे पहले हीsrc/index.js.
के सबसे ऊपरी हिस्से पर इंपोर्ट किया जा चुका है
import "./style.css";
import "@babel/polyfill";
@babel/preset-env
से पता चलता है कि टारगेट के तौर पर चुने गए किसी भी ब्राउज़र या एनवायरमेंट के लिए, कौनसे ट्रांसफ़ॉर्म और पॉलीफ़िल ज़रूरी हैं.
बेबल कॉन्फ़िगरेशन फ़ाइल, .babelrc
पर एक नज़र डालें, ताकि यह देखा जा सके कि इसमें क्या-क्या शामिल है:
{
"presets": [
[
"@babel/preset-env",
{
"targets": "last 2 versions"
}
]
]
}
यह बेबल और Webpack का सेटअप है. अगर आपने webpack के बजाय किसी अन्य मॉड्यूल बंडलर का इस्तेमाल किया है, तो अपने ऐप्लिकेशन में बेबल को शामिल करने का तरीका जानें.
.babelrc
की targets
एट्रिब्यूट से यह पता चलता है कि किन ब्राउज़र को टारगेट किया जा रहा है. @babel/preset-env
ब्राउज़र की सूची के साथ काम करता है. इसका मतलब है कि आपको साथ काम करने वाली उन क्वेरी की पूरी सूची मिल जाएगी
जिनका इस्तेमाल इस फ़ील्ड में
ब्राउज़र की सूची वाले दस्तावेज़ में किया जा सकता है.
"last 2 versions"
वैल्यू, हर ब्राउज़र के पिछले दो वर्शन के लिए ऐप्लिकेशन में कोड को ट्रांसपिल करती है.
डीबग करना
ब्राउज़र के सभी बेबल टारगेट के साथ-साथ, इसमें शामिल सभी ट्रांसफ़ॉर्म और पॉलीफ़िल को अच्छी तरह से देखने के लिए, .babelrc:
में debug
फ़ील्ड जोड़ें
{
"presets": [
[
"@babel/preset-env",
{
"targets": "last 2 versions",
"debug": true
}
]
]
}
- टूल पर क्लिक करें.
- लॉग पर क्लिक करें.
ऐप्लिकेशन को फिर से लोड करें और एडिटर के सबसे नीचे, Glitch के स्टेटस लॉग पर नज़र डालें.
टारगेट किए गए ब्राउज़र
बेबल, कंपाइलेशन प्रोसेस के बारे में कंसोल में कई जानकारी लॉग करता है. इसमें उन सभी टारगेट एनवायरमेंट की जानकारी भी शामिल है जिनके लिए कोड को कंपाइल किया गया है.
ध्यान दें कि बंद किए गए ब्राउज़र, जैसे Internet Explorer को इस सूची में कैसे शामिल किया गया है. यह एक समस्या है क्योंकि असमर्थित ब्राउज़र में नई सुविधाएं नहीं जोड़ी जाएंगी और बेबल उनके लिए विशिष्ट सिंटैक्स को ट्रांसप करना जारी रखता है. अगर उपयोगकर्ता आपकी साइट ऐक्सेस करने के लिए इस ब्राउज़र का इस्तेमाल नहीं कर रहे हैं, तो इससे आपके बंडल का साइज़ बढ़ जाएगा.
बेबल, इस्तेमाल किए जाने वाले ट्रांसफ़ॉर्म प्लगिन की सूची भी लॉग करता है:
यह तो काफ़ी लंबी सूची है! ये ऐसे सभी प्लग इन हैं जिनका इस्तेमाल बेबल को सभी टारगेट किए गए ब्राउज़र के लिए किसी भी ES2015+ सिंटैक्स को पुराने सिंटैक्स में बदलने के लिए करना पड़ता है.
हालांकि, बेबल इस्तेमाल किए जाने वाले किसी खास पॉलीफ़िल को नहीं दिखाता है:
ऐसा इसलिए है, क्योंकि पूरे @babel/polyfill
को सीधे इंपोर्ट किया जा रहा है.
पॉलीफ़िल को अलग-अलग लोड करें
डिफ़ॉल्ट रूप से, @babel/polyfill
को किसी फ़ाइल में इंपोर्ट किए जाने पर, बेबल में ES2015+ के पूरे एनवायरमेंट के लिए ज़रूरी सभी पॉलीफ़िल शामिल होते हैं. टारगेट ब्राउज़र के लिए ज़रूरी पॉलीफ़िल को इंपोर्ट करने के लिए, कॉन्फ़िगरेशन में useBuiltIns: 'entry'
जोड़ें.
{
"presets": [
[
"@babel/preset-env",
{
"targets": "last 2 versions",
"debug": true
"useBuiltIns": "entry"
}
]
]
}
ऐप्लिकेशन को फिर से लोड करें. अब आपके पास, सभी खास पॉलीफ़िल को देखने का विकल्प है:
हालांकि, अब इसमें "last 2 versions"
के लिए सिर्फ़ पॉलीफ़िल की ज़रूरत है, लेकिन यह सूची काफ़ी लंबी है! ऐसा इसलिए होता है, क्योंकि हर नई सुविधा के लिए टारगेट ब्राउज़र के लिए ज़रूरी पॉलीफ़िल अब भी शामिल होता है. एट्रिब्यूट की वैल्यू को बदलकर usage
करें. ऐसा करके, सिर्फ़ उन सुविधाओं को शामिल किया जा सकता है जो कोड में इस्तेमाल की जा रही सुविधाओं के लिए ज़रूरी हैं.
{
"presets": [
[
"@babel/preset-env",
{
"targets": "last 2 versions",
"debug": true,
"useBuiltIns": "entry"
"useBuiltIns": "usage"
}
]
]
}
इससे, ज़रूरत पड़ने पर पॉलीफ़िल को अपने-आप शामिल कर लिया जाता है.
इसका मतलब है कि src/index.js.
में जाकर, @babel/polyfill
को इंपोर्ट करने की सुविधा हटाई जा सकती है
import "./style.css";
import "@babel/polyfill";
अब ऐप्लिकेशन के लिए ज़रूरी पॉलीफ़िल ही शामिल किए गए हैं.
ऐप्लिकेशन बंडल का साइज़ काफ़ी कम हो गया है.
काम करने वाले ब्राउज़र की सूची को छोटा करना
शामिल किए गए ब्राउज़र लक्ष्यों की संख्या अब भी बहुत ज़्यादा है और बहुत से उपयोगकर्ता Internet Explorer जैसे बंद किए गए ब्राउज़र का उपयोग नहीं करते. कॉन्फ़िगरेशन को इनसे अपडेट करें:
{
"presets": [
[
"@babel/preset-env",
{
"targets": "last 2 versions",
"targets": [">0.25%", "not ie 11"],
"debug": true,
"useBuiltIns": "usage",
}
]
]
}
फ़ेच किए गए बंडल के बारे में जानकारी देखें.
चूंकि ऐप्लिकेशन बहुत छोटा है, इसलिए इन बदलावों में कोई खास
कोई अंतर नहीं है. हालांकि, हमारा सुझाव है कि ब्राउज़र की बाज़ार में हिस्सेदारी के प्रतिशत (जैसे कि
">0.25%"
) का इस्तेमाल करने के साथ-साथ, उन ब्राउज़र को बाहर रखें जिनके बारे में आपको पूरा भरोसा है कि आपके उपयोगकर्ता उनका इस्तेमाल नहीं कर रहे हैं. इसके बारे में ज़्यादा जानने के लिए, जेम्स कायल के "पिछले दो वर्शन" लेख को पढ़ें.
<script type="module"> का इस्तेमाल करें
सुधार करने के लिए और भी गुंजाइश है. हालांकि, इस्तेमाल नहीं किए गए कई पॉलीफ़िल हटा दिए गए हैं. फिर भी ऐसे कई पॉलीफ़िल मौजूद हैं जो कुछ ब्राउज़र के लिए ज़रूरी नहीं हैं. मॉड्यूल का इस्तेमाल करके, नया सिंटैक्स बिना किसी ग़ैर-ज़रूरी पॉलीफ़िल के इस्तेमाल के बिना सीधे ब्राउज़र पर लिखा और भेजा जा सकता है.
JavaScript मॉड्यूल एक बाकी नई सुविधा है, जो सभी मुख्य ब्राउज़र पर काम करती है.
अन्य मॉड्यूल से इंपोर्ट और एक्सपोर्ट करने वाली स्क्रिप्ट तय करने के लिए, type="module"
एट्रिब्यूट का इस्तेमाल करके मॉड्यूल बनाए जा सकते हैं. उदाहरण के लिए:
// math.mjs
export const add = (x, y) => x + y;
<!-- index.html -->
<script type="module">
import { add } from './math.mjs';
add(5, 2); // 7
</script>
कई नई ECMAScript सुविधाएं ऐसे एनवायरमेंट में पहले से काम कर सकती हैं जो JavaScript मॉड्यूल का इस्तेमाल करते हैं (बबेल की ज़रूरत के बजाय.) इसका मतलब है कि बेबल कॉन्फ़िगरेशन को इस तरह बदला जा सकता है कि ब्राउज़र पर आपके ऐप्लिकेशन के दो अलग-अलग वर्शन भेजे जा सकें:
- एक वर्शन जो मॉड्यूल का समर्थन करने वाले नए ब्राउज़र में काम करेगा और जिसमें एक ऐसा मॉड्यूल शामिल है जो काफ़ी हद तक ट्रांसपैर नहीं किया गया है, लेकिन उसका फ़ाइल साइज़ छोटा है
- ऐसा वर्शन जिसमें बड़ी, ट्रांसपिल की गई स्क्रिप्ट शामिल है, जो किसी भी लेगसी ब्राउज़र में काम करेगी
बेबल के साथ ES मॉड्यूल का इस्तेमाल करना
ऐप्लिकेशन के दोनों वर्शन के लिए अलग-अलग @babel/preset-env
सेटिंग रखने के लिए, .babelrc
फ़ाइल हटाएं. ऐप्लिकेशन के हर वर्शन के लिए दो अलग-अलग कंपाइलेशन फ़ॉर्मैट तय करके, बेबेल सेटिंग को webpack कॉन्फ़िगरेशन में जोड़ा जा सकता है.
webpack.config.js
में लेगसी स्क्रिप्ट के लिए कॉन्फ़िगरेशन जोड़कर शुरुआत करें:
const legacyConfig = {
entry,
output: {
path: path.resolve(__dirname, "public"),
filename: "[name].bundle.js"
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: "babel-loader",
options: {
presets: [
["@babel/preset-env", {
useBuiltIns: "usage",
targets: {
esmodules: false
}
}]
]
}
},
cssRule
]
},
plugins
}
ध्यान दें कि "@babel/preset-env"
के लिए targets
वैल्यू के बजाय, false
वैल्यू वाले esmodules
का इस्तेमाल किया जा रहा है. इसका मतलब है कि बेबल
में सभी ज़रूरी ट्रांसफ़ॉर्म और पॉलीफ़िल शामिल हैं, ताकि ऐसे हर ब्राउज़र को टारगेट किया जा सके जो अभी तक ES मॉड्यूल के साथ काम नहीं करता.
webpack.config.js
फ़ाइल की शुरुआत में entry
, cssRule
, और corePlugins
ऑब्जेक्ट जोड़ें. ये सभी चीज़ें मॉड्यूल और ब्राउज़र पर इस्तेमाल की जाने वाली लेगसी स्क्रिप्ट, दोनों के बीच शेयर की जाती हैं.
const entry = {
main: "./src"
};
const cssRule = {
test: /\.css$/,
use: ExtractTextPlugin.extract({
fallback: "style-loader",
use: "css-loader"
})
};
const plugins = [
new ExtractTextPlugin({filename: "[name].css", allChunks: true}),
new HtmlWebpackPlugin({template: "./src/index.html"})
];
अब इसी तरह, नीचे दिए गए मॉड्यूल स्क्रिप्ट के लिए एक कॉन्फ़िगरेशन ऑब्जेक्ट बनाएं, जहां legacyConfig
तय किया गया है:
const moduleConfig = {
entry,
output: {
path: path.resolve(__dirname, "public"),
filename: "[name].mjs"
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: "babel-loader",
options: {
presets: [
["@babel/preset-env", {
useBuiltIns: "usage",
targets: {
esmodules: true
}
}]
]
}
},
cssRule
]
},
plugins
}
यहां मुख्य अंतर यह है कि आउटपुट फ़ाइल नाम के लिए, .mjs
फ़ाइल एक्सटेंशन का इस्तेमाल किया जाता है. यहां esmodules
की वैल्यू 'सही' पर सेट है. इसका मतलब है कि इस मॉड्यूल में दिया गया कोड, कम कंपाइल की गई एक छोटी स्क्रिप्ट है. इस उदाहरण में कोई बदलाव नहीं किया जा सकता. इसकी वजह यह है कि इस्तेमाल की गई सभी सुविधाएं, मॉड्यूल के साथ काम करने वाले ब्राउज़र में पहले से ही काम करती हैं.
फ़ाइल के सबसे आखिर में, दोनों कॉन्फ़िगरेशन को एक ही अरे में एक्सपोर्ट करें.
module.exports = [
legacyConfig, moduleConfig
];
अब इससे, ब्राउज़र पर काम करने वाले ब्राउज़र के लिए एक छोटा मॉड्यूल और पुराने ब्राउज़र के लिए बड़ी ट्रांसपिल की गई स्क्रिप्ट, दोनों बनती है.
मॉड्यूल के साथ काम करने वाले ब्राउज़र, nomodule
एट्रिब्यूट वाली स्क्रिप्ट को अनदेखा करते हैं.
वहीं, जिन ब्राउज़र में मॉड्यूल काम नहीं करते वे type="module"
वाले स्क्रिप्ट एलिमेंट को अनदेखा कर देते हैं. इसका मतलब है कि आपके पास मॉड्यूल के साथ-साथ, कंपाइल किए गए फ़ॉलबैक को शामिल करने की सुविधा होती है. आम तौर पर, ऐप्लिकेशन के दो वर्शन index.html
में इस तरह होने चाहिए:
<script type="module" src="main.mjs"></script>
<script nomodule src="main.bundle.js"></script>
मॉड्यूल की सुविधा वाले ब्राउज़र, main.mjs
को फ़ेच और एक्ज़ीक्यूट करते हैं. साथ ही, उन्हें अनदेखा करते हैं
main.bundle.js.
जिन ब्राउज़र पर मॉड्यूल काम नहीं करते वे ऐसा करते हैं.
यह ध्यान देना ज़रूरी है कि सामान्य स्क्रिप्ट के उलट, मॉड्यूल स्क्रिप्ट हमेशा डिफ़ॉल्ट रूप से टाल दी जाती हैं.
अगर आपको मिलती-जुलती nomodule
स्क्रिप्ट को भी टाला जाना है और सिर्फ़ पार्स करने के बाद ही उसे एक्ज़ीक्यूट करना है, तो आपको defer
एट्रिब्यूट जोड़ना होगा:
<script type="module" src="main.mjs"></script>
<script nomodule src="main.bundle.js" defer></script>
आपको बस मॉड्यूल और लेगसी स्क्रिप्ट में module
और nomodule
एट्रिब्यूट जोड़ने होंगे. इसके बाद, webpack.config.js
के सबसे ऊपर मौजूद ScriptExtHtmlWebpackPlugin को इंपोर्ट करें:
const path = require("path");
const webpack = require("webpack");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const ScriptExtHtmlWebpackPlugin = require("script-ext-html-webpack-plugin");
इस प्लग इन को शामिल करने के लिए, अब कॉन्फ़िगरेशन में plugins
कलेक्शन को अपडेट करें:
const plugins = [ new ExtractTextPlugin({filename: "[name].css", allChunks: true}), new HtmlWebpackPlugin({template: "./src/index.html"}), new ScriptExtHtmlWebpackPlugin({ module: /\.mjs$/, custom: [ { test: /\.js$/, attribute: 'nomodule', value: '' }, ] }) ];
ये प्लग इन सेटिंग सभी .mjs
स्क्रिप्ट एलिमेंट के लिए type="module"
एट्रिब्यूट और सभी .js
स्क्रिप्ट मॉड्यूल के लिए एक nomodule
एट्रिब्यूट जोड़ती हैं.
एचटीएमएल दस्तावेज़ में मॉड्यूल उपलब्ध कराना
आखिर में, आपको लेगसी और मॉडर्न स्क्रिप्ट एलिमेंट, दोनों को एचटीएमएल फ़ाइल में डालना होगा. माफ़ करें, फ़ाइनल एचटीएमएल फ़ाइल HTMLWebpackPlugin
बनाने वाला प्लगिन, मॉड्यूल और नोमॉड्यूल स्क्रिप्ट, दोनों के आउटपुट के साथ फ़िलहाल काम नहीं करता. हालांकि, इस समस्या को हल करने के लिए अलग-अलग तरीके और अलग-अलग प्लगिन बनाए गए हैं, जैसे कि BabelMultiTargetPlugin और HTMLWebpackMultiBuildPlugin. हालांकि, इस ट्यूटोरियल के लिए मॉड्यूल स्क्रिप्ट एलिमेंट को मैन्युअल रूप से जोड़ने का एक आसान तरीका इस्तेमाल किया जाता है.
फ़ाइल के आखिर में src/index.js
में यह जोड़ें:
...
</form>
<script type="module" src="main.mjs"></script>
</body>
</html>
अब ऐप्लिकेशन को ऐसे ब्राउज़र में लोड करें जिस पर मॉड्यूल काम करते हों, जैसे कि Chrome का सबसे नया वर्शन.
सिर्फ़ मॉड्यूल को फ़ेच किया जाता है. इसका साइज़ काफ़ी छोटा होता है, क्योंकि इसे बड़े पैमाने पर ट्रांसपिल नहीं किया जा सकता! स्क्रिप्ट के दूसरे एलिमेंट को ब्राउज़र पूरी तरह अनदेखा कर देता है.
अगर ऐप्लिकेशन को किसी पुराने ब्राउज़र पर लोड किया जाता है, तो सिर्फ़ बड़ी और ट्रांसपिल की गई स्क्रिप्ट, जिसके लिए सभी ज़रूरी पॉलीफ़िल और ट्रांसफ़ॉर्म को फ़ेच किया जाता है. यहां Chrome के पुराने वर्शन (वर्शन 38) पर किए गए सभी अनुरोधों का स्क्रीनशॉट दिया गया है.
नतीजा
अब आपको यह समझ आ गया है कि टारगेट किए गए ब्राउज़र के लिए ज़रूरी पॉलीफ़िल देने के लिए, @babel/preset-env
का इस्तेमाल कैसे करना है. आपको यह भी पता है कि JavaScript मॉड्यूल किस तरह किसी ऐप्लिकेशन के दो अलग-अलग ट्रांसपिल्ड वर्शन को शिप करके, परफ़ॉर्मेंस को और बेहतर बना सकता है. आपको इस बात की समझ है कि इन दोनों तरीकों से
आपके बंडल का साइज़ कैसे कम हो सकता है. इसके लिए, आगे बढ़ें और ऑप्टिमाइज़ करें!