ה-codelab הוא תוסף ל-Minify and compression paylab (הקטנה ודחיסה של מטענים ייעודיים) ברשת – בהנחה שאתם מכירים את המושגים הבסיסיים של הדחיסה. בהשוואה לאלגוריתמים אחרים של דחיסה כמו gzip
, ב-Codelab הזה תלמדו איך דחיסת Brotli יכולה לצמצם עוד יותר את יחסי הדחיסה ואת הגודל הכולל של האפליקציה.
מדידה
לפני שמתחילים להוסיף אופטימיזציות, תמיד כדאי לנתח קודם את המצב הנוכחי של האפליקציה.
- לוחצים על רמיקס לעריכה כדי שיהיה אפשר לערוך את הפרויקט.
- כדי לראות תצוגה מקדימה של האתר, מקישים על View App ואז על Fullscreen .
בשיעור הקודם של Minify and דחיסת נתוני מטענים ייעודיים (paylab), הורדנו את הגודל של main.js
מ-225KB ל-61.6KB. בשיעור הזה תלמדו איך דחיסת 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
דחיסה דינמית
דחיסה דינמית כוללת דחיסת נכסים בזמן אמת בהתאם לבקשה מהדפדפן.
יתרונות
- אין צורך ליצור ולעדכן גרסאות שמורות של נכסים דחוסים.
- דחיסה במקום פועל טוב במיוחד לדפי אינטרנט שנוצרים באופן דינמי.
חסרונות
- דחיסת קבצים ברמות גבוהות יותר כדי להשיג יחסי דחיסה טובים יותר נמשכת זמן רב יותר. הדבר עלול לגרום להיט ביצועים כי המשתמש ממתין שהנכסים יידחו לפני שהם נשלחים על ידי השרת.
דחיסה דינמית עם צומת/אקספרס
הקובץ 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
ולהשתמש בתווכה express.static
כדי לטעון את כל קובצי ה-HTML, ה-JS וה-CSS הסטטיים ב-public/directory
(והקבצים האלה נוצרים על ידי Webpack עם כל build).
כדי לוודא שכל הנכסים דחוסים באמצעות brotli בכל פעם שמבקשים אותם, אפשר להשתמש במודול shrink-ray
. כדי להתחיל, יש להוסיף אותו כ-devDependency
ב-package.json
:
"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
מתבצעת מ-bz
בכותרת הContent-Encoding
.
main.bundle.js
ירד מ-225KB ל-53.1KB! זה קטן ב-14% בערך בהשוואה ל-gzip
(61.6KB).
דחיסה סטטית
הרעיון מאחורי דחיסה סטטית הוא לדחוס את הנכסים כדי שיישמרו מראש.
יתרונות
- זמן האחזור עקב רמות דחיסה גבוהות כבר לא מהווה בעיה. לא צריך שום דבר שיקרה בפועל כדי לדחוס קבצים, כי עכשיו אפשר לאחזר אותם ישירות.
חסרונות
- צריך לדחוס את הנכסים בכל build. זמני ה-build יכולים להתארך משמעותית אם משתמשים ברמות דחיסה גבוהות.
דחיסה סטטית עם Node/Express ו-webpack
מכיוון שדחיסה סטטית כוללת דחיסת קבצים מראש, אפשר לשנות את ההגדרות של Webpack כדי לדחוס נכסים כחלק משלב ה-build. לשם כך אפשר להשתמש ב-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
: המערכת מעבדת את כל הנכסים שתואמים ל-RegExp הזה (כלומר, נכסי JavaScript שמסתיימים ב-.js
).
לדוגמה, השם של main.js
ישתנה ל-main.js.br
.
כשהאפליקציה נטענת מחדש ונוצרת מחדש, נוצרת עכשיו גרסה דחוסה של החבילה הראשית. פותחים את Glitch Console כדי לבדוק מה יש בספרייה public/
הסופית שמוצגת על ידי שרת הצמתים.
- לוחצים על הלחצן כלים.
- לוחצים על הלחצן מסוף.
- במסוף, מריצים את הפקודות הבאות כדי לעבור לספרייה
public
ולראות את כל הקבצים שבה:
cd public
ls -lh
גרסת ה-Brotli הדחוסה של החבילה, main.bundle.js.br
, גם שמורה כאן, והיא קטנה ב-76% בערך (225KB לעומת 53KB) לעומת main.bundle.js
.
בשלב הבא, מבקשים מהשרת לשלוח את הקבצים האלה דחוסים ב-brotli בכל פעם שמבקשים גרסאות ה-JS המקוריות שלהם. כדי לעשות זאת, אפשר להגדיר מסלול חדש ב-server.js
לפני שהקבצים יוצגו באמצעות express.static
.
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
מצורפת לכתובת ה-URL של הבקשה וכותרת התגובהContent-Encoding
מוגדרת ל-br
. - הכותרת
Content-Type
מוגדרת ל-application/javascript; charset=UTF-8
כדי לציין את סוג ה-MIME. - לבסוף,
next()
מבטיח שהרצף ימשיך לכל קריאה חוזרת (callback) שעשויה להיות הבאה.
יכול להיות שחלק מהדפדפנים לא תומכים בדחיסת brotli, לכן חשוב לוודא שיש תמיכה ב-brotli לפני החזרת הקובץ הדחוס ב-brotli. לשם כך, צריך לבדוק שהכותרת של הבקשה 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'));
לאחר הטעינה מחדש של האפליקציה, מעיינים שוב בחלונית 'רשת'.
זהו! השתמשת בדחיסת Brotli כדי להמשיך לדחוס את הנכסים שלך!
סיכום
ה-Codelab הדגים איך brotli
יכול לצמצם עוד יותר את הגודל הכולל של האפליקציה. בכל מקום שבו יש תמיכה, brotli
הוא אלגוריתם דחיסה חזק יותר מאשר gzip
.