অব্যবহৃত কোড সরান

এই কোডল্যাবে, অব্যবহৃত এবং অপ্রয়োজনীয় নির্ভরতাগুলিকে সরিয়ে নিম্নলিখিত অ্যাপ্লিকেশনটির কর্মক্ষমতা উন্নত করুন।

অ্যাপের স্ক্রিনশট

পরিমাপ করা

অপ্টিমাইজেশান যোগ করার আগে একটি ওয়েবসাইট কতটা ভাল পারফর্ম করে তা প্রথমে পরিমাপ করা সর্বদা একটি ভাল ধারণা।

  • সাইটের পূর্বরূপ দেখতে, অ্যাপ দেখুন টিপুন। তারপর ফুলস্ক্রিন টিপুন পূর্ণ পর্দা .

এগিয়ে যান এবং আপনার প্রিয় বিড়ালছানা ক্লিক করুন! এই অ্যাপ্লিকেশনটিতে ফায়ারবেসের রিয়েলটাইম ডেটাবেস ব্যবহার করা হয় যার কারণে স্কোরটি রিয়েল-টাইমে আপডেট হয় এবং অ্যাপ্লিকেশনটি ব্যবহার করে অন্য প্রতিটি ব্যক্তির সাথে সিঙ্ক্রোনাইজ করা হয়। 🐈

  1. DevTools খুলতে `Control+Shift+J` (বা Mac এ `Command+Option+J`) টিপুন।
  2. নেটওয়ার্ক ট্যাবে ক্লিক করুন।
  3. অক্ষম ক্যাশে চেকবক্স নির্বাচন করুন।
  4. অ্যাপটি পুনরায় লোড করুন।

992 KB এর আসল বান্ডেল সাইজ

এই সাধারণ অ্যাপ্লিকেশনটি লোড করার জন্য প্রায় 1 এমবি মূল্যের জাভাস্ক্রিপ্ট পাঠানো হচ্ছে!

DevTools-এ প্রজেক্টের সতর্কতা দেখুন।

  • কনসোল ট্যাবে ক্লিক করুন।
  • Filter ইনপুটের পাশে লেভেল ড্রপডাউনে Warnings সক্রিয় করা আছে তা নিশ্চিত করুন।

সতর্কতা ফিল্টার

  • প্রদর্শিত সতর্কতাটি একবার দেখুন।

কনসোল সতর্কতা

ফায়ারবেস, যেটি এই অ্যাপ্লিকেশনটিতে ব্যবহৃত লাইব্রেরিগুলির মধ্যে একটি, এটি একটি সতর্কতা প্রদান করে একটি ভাল সামারিটান হয়ে উঠছে যাতে ডেভেলপারদের জানানো হয় যে এটির সম্পূর্ণ প্যাকেজ আমদানি না করে শুধুমাত্র ব্যবহৃত উপাদানগুলিই আমদানি করা হয়৷ অন্য কথায়, এমন অব্যবহৃত লাইব্রেরি রয়েছে যা এই অ্যাপ্লিকেশনটিতে দ্রুত লোড করার জন্য সরানো যেতে পারে।

এমন উদাহরণও রয়েছে যখন একটি নির্দিষ্ট লাইব্রেরি ব্যবহার করা হয়, তবে যেখানে একটি সহজ বিকল্প হতে পারে। অপ্রয়োজনীয় লাইব্রেরি অপসারণের ধারণাটি পরে এই টিউটোরিয়ালে অন্বেষণ করা হয়েছে।

বান্ডিল বিশ্লেষণ

অ্যাপ্লিকেশনটিতে দুটি প্রধান নির্ভরতা রয়েছে:

  • ফায়ারবেস : একটি প্ল্যাটফর্ম যা iOS, Android বা ওয়েব অ্যাপ্লিকেশনগুলির জন্য বেশ কয়েকটি দরকারী পরিষেবা সরবরাহ করে। এখানে এর রিয়েলটাইম ডাটাবেস রিয়েল টাইমে প্রতিটি বিড়ালছানার তথ্য সংরক্ষণ এবং সিঙ্ক করতে ব্যবহৃত হয়।
  • Moment.js : একটি ইউটিলিটি লাইব্রেরি যা জাভাস্ক্রিপ্টে তারিখগুলি পরিচালনা করা সহজ করে তোলে। প্রতিটি বিড়ালছানার জন্ম তারিখ Firebase ডাটাবেসে সংরক্ষিত থাকে এবং moment সপ্তাহে তার বয়স গণনা করতে ব্যবহৃত হয়।

কিভাবে মাত্র দুটি নির্ভরতা প্রায় 1 MB এর একটি বান্ডিল আকারে অবদান রাখতে পারে? ঠিক আছে, কারণগুলির মধ্যে একটি হল যে কোনও নির্ভরতার পরিবর্তে তাদের নিজস্ব নির্ভরতা থাকতে পারে, তাই নির্ভরতা "বৃক্ষ" এর প্রতিটি গভীরতা/শাখা বিবেচনা করা হলে কেবল দুটির চেয়ে অনেক বেশি রয়েছে। অনেক নির্ভরতা অন্তর্ভুক্ত করা থাকলে একটি অ্যাপ্লিকেশন তুলনামূলকভাবে দ্রুত বড় হওয়া সহজ।

কি ঘটছে তার একটি ভাল ধারণা পেতে বান্ডলার বিশ্লেষণ করুন. বিভিন্ন সম্প্রদায়-নির্মিত সরঞ্জাম রয়েছে যা এটি করতে সহায়তা করতে পারে, যেমন webpack-bundle-analyzer

এই টুলের প্যাকেজটি ইতিমধ্যেই একটি devDependency হিসেবে অ্যাপে অন্তর্ভুক্ত করা হয়েছে।

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

এর মানে হল যে এটি সরাসরি ওয়েবপ্যাক কনফিগারেশন ফাইলে ব্যবহার করা যেতে পারে। webpack.config.js এর একেবারে শুরুতে এটি আমদানি করুন:

const path = require("path");

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

এখন এটি plugins অ্যারের মধ্যে ফাইলের একেবারে শেষে প্লাগইন হিসাবে যুক্ত করুন:

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

যখন অ্যাপ্লিকেশনটি পুনরায় লোড হয়, তখন আপনি অ্যাপটির পরিবর্তে পুরো বান্ডিলের একটি ভিজ্যুয়ালাইজেশন দেখতে পাবেন।

ওয়েবপ্যাক বান্ডেল বিশ্লেষক

কিছু বিড়ালছানা দেখার মতো সুন্দর নয় 🐱, তবে অবিশ্বাস্যভাবে সহায়ক। যেকোনো প্যাকেজের উপর ঘোরাফেরা করলে এর আকার তিনটি ভিন্ন উপায়ে উপস্থাপিত হয়:

পরিসংখ্যান আকার যেকোন মিনিফেকশন বা কম্প্রেশনের আগে সাইজ।
পার্স করা আকার কম্পাইল হওয়ার পর বান্ডেলের মধ্যে প্রকৃত প্যাকেজের আকার। ওয়েবপ্যাকের সংস্করণ 4 (যা এই অ্যাপ্লিকেশনটিতে ব্যবহৃত হয়) স্বয়ংক্রিয়ভাবে সংকলিত ফাইলগুলিকে ছোট করে যার কারণে এটি স্ট্যাট আকারের চেয়ে ছোট।
জিজিপড আকার জিজিপ এনকোডিং দিয়ে সংকুচিত হওয়ার পরে প্যাকেজের আকার। এই বিষয় একটি পৃথক নির্দেশিকা কভার করা হয়.

ওয়েবপ্যাক-বান্ডেল-বিশ্লেষক টুলের সাহায্যে, অব্যবহৃত বা অপ্রয়োজনীয় প্যাকেজগুলি সনাক্ত করা সহজ যা বান্ডেলের একটি বড় শতাংশ তৈরি করে।

অব্যবহৃত প্যাকেজ অপসারণ

ভিজ্যুয়ালাইজেশন দেখায় যে 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;

অ্যাপ্লিকেশন এখন স্বাভাবিকভাবে লোড করা উচিত. Firebase আমদানি আপডেট করতে src/index.js পরিবর্তন করুন।

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

এখন অ্যাপটি রিলোড হলে, DevTools সতর্কতা দেখায় না। DevTools নেটওয়ার্ক প্যানেল খোলার ফলে বান্ডেল আকারে একটি চমৎকার হ্রাসও দেখা যায়:

বান্ডেলের আকার 480 KB এ কমে গেছে

বান্ডিল আকারের অর্ধেকেরও বেশি সরানো হয়েছে। Firebase অনেকগুলি বিভিন্ন পরিষেবা প্রদান করে এবং ডেভেলপারদের শুধুমাত্র সেইগুলি অন্তর্ভুক্ত করার বিকল্প দেয় যা আসলে প্রয়োজন। এই অ্যাপ্লিকেশনটিতে, শুধুমাত্র firebase/database সমস্ত ডেটা সঞ্চয় এবং সিঙ্ক করতে ব্যবহৃত হয়েছিল। firebase/app আমদানি, যা প্রতিটি বিভিন্ন পরিষেবার জন্য API পৃষ্ঠ সেট আপ করে, সর্বদা প্রয়োজন হয়।

অন্যান্য অনেক জনপ্রিয় লাইব্রেরি, যেমন lodash , এছাড়াও ডেভেলপারদের তাদের প্যাকেজের বিভিন্ন অংশ বেছে বেছে আমদানি করতে দেয়। বেশি কাজ না করে, শুধুমাত্র যা ব্যবহার করা হচ্ছে তা অন্তর্ভুক্ত করার জন্য একটি অ্যাপ্লিকেশনে লাইব্রেরি আমদানি আপডেট করার ফলে উল্লেখযোগ্য কর্মক্ষমতা উন্নতি হতে পারে।

যদিও বান্ডেলের আকার বেশ খানিকটা কমানো হয়েছে, তবুও আরও কাজ বাকি আছে! 😈

অপ্রয়োজনীয় প্যাকেজ অপসারণ

ফায়ারবেসের বিপরীতে, moment লাইব্রেরির অংশগুলি আমদানি করা এত সহজে করা যায় না, তবে এটি সম্পূর্ণরূপে সরানো যেতে পারে?

প্রতিটি সুন্দর বিড়ালছানার জন্মদিন ফায়ারবেস ডাটাবেসে ইউনিক্স ফরম্যাটে (মিলিসেকেন্ড) সংরক্ষণ করা হয়।

জন্মতারিখ ইউনিক্স ফরম্যাটে সংরক্ষিত

এটি একটি নির্দিষ্ট তারিখ এবং সময়ের একটি টাইমস্ট্যাম্প যা 1 জানুয়ারী, 1970 00:00 UTC থেকে অতিবাহিত হওয়া মিলিসেকেন্ডের সংখ্যা দ্বারা প্রতিনিধিত্ব করে৷ যদি বর্তমান তারিখ এবং সময় একই বিন্যাসে গণনা করা যায়, তবে সপ্তাহে প্রতিটি বিড়ালছানার বয়স খুঁজে বের করার জন্য একটি ছোট ফাংশন তৈরি করা যেতে পারে।

বরাবরের মতো, আপনি এখানে অনুসরণ করার মতো অনুলিপি এবং আটকানোর চেষ্টা করবেন না। src/index.js এ আমদানি থেকে moment মুছে দিয়ে শুরু করুন।

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

একটি ফায়ারবেস ইভেন্ট লিসেনার আছে যা আমাদের ডাটাবেসের মান পরিবর্তনগুলি পরিচালনা করে:

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 KB এ কমে গেছে

আমাদের বান্ডিলের আকার আবার অর্ধেকেরও বেশি কমে গেল!

উপসংহার

এই কোডল্যাবের সাথে, আপনার একটি শালীন ধারণা থাকা উচিত যে কীভাবে একটি নির্দিষ্ট বান্ডেল বিশ্লেষণ করতে হয় এবং কেন এটি অব্যবহৃত বা অপ্রয়োজনীয় প্যাকেজগুলি সরাতে এত কার্যকর হতে পারে। আপনি এই কৌশলটি দিয়ে একটি অ্যাপ্লিকেশন অপ্টিমাইজ করা শুরু করার আগে, এটি জানা গুরুত্বপূর্ণ যে এটি বড় অ্যাপ্লিকেশনগুলিতে উল্লেখযোগ্যভাবে আরও জটিল হতে পারে

অব্যবহৃত লাইব্রেরিগুলি সরানোর বিষয়ে, একটি বান্ডেলের কোন অংশগুলি ব্যবহার করা হচ্ছে এবং কোন অংশগুলি নয় তা খুঁজে বের করার চেষ্টা করুন। একটি রহস্যময় প্যাকেজের জন্য যা মনে হচ্ছে এটি কোথাও ব্যবহার করা হচ্ছে না, এক ধাপ পিছিয়ে নিন এবং কোন শীর্ষ-স্তরের নির্ভরতাগুলির প্রয়োজন হতে পারে তা পরীক্ষা করুন। তাদের একে অপরের থেকে আলাদা করার উপায় খুঁজে বের করার চেষ্টা করুন।

যখন এটি অপ্রয়োজনীয় লাইব্রেরিগুলি সরানোর ক্ষেত্রে আসে, তখন জিনিসগুলি একটু বেশি জটিল হতে পারে। আপনার দলের সাথে ঘনিষ্ঠভাবে কাজ করা এবং কোডবেসের অংশগুলিকে সহজ করার সম্ভাবনা আছে কিনা তা দেখা গুরুত্বপূর্ণ। এই অ্যাপ্লিকেশানে moment সরানো মনে হতে পারে যে এটি প্রতিবার করা সঠিক জিনিস হবে, তবে যদি এমন সময় অঞ্চল এবং বিভিন্ন লোকেলগুলি পরিচালনা করা প্রয়োজন হয় তবে কী হবে? অথবা যদি আরো জটিল তারিখ ম্যানিপুলেশন ছিল? তারিখ/সময় ম্যানিপুলেট এবং পার্স করার সময় জিনিসগুলি খুব জটিল হতে পারে এবং moment এবং date-fns এর মতো লাইব্রেরিগুলি এটিকে উল্লেখযোগ্যভাবে সহজ করে তোলে।

সবকিছুই একটি ট্রেডঅফ, এবং এটি একটি তৃতীয় পক্ষের লাইব্রেরির উপর নির্ভর না করে একটি কাস্টম সমাধান রোল আউট করার জটিলতা এবং প্রচেষ্টার জন্য মূল্যবান কিনা তা নির্ধারণ করা গুরুত্বপূর্ণ।