इस कोडलैब में, इस आसान ऐप्लिकेशन की परफ़ॉर्मेंस को बेहतर बनाएं. इस ऐप्लिकेशन की मदद से, उपयोगकर्ता किसी भी बिल्ली को रेटिंग दे सकते हैं. ट्रांसपाइल किए गए कोड की संख्या को कम करके, JavaScript बंडल को ऑप्टिमाइज़ करने का तरीका जानें.
सैंपल ऐप्लिकेशन में, आपके पास यह बताने के लिए कोई शब्द या इमोजी चुनने का विकल्प होता है कि आपको हर बिल्ली कितनी पसंद है. किसी बटन पर क्लिक करने पर, ऐप्लिकेशन उस बिल्ली की मौजूदा इमेज के नीचे बटन की वैल्यू दिखाता है.
मापें
किसी भी ऑप्टिमाइज़ेशन को जोड़ने से पहले, वेबसाइट की जांच करना हमेशा एक अच्छा आइडिया होता है:
- साइट की झलक देखने के लिए, ऐप्लिकेशन देखें दबाएं. इसके बाद, फ़ुलस्क्रीन दबाएं.
- DevTools खोलने के लिए, `Control+Shift+J` दबाएं. Mac पर, `Command+Option+J` दबाएं.
- नेटवर्क टैब पर क्लिक करें.
- कैश मेमोरी की सुविधा बंद करें चेकबॉक्स को चुनें.
- ऐप्लिकेशन को फिर से लोड करें.
इस ऐप्लिकेशन के लिए 80 केबी से ज़्यादा का इस्तेमाल किया गया है! अब यह पता लगाने का समय आ गया है कि बंडल के कुछ हिस्सों का इस्तेमाल नहीं किया जा रहा है या नहीं:
Command मेन्यू खोलने के लिए,
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
तरीके के polyfill का उदाहरण दिया गया है. - प्लग इन का इस्तेमाल, ES2015 कोड (या उसके बाद के वर्शन) को पुराने ES5 सिंटैक्स में बदलने के लिए किया जाता है. ये सिंटैक्स से जुड़े बदलाव हैं, जैसे कि ऐरो फ़ंक्शन. इसलिए, इन्हें पॉलीफ़िल की मदद से एमुलेट नहीं किया जा सकता.
package.json
देखें कि कौनसी Babel लाइब्रेरी शामिल हैं:
"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 का मुख्य कंपाइलर है. इससे, प्रोजेक्ट के रूट में.babelrc
में सभी Babel कॉन्फ़िगरेशन तय किए जाते हैं.babel-loader
, वेबपैक बिल्ड प्रोसेस में Babel को शामिल करता है.
अब webpack.config.js
देखें और जानें कि babel-loader
को नियम के तौर पर कैसे शामिल किया गया है:
module: { rules: [ //... { test: /\.js$/, exclude: /node_modules/, loader: "babel-loader" } ] },
@babel/polyfill
, ECMAScript की नई सुविधाओं के लिए सभी ज़रूरी polyfills उपलब्ध कराता है, ताकि वे उन प्लैटफ़ॉर्म पर काम कर सकें जिन पर वे काम नहीं करते. यह पहले से ही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/polyfill
इंपोर्ट किया जाता है, तो Babel डिफ़ॉल्ट रूप से, 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 की कई नई सुविधाएं, उन एनवायरमेंट में पहले से ही काम करती हैं जो Babel के बजाय JavaScript मॉड्यूल के साथ काम करते हैं. इसका मतलब है कि Babel के कॉन्फ़िगरेशन में बदलाव करके, ब्राउज़र पर अपने ऐप्लिकेशन के दो अलग-अलग वर्शन भेजे जा सकते हैं:
- ऐसा वर्शन जो मॉड्यूल के साथ काम करने वाले नए ब्राउज़र में काम करेगा. इसमें एक ऐसा मॉड्यूल शामिल है जिसे ज़्यादातर ट्रांसपाइल नहीं किया गया है, लेकिन फ़ाइल का साइज़ छोटा है
- ऐसा वर्शन जिसमें बड़ी और ट्रांसपाइल की गई स्क्रिप्ट शामिल होती है. यह स्क्रिप्ट, किसी भी लेगसी ब्राउज़र में काम करती है
Babel के साथ ES मॉड्यूल का इस्तेमाल करना
ऐप्लिकेशन के दोनों वर्शन के लिए अलग-अलग @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
वैल्यू के बजाय,
false
वैल्यू के साथ esmodules
का इस्तेमाल किया गया है. इसका मतलब है कि 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
, फ़िलहाल मॉड्यूल और nomodule स्क्रिप्ट, दोनों के आउटपुट के साथ काम नहीं करता. इस समस्या को हल करने के लिए, BabelMultiTargetPlugin और HTMLWebpackMultiBuildPlugin जैसे अलग-अलग प्लग इन और अन्य तरीके बनाए गए हैं. हालांकि, इस ट्यूटोरियल में मॉड्यूल स्क्रिप्ट एलिमेंट को मैन्युअल तरीके से जोड़ने का आसान तरीका इस्तेमाल किया गया है.
फ़ाइल के आखिर में src/index.js
में ये चीज़ें जोड़ें:
...
</form>
<script type="module" src="main.mjs"></script>
</body>
</html>
अब ऐप्लिकेशन को ऐसे ब्राउज़र में लोड करें जो मॉड्यूल के साथ काम करता हो. जैसे, Chrome का नया वर्शन.
सिर्फ़ मॉड्यूल को फ़ेच किया जाता है. इसकी वजह यह है कि ज़्यादातर हिस्से को ट्रांसपाइल नहीं किया जाता है, इसलिए बंडल का साइज़ बहुत छोटा होता है! ब्राउज़र, दूसरे स्क्रिप्ट एलिमेंट को पूरी तरह से अनदेखा कर देता है.
अगर ऐप्लिकेशन को किसी पुराने ब्राउज़र पर लोड किया जाता है, तो सिर्फ़ बड़ी और ट्रांसपाइल की गई स्क्रिप्ट को फ़ेच किया जाएगा. इसमें सभी ज़रूरी पॉलीफ़िल और ट्रांसफ़ॉर्म शामिल होंगे. यहां Chrome के पुराने वर्शन (38 वर्शन) पर किए गए सभी अनुरोधों का स्क्रीनशॉट दिया गया है.
नतीजा
अब आपको @babel/preset-env
का इस्तेमाल करके, टारगेट किए गए ब्राउज़र के लिए ज़रूरी polyfills उपलब्ध कराने का तरीका पता है. आपको यह भी पता है कि JavaScript मॉड्यूल, किसी ऐप्लिकेशन के दो अलग-अलग ट्रांसपाइल किए गए वर्शन को शिप करके, परफ़ॉर्मेंस को और बेहतर कैसे बना सकते हैं. इन दोनों तकनीकों से, बंडल का साइज़ काफ़ी कम किया जा सकता है. इस बारे में अच्छी तरह से जानने के बाद, बंडल को ऑप्टिमाइज़ करें!