यह कोडलैब, नेटवर्क पेलोड को छोटा और कंप्रेस करने वाले कोडलैब का एक्सटेंशन है. इसमें यह माना गया है कि आपको कंप्रेस करने के बुनियादी कॉन्सेप्ट के बारे में पता है. इस कोडलैब में, gzip
जैसे अन्य कंप्रेसन एल्गोरिदम की तुलना में, Brotli कंप्रेसन (br
) के बारे में बताया गया है. इससे, कंप्रेसन रेशियो और आपके ऐप्लिकेशन के कुल साइज़ को और कम किया जा सकता है.
मापें
ऑप्टिमाइज़ेशन जोड़ने से पहले, ऐप्लिकेशन की मौजूदा स्थिति का विश्लेषण करना हमेशा अच्छा होता है.
- प्रोजेक्ट में बदलाव करने के लिए, बदलाव करने के लिए रीमिक्स करें पर क्लिक करें.
- साइट की झलक देखने के लिए, ऐप्लिकेशन देखें दबाएं. इसके बाद, फ़ुलस्क्रीन दबाएं.
पिछले नेटवर्क पेलोड को छोटा और कंप्रेस करने के लिए कोडलैब में, हमने main.js
के साइज़ को 225 केबी से घटाकर 61.6 केबी कर दिया था. इस कोडलैब में, आपको पता चलेगा कि Brotli कंप्रेसन की मदद से, इस बंडल का साइज़ और भी कम कैसे किया जा सकता है.
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
फ़ील्ड का इस्तेमाल करके, यह पता लगाया जा सकता है कि किस कंप्रेसन एल्गोरिदम का इस्तेमाल किया गया है:
Brotli को चालू करने का तरीका
Brotli से एन्कोड किए गए संसाधनों को भेजने के लिए, वेब सर्वर को सेट अप करने का तरीका इस बात पर निर्भर करता है कि आपको उन्हें कैसे एन्कोड करना है. आपके पास अनुरोध के समय (डाइनैमिक) Brotli की मदद से, संसाधनों को डाइनैमिक तौर पर कंप्रेस करने या उन्हें पहले से कोड में बदलने का विकल्प होता है, ताकि उपयोगकर्ता के अनुरोध करने के समय वे पहले से ही कंप्रेस हो जाएं (स्टैटिक).
डाइनैमिक कंप्रेशन
डाइनैमिक कंप्रेसन में, ब्राउज़र से ऐसेट का अनुरोध मिलने पर, उन्हें फ़्लाइट पर कंप्रेस किया जाता है.
फ़ायदे
- ऐसेट के सेव किए गए और कंप्रेस किए गए वर्शन बनाने और अपडेट करने की ज़रूरत नहीं है.
- फ़्लाइट के दौरान कॉम्प्रेस करने की सुविधा, खास तौर पर उन वेब पेजों के लिए बेहतर काम करती है जो डाइनैमिक तौर पर जनरेट होते हैं.
नुकसान
- बेहतर कंप्रेसन रेशियो पाने के लिए, फ़ाइलों को ज़्यादा लेवल पर कंप्रेस करने में ज़्यादा समय लगता है. इससे परफ़ॉर्मेंस पर असर पड़ सकता है, क्योंकि उपयोगकर्ता को एसेट के भेजे जाने से पहले, उनके कंप्रेस होने का इंतज़ार करना पड़ता है.
Node और Express की मदद से डाइनैमिक कंप्रेसन
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
में सभी स्टैटिक एचटीएमएल, JS, और सीएसएस फ़ाइलों को लोड करने के लिए, express.static
मध्यवेयर का इस्तेमाल करता है. ये फ़ाइलें, हर बिल्ड के साथ वेबपैक बनाता है.public/directory
यह पक्का करने के लिए कि जब भी किसी ऐसेट का अनुरोध किया जाए, तो उसे ब्रॉटली का इस्तेमाल करके कंप्रेस किया जाए, shrink-ray
मॉड्यूल का इस्तेमाल किया जा सकता है. package.json
में इसे devDependency
के तौर पर जोड़कर शुरुआत करें:
"devDependencies": {
// ...
"shrink-ray": "^0.1.3"
},
और इसे सर्वर फ़ाइल, server.js
में इंपोर्ट करें:
const express = require('express');
const shrinkRay = require('shrink-ray');
साथ ही, express.static
के माउंट होने से पहले, इसे मिडलवेयर के तौर पर जोड़ें:
// ...
const app = express();
// Compress all requests
app.use(shrinkRay());
app.use(express.static('public'));
अब ऐप्लिकेशन को फिर से लोड करें और नेटवर्क पैनल में बंडल का साइज़ देखें:
अब आपको Content-Encoding
हेडर में दिखेगा कि brotli
, bz
से लागू किया गया है.
main.bundle.js
का साइज़ 225 केबी से घटकर 53.1 केबी हो गया है! यह gzip
(61.6 केबी) की तुलना में ~14% छोटा है.
स्टैटिक कंप्रेसन
स्टैटिक कंप्रेसन का मकसद, ऐसेट को पहले से कंप्रेस करके सेव करना है.
फ़ायदे
- अब वीडियो को ज़्यादा कंप्रेस करने की वजह से, इंतज़ार का समय ज़्यादा नहीं होता. फ़ाइलों को कंप्रेस करने के लिए, अब उन्हें फ़्लाइट में कुछ भी करने की ज़रूरत नहीं है, क्योंकि उन्हें अब सीधे फ़ेच किया जा सकता है.
नुकसान
- हर बिल्ड के साथ एसेट को कंप्रेस करना ज़रूरी है. ज़्यादा कंप्रेस करने पर, बिल्ड होने में लगने वाला समय काफ़ी बढ़ सकता है.
webpack की मदद से Node और Express का इस्तेमाल करके स्टैटिक कंप्रेसन
स्टैटिक कंप्रेसन में, फ़ाइलों को पहले से कंप्रेस करना शामिल होता है. इसलिए, वेबपैक की सेटिंग में बदलाव करके, एसेट को बिल्ड करने के दौरान कंप्रेस किया जा सकता है. इसके लिए, brotli-webpack-plugin
का इस्तेमाल किया जा सकता है.
package.json
में इसे devDependency
के तौर पर जोड़कर शुरुआत करें:
"devDependencies": {
// ...
"brotli-webpack-plugin": "^1.1.0"
},
किसी भी दूसरे वेबपैक प्लग इन की तरह, इसे कॉन्फ़िगरेशन फ़ाइल में इंपोर्ट करें,
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
कर दिया जाएगा.
ऐप्लिकेशन फिर से लोड होने और फिर से बनने के बाद, मुख्य बंडल का कंप्रेस किया गया वर्शन बन जाता है. Node सर्वर से दिखाई गई फ़ाइनल public/
डायरेक्ट्री में क्या है, यह देखने के लिए Glitch कंसोल खोलें.
- टूल बटन पर क्लिक करें.
- कंसोल बटन पर क्लिक करें.
- कंसोल में,
public
डायरेक्ट्री में जाने और उसकी सभी फ़ाइलें देखने के लिए, ये निर्देश चलाएं:
cd public
ls -lh
बंडल main.bundle.js.br
का ब्रॉटली से कंप्रेस किया गया वर्शन, अब यहां भी सेव किया गया है. यह main.bundle.js
की तुलना में ~76% छोटा (225 केबी बनाम 53 केबी) है.
इसके बाद, सर्वर को बताएं कि जब भी उनके ओरिजनल JS वर्शन का अनुरोध किया जाए, तब ब्रॉटली से कंप्रेस की गई ये फ़ाइलें भेजें. ऐसा करने के लिए, express.static
की मदद से फ़ाइलें दिखाने से पहले, server.js
में नया रूट तय करें.
const express = require('express');
const 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()
यह पक्का करता है कि क्रम अगले कॉलबैक पर जारी रहे.
हो सकता है कि कुछ ब्राउज़र, Brotli कंप्रेसन का इस्तेमाल न कर पाएं. इसलिए, Brotli से कंप्रेस की गई फ़ाइल दिखाने से पहले, इस बात की पुष्टि कर लें कि ब्राउज़र में Brotli काम करता है. इसके लिए, Accept-Encoding
अनुरोध हेडर में br
शामिल है या नहीं, यह देखें:
const express = require('express');
const 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'));
ऐप्लिकेशन फिर से लोड होने के बाद, नेटवर्क पैनल को फिर से देखें.
हो गया! आपने अपनी ऐसेट को ज़्यादा कंप्रेस करने के लिए, Brotli कंप्रेसन का इस्तेमाल किया है!
नतीजा
इस कोडलैब में बताया गया है कि brotli
आपके ऐप्लिकेशन के कुल साइज़ को और कैसे कम कर सकता है. जहां काम करता है वहां brotli
, gzip
से ज़्यादा बेहतर कंप्रेसन एल्गोरिदम है.