इस्तेमाल न होने वाले कोड हटा दें

इस कोडलैब में, नीचे दिए गए ऐप्लिकेशन की परफ़ॉर्मेंस बेहतर बनाएं किसी भी इस्तेमाल न की गई और ग़ैर-ज़रूरी डिपेंडेंसी को हटाना.

ऐप्लिकेशन का स्क्रीनशॉट

मापें

आपको हमेशा यह आकलन करना चाहिए कि किसी वेबसाइट की परफ़ॉर्मेंस ऑप्टिमाइज़ेशन जोड़ना.

  • साइट की झलक देखने के लिए, ऐप्लिकेशन देखें दबाएं. इसके बाद, फ़ुलस्क्रीन फ़ुलस्क्रीन.

आगे बढ़ें और अपने पसंदीदा बिल्ली के बच्चे पर क्लिक करें! Firebase की रीयलटाइम डेटाबेस यह है का इस्तेमाल किया है, इसलिए स्कोर रीयल-टाइम में अपडेट होता रहता है. ऐप्लिकेशन का उपयोग कर रहे प्रत्येक अन्य व्यक्ति के साथ समन्वयित होता है. 🐈

  1. DevTools खोलने के लिए, `Control+Shift+J` (या Mac पर `Command+Option+J`) दबाएं.
  2. नेटवर्क टैब पर क्लिक करें.
  3. कैश मेमोरी बंद करें चेकबॉक्स चुनें.
  4. ऐप्लिकेशन को फिर से लोड करें.

मूल बंडल का साइज़ 992 केबी है

इस आसान ऐप्लिकेशन को लोड करने के लिए करीब 1 एमबी की JavaScript भेजी जा रही है!

DevTools में प्रोजेक्ट से जुड़ी चेतावनियां देखें.

  • कंसोल टैब पर क्लिक करें.
  • पक्का करें कि लेवल ड्रॉपडाउन में Warnings चालू हो Filter इनपुट.

चेतावनियां फ़िल्टर

  • दिखाई गई चेतावनी को देखें.

कंसोल से जुड़ी चेतावनी

Firebase, इस ऐप्लिकेशन में इस्तेमाल की जाने वाली लाइब्रेरी में से एक है. डेवलपर को यह चेतावनी देकर कि वे पैकेज को शामिल करने की ज़रूरत नहीं होती. हालांकि, सिर्फ़ कॉम्पोनेंट का इस्तेमाल किया जाता है. दूसरे शब्दों में, हमारे पास इस्तेमाल नहीं की गई लाइब्रेरी जिन्हें लोड करने के लिए इस ऐप्लिकेशन से हटाया जा सकता है और तेज़ी से.

ऐसे मामले भी होते हैं जब किसी खास लाइब्रेरी का इस्तेमाल किया जाता है, लेकिन एक ज़्यादा आसान विकल्प है. अनदेखी लाइब्रेरी को हटाने का सिद्धांत यह है इस ट्यूटोरियल में बाद में देखा जा सकता है.

बंडल का विश्लेषण किया जा रहा है

ऐप्लिकेशन में दो मुख्य डिपेंडेंसी होती हैं:

  • Firebase: एक ऐसा प्लैटफ़ॉर्म जो बड़ी संख्या में उपयोगी सेवाएं उपलब्ध कराता है, जिनमें iOS, Android या वेब ऐप्लिकेशन शामिल हैं. यह रही रीयलटाइम रिपोर्ट डेटाबेस का इस्तेमाल इन कामों के लिए किया जाता है बिल्ली के हर बच्चे की जानकारी को रीयल टाइम में सेव और सिंक करें.
  • Moment.js: यह एक यूटिलिटी लाइब्रेरी है जो JavaScript में तारीखें हैंडल करते हैं. हर बच्चे के जन्म की तारीख Firebase डेटाबेस और moment का इस्तेमाल करके हफ़्तों के हिसाब से इसकी उम्र का हिसाब लगाया जाता है.

सिर्फ़ दो डिपेंडेंसी से करीब एक एमबी के बंडल साइज़ में क्या योगदान मिल सकता है? ठीक है, इसकी एक वजह यह है कि निर्भरता होती है, इसलिए यदि आपकी डिपेंडेंसी "ट्री" को ध्यान में रखा जाता है. किसी ऐप्लिकेशन का बड़ा होना आसान है कई डिपेंडेंसी शामिल हों, तो दूसरे तरीकों से तेज़ी से लोड होता है.

बंडलर का विश्लेषण करके जानें कि क्या चल रहा है. कई समुदाय की ओर से बनाए गए अलग-अलग टूल की मदद से यह काम किया जा सकता है. जैसे webpack-bundle-analyzer.

इस टूल का पैकेज, ऐप्लिकेशन में devDependency के तौर पर पहले से शामिल है.

"devDependencies": {
  //...
  "webpack-bundle-analyzer": "^2.13.1"
},

इसका मतलब है कि इसका इस्तेमाल सीधे webpack कॉन्फ़िगरेशन फ़ाइल में किया जा सकता है. इसे webpack.config.js की शुरुआत में इंपोर्ट करें:

const path = require("path");

//...
const BundleAnalyzerPlugin = require("webpack-bundle-analyzer")
  .BundleAnalyzerPlugin;

अब इसे plugins कलेक्शन में फ़ाइल के सबसे आखिर में प्लगिन के तौर पर जोड़ें:

module.exports = {
  //...
  plugins: [
    //...
    new BundleAnalyzerPlugin()
  ]
};

जब ऐप्लिकेशन फिर से लोड होता है, तो आपको पूरे ऐप्लिकेशन का विज़ुअलाइज़ेशन दिखेगा बंडल का इस्तेमाल करने के लिए किया जा सकता है.

Webpack बंडल ऐनालाइज़र

कुछ बिल्ली के बच्चों को देखने जितना प्यारा नहीं Huddle, लेकिन फिर भी बहुत मददगार साबित होता है. किसी भी पैकेज पर कर्सर घुमाने पर, उसका साइज़ तीन फ़ॉर्मैट में दिखता है अलग-अलग तरीके:

आंकड़े का साइज़ किसी भी काट-छांट या कंप्रेस करने से पहले का आकार.
पार्स किया गया साइज़ कंपाइल होने के बाद, बंडल के अंदर असल पैकेज का साइज़. Webpack का वर्शन 4 (इसका इस्तेमाल इस ऐप्लिकेशन में किया जाता है) फ़ाइलों को अपने आप कंपाइल कर दिया जाता है, इसलिए यह दिए गए आंकड़ों से कम होता है साइज़.
Gzip किया गया साइज़ gzip एन्कोडिंग की मदद से कंप्रेस करने के बाद, पैकेज का साइज़. यह विषय एक अलग गाइड में शामिल है.

Webpack-बंडल-ऐनलिज़र टूल की मदद से, इस्तेमाल नहीं किए गए या ऐसे पैकेज जिनकी ज़रूरत नहीं है. ये पैकेज बंडल में बड़ी संख्या में होते हैं.

इस्तेमाल नहीं किए गए पैकेज हटाना

विज़ुअलाइज़ेशन से पता चलता है कि firebase पैकेज में बहुत ज़्यादा है बस एक डेटाबेस तक सीमित नहीं है. इसमें कुछ अतिरिक्त पैकेज शामिल हैं, जैसे:

  • firestore
  • auth
  • storage
  • messaging
  • functions

Firebase की ओर से दी जाने वाली ये सभी शानदार सेवाएं हैं. इन सेवाओं के लिए, दस्तावेज़ में बताया गया है), लेकिन उनमें से किसी का भी इस्तेमाल ऐप्लिकेशन में नहीं किया जा रहा हो. इसलिए, उन सभी को इंपोर्ट करने की कोई वजह नहीं होगी.

ऐप्लिकेशन को फिर से देखने के लिए, webpack.config.js में किए गए बदलावों को पहले जैसा करें:

  • प्लग इन की सूची से BundleAnalyzerPlugin को हटाएं:
plugins: [
  //...
  new BundleAnalyzerPlugin()
];
  • साथ ही, अब फ़ाइल के सबसे ऊपर से इस्तेमाल न होने वाले इंपोर्ट को हटा दें:
const path = require("path");

//...
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;

ऐप्लिकेशन अब सामान्य रूप से लोड होना चाहिए. अपडेट करने के लिए, src/index.js में बदलाव करें: Firebase इंपोर्ट.

import firebase from 'firebase';
import firebase from 'firebase/app';
import 'firebase/database';

अब ऐप्लिकेशन के फिर से लोड होने पर, DevTools की चेतावनी नहीं दिखेगी. खोला जा रहा है DevTools नेटवर्क पैनल की वजह से बंडल के साइज़ में ठीक कमी भी दिखती है:

बंडल का साइज़ कम करके 480 केबी किया गया

बंडल के आधे से ज़्यादा साइज़ को हटा दिया गया है. Firebase कई अलग-अलग प्लैटफ़ॉर्म इससे डेवलपर को सिर्फ़ उन सेवाओं को शामिल करने का विकल्प मिलता है जो की ज़रूरत नहीं है. इस ऐप्लिकेशन में, सेव और सिंक करने के लिए सिर्फ़ firebase/database का इस्तेमाल किया गया मदद मिलती है. firebase/app इंपोर्ट, जो जानकारी देना हमेशा ज़रूरी है.

lodash जैसी कई अन्य लोकप्रिय लाइब्रेरी भी डेवलपर को ये काम करने की अनुमति देती हैं अपने पैकेज के अलग-अलग हिस्सों को चुनिंदा तरीके से इंपोर्ट कर सकते हैं. बिना ज़्यादा मेहनत किए, किसी ऐप्लिकेशन में लाइब्रेरी से इंपोर्ट किए गए डेटा को अपडेट करके, उसमें सिर्फ़ वही डेटा शामिल किया जा सकता है जिसका इस्तेमाल किया जा रहा है परफ़ॉर्मेंस में सुधार हो सकता है.

हालांकि, बंडल के साइज़ को थोड़ा कम कर दिया गया है, लेकिन अब भी साइज़ कम किया गया है करने के लिए बहुत मेहनत करनी पड़ती है! 😈

ग़ैर-ज़रूरी पैकेज हटाना

Firebase के उलट, moment लाइब्रेरी के हिस्सों को इस तरह इंपोर्ट नहीं किया जा सकता: लेकिन क्या इसे पूरी तरह से हटाया जा सकता है?

हर प्यारे बिल्ली के बच्चे का जन्मदिन Unix फ़ॉर्मैट (मिलीसेकंड) में यहां सेव किया जाता है Firebase डेटाबेस.

Unix फ़ॉर्मैट में सेव की गई जन्म की तारीखें

यह एक खास तारीख और समय का टाइमस्टैंप है, जिसे मिलीसेकंड जो 1 जनवरी, 1970 को 00:00 यूटीसी से बीत चुके हैं. अगर मौजूदा तारीख और समय की गणना उसी फ़ॉर्मैट में की जा सकती है. इसका इस्तेमाल करके हफ़्ते में हर बिल्ली के बच्चे की उम्र तय की जा सकती है.

हमेशा की तरह, कोशिश करें कि यहां क्लिक करते समय कॉपी और पेस्ट न करें. इससे शुरू करें src/index.js में इंपोर्ट से moment को हटाया जा रहा है.

import firebase from 'firebase/app';
import 'firebase/database';
import * as moment from 'moment';

यह Firebase इवेंट लिसनर है, जो हमारे डेटाबेस में वैल्यू में हुए बदलावों को मैनेज करता है:

favoritesRef.on("value", (snapshot) => { ... })

इसके ऊपर, एक छोटा फलन जोड़ें, जो एक दी गई तारीख:

const ageInWeeks = birthDate => {
  const WEEK_IN_MILLISECONDS = 1000 * 60 * 60 * 24 * 7;
  const diff = Math.abs((new Date).getTime() - birthDate);
  return Math.floor(diff / WEEK_IN_MILLISECONDS);
}

इस फ़ंक्शन में, मौजूदा तारीख और मिलीसेकंड के बीच का अंतर समय (new Date).getTime() और जन्म की तारीख (birthDate तर्क, पहले से ही है मिलीसेकंड में), तो इसकी गिनती करने के बाद, नतीजे के तौर पर एक हफ़्ता.

आखिर में, इवेंट लिसनर में moment के सभी इंस्टेंस इस तरह हटाए जा सकते हैं इसके बजाय इस फ़ंक्शन का इस्तेमाल करके:

favoritesRef.on("value", (snapshot) => {
  const { kitties, favorites, names, birthDates } = snapshot.val();
  favoritesScores = favorites;

  kittiesList.innerHTML = kitties.map((kittiePic, index) => {
    const birthday = moment(birthDates[index]);

    return `
      <li>
        <img src=${kittiePic} onclick="favKittie(${index})">
        <div class="extra">
          <div class="details">
            <p class="name">${names[index]}</p>
            <p class="age">${moment().diff(birthday, 'weeks')} weeks old</p>
            <p class="age">${ageInWeeks(birthDates[index])} weeks old</p>
          </div>
          <p class="score">${favorites[index]} ❤</p>
        </div>
      </li>
    `})
});

अब ऐप्लिकेशन को फिर से लोड करें और एक बार फिर से नेटवर्क पैनल देखें.

बंडल का साइज़ कम करके 225 केबी किया गया

हमारे बंडल का साइज़ फिर से आधे से ज़्यादा कम कर दिया गया है!

नतीजा

इस कोडलैब के साथ, आपको अच्छी तरह समझ आ जाना चाहिए कि बंडल चुनें और यह बताएं कि इस्तेमाल न होने वाली या बिना ज़रूरत वाली चीज़ों को हटाना इतना मददगार क्यों है पैकेज. इस तकनीक से किसी ऐप्लिकेशन को ऑप्टिमाइज़ करने से पहले, आपको इसलिए, यह जानना भी ज़रूरी है कि बड़ी तादाद में ऐप्लिकेशन में दिया गया है.

इस्तेमाल नहीं की गई लाइब्रेरी को हटाने के संबंध में, यह जानने की कोशिश करें कि बंडल का इस्तेमाल किया जा रहा है और कौनसे हिस्से नहीं हैं. रहस्यमयी लुक के लिए जिस पैकेज को देखकर लगता है कि उसका कहीं भी इस्तेमाल नहीं किया जा रहा है, थोड़ा पीछे जाकर देखें किन टॉप-लेवल डिपेंडेंसी को इसकी ज़रूरत पड़ सकती है. अपने हिसाब से कोई रास्ता खोजना अलग-अलग कैटगरी में रखें.

जब अनचाही लाइब्रेरी को हटाने की बात आती है, तो आपको दो कार्रवाइयां करने की ज़रूरत पड़ सकती है मुश्किल. अपनी टीम के साथ मिलकर काम करना और यह देखना ज़रूरी है कि कोड बेस के हिस्सों को आसान बना सकता है. moment को इसमें हटाया जा रहा है ऐप्लिकेशन को हर बार सही तरीके से ही लागू करना चाहिए, लेकिन क्या ऐसे टाइम ज़ोन और अलग-अलग स्थान-भाषा को हैंडल करने की ज़रूरत थी? या क्या होता अगर तारीख में हेर-फेर करना ज़्यादा मुश्किल होता? इससे चीज़ें बहुत ज़्यादा यह तारीखों/समय और moment जैसी लाइब्रेरी में बदलाव करने और उन्हें पार्स करने में मुश्किल होता है और date-fns इसे काफ़ी हद तक आसान बना देते हैं.

हर चीज़ का मोल-भाव है और यह जानना ज़रूरी है कि क्या यह कीमत किसी कस्टम समाधान को रोल आउट करने की मुश्किलों और मेहनत तीसरे पक्ष की लाइब्रेरी.