ה-codelab הזה הוא הרחבה של ה-codelab בנושא מזעור ודחיסה של נתוני רשת, וההנחה היא שאתם מכירים את המושגים הבסיסיים של דחיסה. בהשוואה לאלגוריתמים אחרים לדחיסה כמו gzip
, במעבדת הקוד הזו נסביר איך דחיסת Brotli (br
) יכולה להקטין עוד יותר את יחסי הדחיסה ואת הגודל הכולל של האפליקציה.
מדידה
לפני שמתחילים להוסיף אופטימיזציות, תמיד כדאי קודם לנתח את המצב הנוכחי של האפליקציה.
- לוחצים על Remix to Edit כדי להפוך את הפרויקט לעריכה.
- כדי לראות תצוגה מקדימה של האתר, לוחצים על הצגת האפליקציה ואז על מסך מלא
.
ב-codelab הקודם בנושא הקטנה ודחיסה של מטענים ייעודיים (payload) ברשת, צמצמנו את הגודל של main.js
מ-225KB ל-61.6KB. ב-codelab הזה נסביר איך אפשר להקטין עוד יותר את גודל החבילה באמצעות דחיסת Brotli.
דחיסת Brotli
Brotli
הוא אלגוריתם דחיסה חדש יותר שיכול לספק תוצאות דחיסה טובות יותר של טקסט
מאשר gzip
. לפי CertSimple, הביצועים של Brotli הם:
- 14% קטן יותר מ-
gzip
עבור JavaScript - קטן ב-21% מהגודל של
gzip
ב-HTML - 17% קטן יותר מ-
gzip
עבור CSS
כדי להשתמש ב-Brotli, השרת צריך לתמוך ב-HTTPS. Brotli נתמך בכל הדפדפנים המודרניים. בדפדפנים שתומכים ב-Brotli, הערך br
יופיע בכותרות Accept-Encoding
:
Accept-Encoding: gzip, deflate, br
אפשר לקבוע באיזה אלגוריתם דחיסה נעשה שימוש באמצעות השדה Content-Encoding
בכרטיסייה 'רשת' ב'כלים למפתחים ב-Chrome' (Command+Option+I
או Ctrl+Alt+I
):

איך מפעילים את Brotli
הדרך להגדיר שרת אינטרנט לשליחת משאבים עם קידוד Brotli תלויה באופן שבו אתם מתכננים לקודד אותם. האפשרויות הן לדחוס באופן דינמי משאבים באמצעות Brotli בזמן הבקשה (דינמי), או לקודד אותם מראש כך שהם כבר יהיו דחוסים בזמן שהמשתמש יבקש אותם (סטטי).
דחיסה דינמית
דחיסה דינמית כוללת דחיסה של נכסים תוך כדי תנועה, בזמן שהדפדפן מבקש אותם.
יתרונות
- אין צורך ליצור ולעדכן גרסאות דחוסות ושמורות של נכסים.
- דחיסה תוך כדי תנועה מתאימה במיוחד לדפי אינטרנט שנוצרים באופן דינמי.
חסרונות
- דחיסת קבצים ברמות גבוהות יותר כדי להשיג יחסי דחיסה טובים יותר אורכת זמן רב יותר. הדבר עלול לפגוע בביצועים כי המשתמש צריך לחכות עד שהנכסים יידחסו לפני שהשרת ישלח אותם.
דחיסה דינמית באמצעות Node ו-Express
הקובץ server.js
אחראי להגדרת שרת Node שמארח את האפליקציה.
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
כדי לטעון את כל קובצי ה-HTML, ה-JS וה-CSS הסטטיים ב-public/directory
(וקבצים אלה נוצרים על ידי webpack בכל בנייה).
כדי לוודא שכל הנכסים נדחסים באמצעות brotli בכל פעם שהם מבוקשים, אפשר להשתמש במודול shrink-ray
. כדי להתחיל, מוסיפים אותו כdevDependency
בpackage.json
:
"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'));
עכשיו טוענים מחדש את האפליקציה ומסתכלים על גודל ה-bundle בחלונית Network:

מעכשיו אפשר לראות שההגדרה brotli
חלה מ-bz
בכותרת Content-Encoding
.
הגודל של main.bundle.js
ירד מ-225KB ל-53.1KB. הגודל קטן בכ-14% בהשוואה ל-gzip
(61.6KB).
דחיסה סטטית
הרעיון מאחורי דחיסה סטטית הוא לדחוס ולשמור נכסים מראש.
יתרונות
- זמן האחזור בגלל רמות דחיסה גבוהות כבר לא מהווה בעיה. אין צורך לבצע דחיסה של קבצים בזמן אמת, כי עכשיו אפשר לאחזר אותם ישירות.
חסרונות
- צריך לדחוס את הנכסים בכל בנייה. זמני הבנייה יכולים להתארך משמעותית אם משתמשים ברמות דחיסה גבוהות.
דחיסה סטטית באמצעות Node ו-Express עם webpack
בדחיסה סטטית, הקבצים נדחסים מראש, ולכן אפשר לשנות את ההגדרות של webpack כדי לדחוס נכסים כחלק משלב הבנייה. אפשר להשתמש בbrotli-webpack-plugin
לצורך הזה.
כדי להתחיל, מוסיפים אותו כdevDependency
בpackage.json
:
"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
: כל הנכסים שתואמים לביטוי הרגולרי הזה (כלומר, נכסי JavaScript שמסתיימים ב-.js
) יעברו עיבוד.
לדוגמה, main.js
ישונה ל-main.js.br
.
כשהאפליקציה נטענת מחדש ונבנית מחדש, נוצרת גרסה דחוסה של החבילה הראשית. פותחים את Glitch Console כדי לראות מה יש בספרייה הסופית public/
שמוצגת על ידי שרת Node.
- לוחצים על הלחצן כלים.
- לוחצים על הלחצן Console.
- במסוף, מריצים את הפקודות הבאות כדי לעבור לספרייה
public
ולראות את כל הקבצים שלה:
cd public
ls -lh

הגרסה הדחוסה של החבילה בפורמט Brotli, main.bundle.js.br
, נשמרת גם כאן, והגודל שלה קטן בכ-76% (225 KB לעומת 53 KB) בהשוואה ל-main.bundle.js
.
לאחר מכן, צריך להגדיר לשרת לשלוח את הקבצים האלה שנדחסו באמצעות Brotli בכל פעם שמתקבלת בקשה לגרסאות ה-JS המקוריות שלהם. כדי לעשות זאת, צריך להגדיר נתיב חדש ב-server.js
לפני שהקבצים מוגשים באמצעות express.static
.
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
מצורף לכתובת ה-URL של הבקשה וכותרת התגובהContent-Encoding
מוגדרת ל-br
. - הכותרת
Content-Type
מוגדרת לערךapplication/javascript; charset=UTF-8
כדי לציין את סוג ה-MIME. - לבסוף,
next()
מוודא שהרצף ממשיך לכל קריאה חוזרת שעשויה להיות הבאה.
יכול להיות שדפדפנים מסוימים לא תומכים בדחיסת 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'));
אחרי שהאפליקציה נטענת מחדש, בודקים שוב את החלונית Network (רשת).

הצלחת! השתמשת בדחיסת Brotli כדי לדחוס עוד יותר את הנכסים שלך.
סיכום
ב-codelab הזה מוסבר איך brotli
יכול להקטין עוד יותר את הגודל הכולל של האפליקציה. במקרים שבהם יש תמיכה, brotli
הוא אלגוריתם דחיסה חזק יותר מ-gzip
.