Gzip দিয়ে নেটওয়ার্ক পেলোডগুলিকে ছোট করুন এবং সংকুচিত করুন

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

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

পরিমাপ করা

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

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

এই অ্যাপটি, যা "অব্যবহৃত কোড সরান" কোডল্যাবেও আচ্ছাদিত ছিল, আপনাকে আপনার প্রিয় বিড়ালছানাকে ভোট দিতে দেয়৷ 🐈

এখন এই অ্যাপ্লিকেশনটি কত বড় তা একবার দেখুন:

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

নেটওয়ার্ক প্যানেলে আসল বান্ডিলের আকার

যদিও এই বান্ডেলের আকার কমাতে "অব্যবহৃত কোড সরান" কোডল্যাবে অনেক অগ্রগতি হয়েছে, 225 KB এখনও বেশ বড়।

মিনিফিকেশন

নিম্নলিখিত কোড ব্লক বিবেচনা করুন.

function soNice() {
  let counter = 0;

  while (counter < 100) {
    console.log('nice');
    counter++;
  }
}

যদি এই ফাংশনটি নিজের একটি ফাইলে সংরক্ষণ করা হয়, ফাইলের আকার প্রায় 112 বি (বাইট)।

যদি সমস্ত হোয়াইটস্পেস মুছে ফেলা হয়, ফলস্বরূপ কোডটি এইরকম দেখায়:

function soNice(){let counter=0;while(counter<100){console.log("nice");counter++;}}

ফাইলের আকার এখন প্রায় 83 B হবে। পরিবর্তনশীল নামের দৈর্ঘ্য কমিয়ে এবং কিছু এক্সপ্রেশন পরিবর্তন করে যদি এটি আরও বিভ্রান্ত হয়ে যায়, তাহলে চূড়ান্ত কোডটি এভাবে দেখা যেতে পারে:

function soNice(){for(let i=0;i<100;)console.log("nice"),i++}

ফাইলের আকার এখন 62 বি এ পৌঁছেছে।

প্রতিটি পদক্ষেপের সাথে, কোডটি পড়া কঠিন হয়ে উঠছে। যাইহোক, ব্রাউজারের জাভাস্ক্রিপ্ট ইঞ্জিন এগুলির প্রত্যেকটিকে একইভাবে ব্যাখ্যা করে। এই পদ্ধতিতে কোড অস্পষ্ট করার সুবিধাটি ছোট ফাইলের আকার অর্জনে সহায়তা করতে পারে। 112 B এর সাথে শুরু করার মতো খুব বেশি কিছু ছিল না, তবে এখনও আকারে 50% হ্রাস ছিল!

এই অ্যাপ্লিকেশনে, ওয়েবপ্যাক সংস্করণ 4 একটি মডিউল বান্ডলার হিসাবে ব্যবহৃত হয়। নির্দিষ্ট সংস্করণটি package.json এ দেখা যাবে।

"devDependencies": {
  //...
  "webpack": "^4.16.4",
  //...
}

সংস্করণ 4 ইতিমধ্যে উত্পাদন মোডের সময় ডিফল্টরূপে বান্ডেলটিকে ছোট করে। এটি TerserWebpackPlugin ব্যবহার করে Terser- এর জন্য একটি প্লাগইন। Terser হল একটি জনপ্রিয় টুল যা জাভাস্ক্রিপ্ট কোড সংকুচিত করতে ব্যবহৃত হয়।

মিনিফাইড কোডটি কেমন তা একটি ধারণা পেতে, এগিয়ে যান এবং DevTools নেটওয়ার্ক প্যানেলে থাকাকালীন main.bundle.js এ ক্লিক করুন৷ এখন রেসপন্স ট্যাবে ক্লিক করুন।

সংক্ষিপ্ত প্রতিক্রিয়া

কোডটি তার চূড়ান্ত আকারে, ছোট এবং ম্যাংগলড, প্রতিক্রিয়া বডিতে দেখানো হয়েছে। বান্ডেলটি ছোট না হলে কত বড় হতে পারে তা জানতে, webpack.config.js খুলুন এবং mode কনফিগারেশন আপডেট করুন।

module.exports = {
  mode: 'production',
  mode: 'none',
  //...

অ্যাপ্লিকেশানটি পুনরায় লোড করুন এবং DevTools নেটওয়ার্ক প্যানেলের মাধ্যমে আবার বান্ডেলের আকার দেখুন

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

যে একটি চমত্কার বড় পার্থক্য! 😅

চালিয়ে যাওয়ার আগে এখানে পরিবর্তনগুলি প্রত্যাবর্তন নিশ্চিত করুন৷

module.exports = {
  mode: 'production',
  mode: 'none',
  //...

আপনার অ্যাপ্লিকেশনে কোড ছোট করার একটি প্রক্রিয়া অন্তর্ভুক্ত করা আপনি যে সরঞ্জামগুলি ব্যবহার করেন তার উপর নির্ভর করে:

  • যদি ওয়েবপ্যাক v4 বা তার বেশি ব্যবহার করা হয়, তাহলে প্রোডাকশন মোডে ডিফল্টরূপে কোড ছোট হওয়ার কারণে কোনো অতিরিক্ত কাজ করার দরকার নেই। 👍
  • যদি ওয়েবপ্যাকের একটি পুরানো সংস্করণ ব্যবহার করা হয়, তাহলে ওয়েবপ্যাক তৈরির প্রক্রিয়াতে TerserWebpackPlugin ইনস্টল করুন এবং অন্তর্ভুক্ত করুন। ডকুমেন্টেশন বিস্তারিতভাবে এটি ব্যাখ্যা করে।
  • অন্যান্য মিনিফিকেশন প্লাগইনগুলিও বিদ্যমান এবং এর পরিবর্তে ব্যবহার করা যেতে পারে, যেমন BabelMinifyWebpackPlugin এবং ClosureCompilerPlugin
  • যদি একটি মডিউল বান্ডলার একেবারেই ব্যবহার না করা হয়, একটি CLI টুল হিসাবে Terser ব্যবহার করুন বা এটি সরাসরি নির্ভরতা হিসাবে অন্তর্ভুক্ত করুন।

সঙ্কোচন

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

কম্প্রেশন বলতে সাধারণত কোড বোঝায় যা ডেটা কম্প্রেশন অ্যালগরিদম ব্যবহার করে পরিবর্তন করা হয়েছে। মিনিফিকেশনের বিপরীতে যা পুরোপুরি বৈধ কোড প্রদান করে, সংকুচিত কোড ব্যবহার করার আগে ডিকম্প্রেস করা প্রয়োজন।

প্রতিটি HTTP অনুরোধ এবং প্রতিক্রিয়ার সাথে, ব্রাউজার এবং ওয়েব সার্ভারগুলি আনা বা প্রাপ্ত করা সম্পদ সম্পর্কে অতিরিক্ত তথ্য অন্তর্ভুক্ত করতে শিরোনাম যোগ করতে পারে। এটি DevTools নেটওয়ার্ক প্যানেলের মধ্যে Headers ট্যাবে দেখা যাবে যেখানে তিনটি প্রকার দেখানো হয়েছে:

  • সাধারণ সমগ্র অনুরোধ-প্রতিক্রিয়া ইন্টারঅ্যাকশনের সাথে প্রাসঙ্গিক সাধারণ শিরোনামগুলিকে প্রতিনিধিত্ব করে।
  • প্রতিক্রিয়া শিরোনাম সার্ভার থেকে প্রকৃত প্রতিক্রিয়ার জন্য নির্দিষ্ট শিরোনামগুলির একটি তালিকা দেখায়।
  • রিকোয়েস্ট হেডার ক্লায়েন্টের অনুরোধের সাথে সংযুক্ত হেডারের একটি তালিকা দেখায়।

Request Headers accept-encoding শিরোনামটি দেখুন।

এনকোডিং হেডার গ্রহণ করুন

কোন বিষয়বস্তু এনকোডিং ফরম্যাট বা কম্প্রেশন অ্যালগরিদম সমর্থন করে তা নির্দিষ্ট করতে ব্রাউজার accept-encoding ব্যবহার করে। সেখানে অনেক টেক্সট-কম্প্রেশন অ্যালগরিদম আছে, কিন্তু HTTP নেটওয়ার্ক অনুরোধের কম্প্রেশন (এবং ডিকম্প্রেশন) জন্য এখানে শুধুমাত্র তিনটি সমর্থিত:

  • Gzip ( gzip ): সার্ভার এবং ক্লায়েন্ট ইন্টারঅ্যাকশনের জন্য সর্বাধিক ব্যবহৃত কম্প্রেশন বিন্যাস। এটি ডিফ্লেট অ্যালগরিদমের উপরে তৈরি করে এবং সমস্ত বর্তমান ব্রাউজারে সমর্থিত।
  • Deflate ( deflate ): সাধারণত ব্যবহৃত হয় না।
  • ব্রটলি ( br ): একটি নতুন কম্প্রেশন অ্যালগরিদম যার লক্ষ্য কম্প্রেশন অনুপাতকে আরও উন্নত করা, যার ফলে আরও দ্রুত পৃষ্ঠা লোড হতে পারে। এটি বেশিরভাগ ব্রাউজারের সর্বশেষ সংস্করণে সমর্থিত।

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

গতিশীল কম্প্রেশন

ডাইনামিক কম্প্রেশনের মধ্যে ফ্লাইতে থাকা সম্পদগুলিকে সংকুচিত করা জড়িত কারণ সেগুলি ব্রাউজার দ্বারা অনুরোধ করা হয়।

পেশাদার

  • সম্পদের সংরক্ষিত সংকুচিত সংস্করণ তৈরি এবং আপডেট করার প্রয়োজন নেই।
  • কম্প্রেসিং অন-দ্য-ফ্লাই বিশেষত গতিশীলভাবে তৈরি করা ওয়েব পৃষ্ঠাগুলির জন্য ভাল কাজ করে।

কনস

  • ভাল কম্প্রেশন অনুপাত অর্জনের জন্য উচ্চ স্তরে ফাইলগুলিকে সংকুচিত করতে আরও বেশি সময় লাগে। এটি একটি পারফরম্যান্স হিট হতে পারে কারণ ব্যবহারকারীরা সার্ভার দ্বারা পাঠানোর আগে সম্পদগুলি সংকুচিত করার জন্য অপেক্ষা করে।

নোড/এক্সপ্রেসের সাথে ডায়নামিক কম্প্রেশন

server.js ফাইলটি নোড সার্ভার সেট আপ করার জন্য দায়ী যা অ্যাপ্লিকেশনটি হোস্ট করে।

const express = require('express');

const app = express();

app.use(express.static('public'));

const listener = app.listen(process.env.PORT, function() {
  console.log('Your app is listening on port ' + listener.address().port);
});

বর্তমানে যা করে তা হল express ইমপোর্ট করা এবং express.static মিডলওয়্যার ব্যবহার করে public/ ডিরেক্টরির সমস্ত স্ট্যাটিক এইচটিএমএল, জেএস এবং সিএসএস ফাইল লোড করা (এবং সেই ফাইলগুলি প্রতিটি বিল্ডের সাথে ওয়েবপ্যাক দ্বারা তৈরি করা হয়)।

প্রতিবার অনুরোধ করা হলে সমস্ত সম্পদ সংকুচিত হয়েছে তা নিশ্চিত করতে, কম্প্রেশন মিডলওয়্যার লাইব্রেরি ব্যবহার করা যেতে পারে। package.jsondevDependency হিসেবে এটি যোগ করে শুরু করুন:

"devDependencies": {
  //...
  "compression": "^1.7.3"
},

এবং এটি সার্ভার ফাইল, server.js এ আমদানি করুন :

const express = require('express');
const compression = require('compression');

এবং express.static মাউন্ট করার আগে এটি একটি মিডলওয়্যার হিসাবে যোগ করুন:

//...

const app = express();

app.use(compression());

app.use(express.static('public'));

//...

এখন অ্যাপটি পুনরায় লোড করুন এবং নেটওয়ার্ক প্যানেলে বান্ডেলের আকারটি দেখুন।

গতিশীল কম্প্রেশন সঙ্গে বান্ডিল আকার

225 KB থেকে 61.6 KB! Response Headers এখন, একটি content-encoding হেডার দেখায় যে সার্ভার এই ফাইলটি gzip দিয়ে এনকোড করে পাঠাচ্ছে।

কন্টেন্ট এনকোডিং হেডার

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

স্ট্যাটিক কম্প্রেশনের পিছনে ধারণা হল সম্পদগুলিকে সংকুচিত করা এবং সময়ের আগে সংরক্ষণ করা।

পেশাদার

  • উচ্চ কম্প্রেশন স্তরের কারণে বিলম্বিততা আর উদ্বেগের বিষয় নয়। ফাইলগুলিকে সংকুচিত করার জন্য ফ্লাইতে কিছু করার দরকার নেই কারণ সেগুলি এখন সরাসরি আনা যায়৷

কনস

  • সম্পদ প্রতিটি বিল্ড সঙ্গে সংকুচিত করা প্রয়োজন. উচ্চ কম্প্রেশন মাত্রা ব্যবহার করা হলে নির্মাণের সময় উল্লেখযোগ্যভাবে বৃদ্ধি পেতে পারে।

নোড/এক্সপ্রেস এবং ওয়েবপ্যাকের সাথে স্ট্যাটিক কম্প্রেশন

যেহেতু স্ট্যাটিক কম্প্রেশনে ফাইলগুলিকে সময়ের আগে সংকুচিত করা জড়িত, তাই ওয়েবপ্যাক সেটিংস বিল্ড স্টেপের অংশ হিসাবে সম্পদগুলিকে সংকুচিত করতে পরিবর্তন করা যেতে পারে। এর জন্য CompressionPlugin ব্যবহার করা যেতে পারে।

package.jsondevDependency হিসেবে এটি যোগ করে শুরু করুন:

"devDependencies": {
  //...
  "compression-webpack-plugin": "^1.1.11"
},

অন্য যেকোনো ওয়েবপ্যাক প্লাগইনের মতো, এটিকে কনফিগারেশন ফাইল, webpack.config.js:

const path = require("path");

//...

const CompressionPlugin = require("compression-webpack-plugin");

এবং plugins অ্যারের মধ্যে এটি অন্তর্ভুক্ত করুন:

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

ডিফল্টরূপে, প্লাগইনটি gzip ব্যবহার করে বিল্ড ফাইলগুলিকে সংকুচিত করে। একটি ভিন্ন অ্যালগরিদম ব্যবহার করতে বা নির্দিষ্ট ফাইলগুলি অন্তর্ভুক্ত/বাদ দেওয়ার বিকল্পগুলি কীভাবে যোগ করতে হয় তা শিখতে ডকুমেন্টেশনটি দেখুন।

যখন অ্যাপটি পুনরায় লোড হয় এবং পুনর্নির্মাণ হয়, তখন মূল বান্ডেলের একটি সংকুচিত সংস্করণ তৈরি হয়। নোড সার্ভার দ্বারা পরিবেশিত চূড়ান্ত public/ ডিরেক্টরির ভিতরে কী রয়েছে তা দেখতে গ্লিচ কনসোলটি খুলুন।

  • টুল বাটনে ক্লিক করুন।
  • কনসোল বোতামে ক্লিক করুন।
  • কনসোলে, public ডিরেক্টরিতে পরিবর্তন করতে নিম্নলিখিত কমান্ডগুলি চালান এবং এর সমস্ত ফাইল দেখুন:
cd public
ls

পাবলিক ডিরেক্টরির মধ্যে চূড়ান্ত আউটপুট ফাইল

বান্ডেলের জিজিপড সংস্করণ, main.bundle.js.gz , এখন এখানেও সংরক্ষণ করা হয়েছে। CompressionPlugin এছাড়াও index.html ডিফল্টভাবে সংকুচিত করে।

পরবর্তী যে জিনিসটি করা দরকার তা হল সার্ভারকে এই জিজিপড ফাইলগুলি পাঠাতে বলা যখনই তাদের আসল JS সংস্করণগুলির অনুরোধ করা হচ্ছে। express.static দিয়ে ফাইলগুলি পরিবেশন করার আগে server.js এ একটি নতুন রুট সংজ্ঞায়িত করে এটি করা যেতে পারে।

const express = require('express');
const app = express();

app.get('*.js', (req, res, next) => {
  req.url = req.url + '.gz';
  res.set('Content-Encoding', 'gzip');
  next();
});

app.use(express.static('public'));

//...

একটি নির্দিষ্ট এন্ডপয়েন্টের জন্য একটি GET অনুরোধে কীভাবে প্রতিক্রিয়া জানাতে হয় তা সার্ভারকে জানাতে app.get ব্যবহার করা হয়। একটি কলব্যাক ফাংশন তারপর এই অনুরোধ পরিচালনা কিভাবে সংজ্ঞায়িত করতে ব্যবহার করা হয়. রুট এই মত কাজ করে:

  • প্রথম আর্গুমেন্ট হিসাবে '*.js' নির্দিষ্ট করার মানে হল যে এটি প্রতিটি এন্ডপয়েন্টের জন্য কাজ করে যা একটি JS ফাইল আনার জন্য ফায়ার করা হয়।
  • কলব্যাকের মধ্যে, অনুরোধের URL-এর সাথে .gz সংযুক্ত করা হয়েছে এবং Content-Encoding প্রতিক্রিয়া শিরোনামটি gzip এ সেট করা হয়েছে।
  • অবশেষে, next() নিশ্চিত করে যে ক্রমটি পরবর্তী যে কোনো কলব্যাকের সাথে চলতে থাকে।

অ্যাপটি পুনরায় লোড হয়ে গেলে, Network প্যানেলটি আরও একবার দেখুন।

স্ট্যাটিক কম্প্রেশন সঙ্গে বান্ডিল আকার হ্রাস

ঠিক আগের মত, বান্ডিল আকার একটি উল্লেখযোগ্য হ্রাস!

উপসংহার

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