این Codelab گسترشی از Minify and compress payloads codelab شبکه است و فرض می کند که شما با مفاهیم اولیه فشرده سازی آشنا هستید. در مقایسه با سایر الگوریتمهای فشردهسازی مانند gzip
، این نرمافزار کد بررسی میکند که چگونه فشردهسازی Brotli میتواند نسبتهای فشردهسازی و اندازه کلی برنامه شما را کاهش دهد.
اندازه گیری کنید
قبل از وارد شدن برای افزودن بهینه سازی، همیشه ایده خوبی است که ابتدا وضعیت فعلی برنامه را تجزیه و تحلیل کنید.
- روی Remix to Edit کلیک کنید تا پروژه قابل ویرایش باشد.
- برای پیش نمایش سایت، View App را فشار دهید. سپس تمام صفحه را فشار دهید .
در نسخه قبلی Minify and compres payloads network ، اندازه main.js
را از 225 کیلوبایت به 61.6 کیلوبایت کاهش دادیم. در این نرمافزار، خواهید دید که چگونه فشردهسازی Brotli میتواند این اندازه بسته را حتی بیشتر کاهش دهد.
فشرده سازی بروتلی
Brotli یک الگوریتم فشرده سازی جدیدتر است که می تواند نتایج فشرده سازی متن بهتری را نسبت به gzip
ارائه دهد. طبق CertSimple ، عملکرد Brotli عبارت است از:
- 14٪ کوچکتر از
gzip
برای جاوا اسکریپت - 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
فشرده سازی دینامیک
فشردهسازی پویا شامل فشردهسازی داراییها در لحظه به محض درخواست مرورگر است.
جوانب مثبت
- ایجاد و بهروزرسانی نسخههای فشرده ذخیرهشده داراییها نیازی به انجام ندارد.
- فشرده سازی در حین پرواز به ویژه برای صفحات وب که به صورت پویا تولید می شوند خوب عمل می کند.
منفی
- فشرده سازی فایل ها در سطوح بالاتر برای دستیابی به نسبت فشرده سازی بهتر زمان بیشتری می برد. این می تواند باعث ضربه عملکرد شود زیرا کاربر منتظر می ماند تا دارایی ها قبل از ارسال توسط سرور فشرده شوند.
فشرده سازی پویا با Node/Express
فایل server.js
مسئول راه اندازی سرور Node است که میزبان برنامه است.
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
(و این فایلها توسط بسته وب با هر ساختنی ایجاد میشوند).
برای اطمینان از اینکه همه دارایی ها هر بار که درخواست می شوند با استفاده از 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
از 225 کیلوبایت به 53.1 کیلوبایت کاهش یافته است! این در مقایسه با gzip
(61.6 کیلوبایت) 14٪ کوچکتر است.
فشرده سازی استاتیک
ایده پشت فشرده سازی استاتیک این است که دارایی ها فشرده شده و زودتر ذخیره شوند.
جوانب مثبت
- تاخیر به دلیل سطوح فشرده سازی بالا دیگر نگران کننده نیست. برای فشردهسازی فایلها، نیازی نیست که در لحظه اتفاقی بیفتد، زیرا اکنون میتوان آنها را مستقیماً واکشی کرد.
منفی
- دارایی ها باید با هر ساختی فشرده شوند. در صورت استفاده از سطوح فشرده سازی بالا، زمان ساخت می تواند به میزان قابل توجهی افزایش یابد.
فشرده سازی استاتیک با Node/Express و 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
: تمام دارایی هایی که با این RegExp مطابقت دارند (یعنی دارایی های جاوا اسکریپت که به.js
ختم می شوند) پردازش می شوند.
برای مثال، main.js
به main.js.br
تغییر نام میدهد.
هنگامی که برنامه بارگیری مجدد و بازسازی می شود، اکنون یک نسخه فشرده از بسته اصلی ایجاد می شود. کنسول Glitch را باز کنید تا به آنچه در داخل دایرکتوری public/
نهایی که توسط سرور Node ارائه می شود نگاهی بیندازید.
- روی دکمه Tools کلیک کنید.
- روی دکمه Console کلیک کنید.
- در کنسول، دستورات زیر را اجرا کنید تا به دایرکتوری
public
تغییر دهید و همه فایلهای آن را ببینید:
cd public
ls -lh
نسخه فشرده شده brotli باندل، main.bundle.js.br
، اکنون در اینجا نیز ذخیره شده است و 76 درصد اندازه آن (225 کیلوبایت در مقابل 53 کیلوبایت) از main.bundle.js
کوچکتر است.
در مرحله بعد، به سرور بگویید که هر زمان که نسخه اصلی JS آنها درخواست شد، این فایل های فشرده شده با brotli را ارسال کند. این را می توان با تعریف یک مسیر جدید در 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
برای یک نقطه پایانی خاص پاسخ دهد استفاده می شود. سپس یک تابع callback برای تعریف نحوه رسیدگی به این درخواست استفاده می شود. مسیر به این صورت عمل می کند:
- تعیین
'*.js'
به عنوان اولین آرگومان به این معنی است که برای هر نقطه پایانی که برای واکشی یک فایل JS فعال می شود، کار می کند. - در پاسخ به تماس،
.br
URL درخواست وصل می شود و سرصفحه پاسخContent-Encoding
رویbr
تنظیم می شود. - هدر
Content-Type
رویapplication/javascript; charset=UTF-8
برای تعیین نوع MIME. - در نهایت،
next()
تضمین می کند که دنباله به هر فراخوانی که ممکن است بعدی باشد ادامه می یابد.
از آنجایی که ممکن است برخی از مرورگرها از فشردهسازی brotli پشتیبانی نکنند، قبل از بازگرداندن فایل فشردهشده brotli با بررسی هدر درخواست Accept-Encoding
شامل br
، تأیید کنید که brotli پشتیبانی میشود:
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 برای فشرده سازی بیشتر دارایی های خود استفاده کرده اید!
نتیجه گیری
این آزمایشگاه کد نشان می دهد که چگونه brotli
می تواند اندازه کلی برنامه شما را بیشتر کاهش دهد. در صورت پشتیبانی، brotli
یک الگوریتم فشرده سازی قدرتمندتر از gzip
است.