इस कोडलैब में, इस सामान्य ऐप्लिकेशन की परफ़ॉर्मेंस को बेहतर बनाएं. इस ऐप्लिकेशन की मदद से, लोग अलग-अलग बिल्लियों को रेटिंग दे सकते हैं. ट्रांसपाइल किए गए कोड की मात्रा को कम करके, JavaScript बंडल को ऑप्टिमाइज़ करने का तरीका जानें.

सैंपल ऐप्लिकेशन में, किसी शब्द या इमोजी को चुनकर यह बताया जा सकता है कि आपको हर बिल्ली कितनी पसंद है. किसी बटन पर क्लिक करने पर, ऐप्लिकेशन, बिल्ली की मौजूदा इमेज के नीचे बटन की वैल्यू दिखाता है.
मापें
किसी भी तरह का ऑप्टिमाइज़ेशन जोड़ने से पहले, वेबसाइट की जांच करना हमेशा एक अच्छा तरीका होता है:
- साइट की झलक देखने के लिए, ऐप्लिकेशन देखें दबाएं. इसके बाद, फ़ुलस्क्रीन
दबाएं.
- DevTools खोलने के लिए, `Control+Shift+J` (या Mac पर `Command+Option+J`) दबाएं.
- नेटवर्क टैब पर क्लिक करें.
- कैश मेमोरी बंद करें चेकबॉक्स को चुनें.
- ऐप्लिकेशन को फिर से लोड करें.

इस ऐप्लिकेशन के लिए 80 केबी से ज़्यादा जगह का इस्तेमाल किया गया है! यह पता लगाएं कि बंडल के कुछ हिस्सों का इस्तेमाल नहीं किया जा रहा है या नहीं:
कमांड मेन्यू खोलने के लिए,
Control+Shift+P(या Mac परCommand+Shift+P) दबाएं.
Show Coverageडालें औरEnterदबाकर कवरेज टैब दिखाएं.कवरेज टैब में, कवरेज कैप्चर करते समय ऐप्लिकेशन को फिर से लोड करने के लिए, फिर से लोड करें पर क्लिक करें.

देखें कि मुख्य बंडल के लिए, कितना कोड इस्तेमाल किया गया और कितना कोड लोड किया गया:
बंडल का आधा हिस्सा (44 केबी) भी इस्तेमाल नहीं किया गया है. ऐसा इसलिए है, क्योंकि इसमें मौजूद ज़्यादातर कोड में पॉलीफ़िल शामिल होते हैं. इससे यह पक्का किया जाता है कि ऐप्लिकेशन पुराने ब्राउज़र में काम करे.
@babel/preset-env का इस्तेमाल करना
JavaScript भाषा का सिंटैक्स, ECMAScript या ECMA-262 के नाम से जाने जाने वाले स्टैंडर्ड के मुताबिक होता है. हर साल, स्पेसिफ़िकेशन के नए वर्शन रिलीज़ किए जाते हैं. इनमें नई सुविधाएं शामिल होती हैं. ये सुविधाएं, प्रस्ताव की प्रोसेस को पूरा कर चुकी होती हैं. हर मुख्य ब्राउज़र, इन सुविधाओं को अलग-अलग चरणों में सपोर्ट करता है.
इस ऐप्लिकेशन में ES2015 की इन सुविधाओं का इस्तेमाल किया गया है:
ES2017 की इस सुविधा का भी इस्तेमाल किया जाता है:
src/index.js में जाकर सोर्स कोड देखें और जानें कि इन सभी का इस्तेमाल कैसे किया जाता है.
ये सभी सुविधाएं, Chrome के नए वर्शन में काम करती हैं. हालांकि, उन ब्राउज़र का क्या होगा जिनमें ये सुविधाएं काम नहीं करती हैं? Babel, ऐप्लिकेशन में शामिल सबसे लोकप्रिय लाइब्रेरी है. इसका इस्तेमाल, नए सिंटैक्स वाले कोड को ऐसे कोड में कंपाइल करने के लिए किया जाता है जिसे पुराने ब्राउज़र और एनवायरमेंट समझ सकें. यह दो तरीकों से ऐसा करता है:
- Polyfills को ES2015+ के नए फ़ंक्शन की नकल करने के लिए शामिल किया जाता है, ताकि उनके एपीआई का इस्तेमाल तब भी किया जा सके, जब ब्राउज़र उन्हें सपोर्ट न करता हो. यहां
Array.includesतरीके के पॉलीफ़िल का एक उदाहरण दिया गया है. - प्लगिन का इस्तेमाल, ES2015 कोड (या बाद के वर्शन) को पुराने ES5 सिंटैक्स में बदलने के लिए किया जाता है. ये सिंटैक्स से जुड़े बदलाव हैं. जैसे, ऐरो फ़ंक्शन. इसलिए, इन्हें पॉलीफ़िल के साथ नहीं बदला जा सकता.
यह देखने के लिए कि Babel की कौनसी लाइब्रेरी शामिल हैं, 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, Babel का मुख्य कंपाइलर है. इससे, सभी Babel कॉन्फ़िगरेशन को प्रोजेक्ट के रूट में मौजूद.babelrcमें तय किया जाता है.babel-loaderइसमें webpack की बिल्ड प्रोसेस में Babel शामिल होता है.
अब 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यह पता लगाता है कि टारगेट के तौर पर चुने गए किसी भी ब्राउज़र या एनवायरमेंट के लिए, कौनसा ट्रांसफ़ॉर्म और पॉलीफ़िल ज़रूरी है.
Babel कॉन्फ़िगरेशन फ़ाइल, .babelrc देखें. इससे आपको पता चलेगा कि इसे कैसे शामिल किया गया है:
{
"presets": [
[
"@babel/preset-env",
{
"targets": "last 2 versions"
}
]
]
}
यह Babel और webpack सेटअप है. अगर webpack के अलावा किसी दूसरे मॉड्यूल बंडलर का इस्तेमाल किया जा रहा है, तो अपने ऐप्लिकेशन में Babel को शामिल करने का तरीका जानें.
targets एट्रिब्यूट में मौजूद .babelrc से पता चलता है कि किन ब्राउज़र को टारगेट किया जा रहा है. @babel/preset-env
यह browserslist के साथ इंटिग्रेट होता है. इसका मतलब है कि इस फ़ील्ड में इस्तेमाल की जा सकने वाली, काम करने वाली क्वेरी की पूरी सूची browserlist के दस्तावेज़ में देखी जा सकती है.
"last 2 versions" वैल्यू, ऐप्लिकेशन में कोड को ट्रांसपाइल करती है. यह कोड, हर ब्राउज़र के पिछले दो वर्शन के लिए होता है.
डीबग करना
ब्राउज़र के सभी Babel टारगेट के साथ-साथ, शामिल किए गए सभी ट्रांसफ़ॉर्म और पॉलीफ़िल को पूरी तरह से देखने के लिए, .babelrc: में debug फ़ील्ड जोड़ें
{
"presets": [
[
"@babel/preset-env",
{
"targets": "last 2 versions",
"debug": true
}
]
]
}
- टूल पर क्लिक करें.
- लॉग पर क्लिक करें.
ऐप्लिकेशन को फिर से लोड करें और एडिटर में सबसे नीचे, गड़बड़ी की स्थिति के लॉग देखें.
टारगेट किए गए ब्राउज़र
Babel, कंपाइल करने की प्रोसेस के बारे में कई तरह की जानकारी को कंसोल में लॉग करता है. इसमें, उन सभी टारगेट एनवायरमेंट की जानकारी भी शामिल होती है जिनके लिए कोड कंपाइल किया गया है.

ध्यान दें कि इस सूची में, बंद हो चुके ब्राउज़र जैसे कि Internet Explorer भी शामिल हैं. यह एक समस्या है, क्योंकि जिन ब्राउज़र पर Babel काम नहीं करता उनमें नई सुविधाएं नहीं जोड़ी जाएंगी. साथ ही, Babel उनके लिए खास सिंटैक्स को ट्रांसपाइल करता रहेगा. अगर उपयोगकर्ता आपकी साइट को ऐक्सेस करने के लिए इस ब्राउज़र का इस्तेमाल नहीं कर रहे हैं, तो इससे आपके बंडल का साइज़ बेवजह बढ़ जाता है.
Babel, इस्तेमाल किए गए ट्रांसफ़ॉर्म प्लगिन की सूची को भी लॉग करता है:

यह तो काफ़ी लंबी सूची है! ये ऐसे सभी प्लगिन हैं जिनका इस्तेमाल Babel को करना होता है, ताकि टारगेट किए गए सभी ब्राउज़र के लिए, ES2015+ सिंटैक्स को पुराने सिंटैक्स में बदला जा सके.
हालांकि, Babel इस्तेमाल किए गए किसी भी पॉलीफ़िल को नहीं दिखाता:
![]()
ऐसा इसलिए है, क्योंकि पूरे @babel/polyfill को सीधे तौर पर इंपोर्ट किया जा रहा है.
एक-एक करके पॉलीफ़िल लोड करना
डिफ़ॉल्ट रूप से, Babel में ES2015+ एनवायरमेंट के लिए ज़रूरी हर पॉलीफ़िल शामिल होता है. ऐसा तब होता है, जब @babel/polyfill को किसी फ़ाइल में इंपोर्ट किया जाता है. अगर टारगेट किए गए ब्राउज़र के लिए ज़रूरी पॉलीफ़िल इंपोर्ट करने हैं, तो कॉन्फ़िगरेशन में 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 मॉड्यूल काम करते हैं. इसके लिए, Babel की ज़रूरत नहीं होती. इसका मतलब है कि Babel कॉन्फ़िगरेशन में बदलाव करके, ब्राउज़र को आपके ऐप्लिकेशन के दो अलग-अलग वर्शन भेजे जा सकते हैं:
- ऐसा वर्शन जो मॉड्यूल के साथ काम करने वाले नए ब्राउज़र में काम करेगा. इसमें ऐसा मॉड्यूल शामिल होगा जिसे ज़्यादातर ट्रांसपाइल नहीं किया गया है, लेकिन इसकी फ़ाइल का साइज़ छोटा है
- ऐसा वर्शन जिसमें बड़ी, ट्रांसपाइल की गई स्क्रिप्ट शामिल होती है. यह किसी भी लेगसी ब्राउज़र में काम करती है
Babel के साथ ES Modules का इस्तेमाल करना
ऐप्लिकेशन के दोनों वर्शन के लिए अलग-अलग @babel/preset-env सेटिंग रखने के लिए, .babelrc फ़ाइल हटाएं. ऐप्लिकेशन के हर वर्शन के लिए, दो अलग-अलग कंपाइलेशन फ़ॉर्मैट तय करके, Babel की सेटिंग को 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 वैल्यू का इस्तेमाल करने के बजाय, esmodules का इस्तेमाल किया गया है. इसकी वैल्यू false है. इसका मतलब है कि Babel में, 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 मॉड्यूल, किसी ऐप्लिकेशन के दो अलग-अलग ट्रांसपाइल किए गए वर्शन को शिप करके, परफ़ॉर्मेंस को और बेहतर कैसे बना सकते हैं. इन दोनों तकनीकों के बारे में जानने के बाद, अब आप अपने बंडल के साइज़ को काफ़ी हद तक कम कर सकते हैं. इसलिए, आगे बढ़ें और ऑप्टिमाइज़ करें!