Brotli की मदद से, नेटवर्क पेलोड को छोटा और कंप्रेस करें

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

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

दूरी मापें

ऑप्टिमाइज़ेशन जोड़ने से पहले, ऐप्लिकेशन की मौजूदा स्थिति का विश्लेषण कर लेना हमेशा एक अच्छा तरीका होता है.

  1. प्रोजेक्ट में बदलाव करने के लिए, बदलाव करने के लिए रीमिक्स करें पर क्लिक करें.
  2. साइट की झलक देखने के लिए, ऐप्लिकेशन देखें दबाएं. इसके बाद, फ़ुलस्क्रीन फ़ुलस्क्रीन दबाएं.

पिछले नेटवर्क पेलोड को छोटा और कंप्रेस करने में, हमने main.js के साइज़ को 225 केबी से कम करके 61.6 केबी कर दिया था. इस कोडलैब में, आपको पता चलेगा कि Brotli कंप्रेस करने की सुविधा की मदद से, इस बंडल के साइज़ को और कम कैसे किया जा सकता है.

ब्रॉटली कंप्रेशन

Brotli एक नया कंप्रेशन एल्गोरिदम है. यह gzip के मुकाबले और भी बेहतर टेक्स्ट कंप्रेशन नतीजे दे सकता है. CertSimple के मुताबिक, Brotli की परफ़ॉर्मेंस:

  • JavaScript के लिए, gzip से 14% कम
  • एचटीएमएल के लिए gzip से 21% कम
  • सीएसएस के लिए, gzip की तुलना में 17% कम

Brotli का इस्तेमाल करने के लिए, यह ज़रूरी है कि आपके सर्वर पर एचटीटीपीएस काम करता हो. Brotli, ज़्यादातर ब्राउज़र के सबसे नए वर्शन में काम करता है. Brotli के साथ काम करने वाले ब्राउज़र में Accept-Encoding हेडर में br शामिल होगा:

Accept-Encoding: gzip, deflate, br

Chrome डेवलपर टूल नेटवर्क टैब (Command+Option+I या Ctrl+Alt+I) में जाकर, Content-Encoding फ़ील्ड पर जाकर यह तय किया जा सकता है कि किस कंप्रेशन एल्गोरिदम का इस्तेमाल किया जाए:

नेटवर्क पैनल

ब्रॉटली को चालू करना

डाइनैमिक कंप्रेशन

डाइनैमिक कंप्रेशन में, ब्राउज़र के अनुरोध पर ऐसेट को तुरंत कंप्रेस किया जाता है.

फ़ायदे

  • एसेट के कंप्रेस किए गए वर्शन बनाने और अपडेट करने की ज़रूरत नहीं है.
  • तुरंत कंप्रेस करने की सुविधा, डाइनैमिक रूप से जनरेट होने वाले वेब पेजों के लिए कारगर साबित होती है.

नुकसान

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

नोड/एक्सप्रेस के साथ डाइनैमिक कंप्रेशन

server.js फ़ाइल की मदद से, ऐप्लिकेशन को होस्ट करने वाला नोड सर्वर सेट अप किया जाता है.

var express = require('express');

var app = express();

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

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

फ़िलहाल, ये सभी काम express को इंपोर्ट करते हैं और public/directory में सभी स्टैटिक एचटीएमएल, JS, और सीएसएस फ़ाइलों को लोड करने के लिए express.static मिडलवेयर का इस्तेमाल करते हैं (और उन फ़ाइलों को हर बिल्ड के साथ webpack के ज़रिए बनाया जाता है).

यह पक्का करने के लिए कि हर बार अनुरोध किए जाने पर सभी ऐसेट को ब्रोटली का इस्तेमाल करके कंप्रेस किया जाए, shrink-ray मॉड्यूल का इस्तेमाल किया जा सकता है. इसे package.json में devDependency के तौर पर जोड़कर शुरू करें:

"devDependencies": {
  //...
  "shrink-ray": "^0.1.3"
},

और इसे सर्वर फ़ाइल, server.js में इंपोर्ट करें:

var express = require('express');
var shrinkRay = require('shrink-ray');

express.static को माउंट करने से पहले, इसे मिडलवेयर के तौर पर जोड़ें:

//...
var app = express();

// compress all requests
app.use(shrinkRay());

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

अब ऐप्लिकेशन को फिर से लोड करें और नेटवर्क पैनल में बंडल के साइज़ को देखें:

डाइनैमिक Brotli कंप्रेशन के साथ बंडल का साइज़

अब Content-Encoding हेडर में यह देखा जा सकता है कि bz की brotli लागू की गई है. main.bundle.js, 225 केबी से घटकर 53.1 केबी हो गया है! यह gzip (61.6 केबी) की तुलना में ~14% कम है.

स्टैटिक कंप्रेशन

स्टैटिक कंप्रेशन के पीछे का आइडिया यह है कि एसेट को समय से पहले कंप्रेस करके सेव कर लिया जाए.

फ़ायदे

  • उच्च संपीड़न स्तर के कारण लेटेंसी अब चिंता का विषय नहीं है. फ़ाइलों को कंप्रेस करने के लिए तुरंत कुछ करने की ज़रूरत नहीं होती, क्योंकि अब उन्हें सीधे तौर पर फ़ेच किया जा सकता है.

नुकसान

  • ऐसेट को हर बिल्ड के साथ कंप्रेस करना ज़रूरी है. ज़्यादा कंप्रेशन लेवल का इस्तेमाल करने पर, बिल्ड टाइम काफ़ी बढ़ सकता है.

नोड/एक्सप्रेस और वेबपैक के साथ स्टैटिक कंप्रेशन

स्टैटिक कंप्रेशन में, समय से पहले फ़ाइलों को कंप्रेस करना शामिल होता है. इसलिए, बिल्ड चरण के हिस्से के तौर पर Webpack की सेटिंग में बदलाव करके ऐसेट को कंप्रेस किया जा सकता है. इसके लिए, brotli-webpack-plugin का इस्तेमाल किया जा सकता है.

इसे package.json में devDependency के तौर पर जोड़कर शुरू करें:

"devDependencies": {
  //...
 "brotli-webpack-plugin": "^1.1.0"
},

किसी भी दूसरे Webpack प्लगिन की तरह, इसे कॉन्फ़िगरेशन फ़ाइल में इंपोर्ट करें, webpack.config.js:

var path = require("path");

//...
var BrotliPlugin = require('brotli-webpack-plugin');

और उसे प्लगिन अरे में शामिल करें:

module.exports = {
  // ...
  plugins: [
    // ...
    new BrotliPlugin({
      asset: '[file].br',
      test: /\.(js)$/
    })
  ]
},

प्लगिन कलेक्शन में इन आर्ग्युमेंट का इस्तेमाल किया जाता है:

  • asset: टारगेट ऐसेट का नाम.
  • [file] को ओरिजनल ऐसेट फ़ाइल के नाम से बदल दिया गया है.
  • test: इस रेगुलर एक्सप्रेशन से मैच करने वाली सभी ऐसेट (यानी, .js पर खत्म होने वाली JavaScript ऐसेट) प्रोसेस की जाती हैं.

उदाहरण के लिए, main.js का नाम बदलकर main.js.br कर दिया जाएगा.

जब ऐप्लिकेशन फिर से लोड और फिर से बनता है, तो अब मुख्य बंडल का कंप्रेस किया गया वर्शन बन जाता है. नोड सर्वर से दी जाने वाली फ़ाइनल public/ डायरेक्ट्री में क्या-क्या है, यह देखने के लिए Glitch Console खोलें.

  1. टूल बटन पर क्लिक करें.
  2. कंसोल बटन पर क्लिक करें.
  3. कंसोल में, public डायरेक्ट्री में बदलने और इसकी सभी फ़ाइलें देखने के लिए, इन निर्देशों का पालन करें:
cd public
ls -lh
बंडल का साइज़, स्टैटिक Brotli कंप्रेशन के साथ

बंडल का ब्रॉटली कंप्रेस किया गया वर्शन, main.bundle.js.br अब यहां भी सेव किया गया है. इसका साइज़, main.bundle.js के मुकाबले करीब 76% कम (225 केबी बनाम 53 केबी) है.

इसके बाद, जब भी उनके मूल JS वर्शन का अनुरोध किया जाए, तब सर्वर को इन ब्रॉटली-कंप्रेस की गई फ़ाइलों को भेजने के लिए कहें. express.static के साथ फ़ाइलें दिखाने से पहले, server.js में एक नया रूट तय करके ऐसा किया जा सकता है.

var express = require('express');

var app = express();

app.get('*.js', (req, res, next) => {
  req.url = req.url + '.br';
  res.set('Content-Encoding', 'br');
  res.set('Content-Type', 'application/javascript; charset=UTF-8');
  next();
});

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

app.get का इस्तेमाल करके, सर्वर को यह बताया जाता है कि किसी खास एंडपॉइंट के लिए, GET के अनुरोध का जवाब कैसे दिया जाए. इसके बाद, कॉलबैक फ़ंक्शन का इस्तेमाल यह तय करने के लिए किया जाता है कि इस अनुरोध को कैसे मैनेज करना है. रास्ता इस तरह से काम करता है:

  • '*.js' को पहला आर्ग्युमेंट बनाने का मतलब है कि यह हर उस एंडपॉइंट के लिए काम करता है जिसे JS फ़ाइल फ़ेच करने के लिए फ़ायर किया जाता है.
  • कॉलबैक में, .br, अनुरोध के यूआरएल से जुड़ा होता है और Content-Encoding रिस्पॉन्स हेडर, br पर सेट होता है.
  • MIME टाइप के बारे में बताने के लिए, Content-Type हेडर को application/javascript; charset=UTF-8 पर सेट किया गया है.
  • आखिर में, next() यह पक्का करता है कि क्रम हर उस कॉलबैक पर जारी रहे जो आगे हो सकता है.

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

var express = require('express');

var app = express();

app.get('*.js', (req, res, next) => {
  if (req.header('Accept-Encoding').includes('br')) {
    req.url = req.url + '.br';
    console.log(req.header('Accept-Encoding'));
    res.set('Content-Encoding', 'br');
    res.set('Content-Type', 'application/javascript; charset=UTF-8');
  }
  next();
});

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

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

बंडल का साइज़ 53.1 केबी (225 केबी से)

हो गया! आपने अपनी ऐसेट को और कंप्रेस करने के लिए Brotli कंप्रेशन का इस्तेमाल किया है!

नतीजा

इस कोडलैब से पता चलता है कि brotli, आपके ऐप्लिकेशन के कुल साइज़ को और कम कैसे कर सकता है. जहां यह सुविधा काम करती है वहां gzip के मुकाबले brotli, ज़्यादा बेहतर कंप्रेशन एल्गोरिदम है.