هذا الدرس التطبيقي حول الترميز هو امتداد لعملية تقليل أحمال الشبكة وضغطها.
درس تطبيقي حول الترميز
ويفترض أنك على دراية بمفاهيم الضغط الأساسية. بالنسبة
مقارنةً بخوارزميات الضغط الأخرى مثل gzip
، يستكشف هذا الدرس التطبيقي حول الترميز كيفية
يمكن أن يؤدي ضغط Brotli إلى تقليل نِسب الضغط وتحسين أداء تطبيقك بشكل عام
الحجم.
القياس
قبل التعمق في إضافة التحسينات، يُفضل دائمًا تحليل الحالة الحالية للتطبيق.
- انقر على إنشاء ريمكس لتعديل لجعل المشروع قابلاً للتعديل.
- لمعاينة الموقع الإلكتروني، اضغط على عرض التطبيق. ثم اضغط ملء الشاشة
في القسم السابق تصغير وضغط حمولات الشبكة
درس تطبيقي حول الترميز
تم تقليل حجم main.js
من 225 كيلوبايت إلى 61.6 كيلوبايت. في هذا الدرس التطبيقي حول الترميز،
كيف يمكن لضغط Brotli تقليل حجم الحزمة بشكل أكبر.
ضغط Brotli
بروتلي
هي خوارزمية ضغط أحدث يمكنها توفير ضغط أفضل للنص
نتائج من gzip
. وفقًا لـ
CertSimple، أداء Brotli هو:
- أصغر من
gzip
بنسبة 14% للغة JavaScript - أصغر بنسبة 21% من
gzip
لـ HTML - أصغر بنسبة% 17 من
gzip
لخدمة مقارنة الأسعار
لاستخدام 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
مسؤول عن إعداد خادم العُقدة الذي يستضيفه
التطبيق.
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 كيلوبايت! هذا الرقم أصغر بنسبة% 14 تقريبًا
مقارنةً بـ gzip
(61.6 كيلوبايت).
الضغط الثابت
تكمن الفكرة وراء الضغط الثابت في ضغط مواد العرض وحفظها مسبقًا محددة.
الإيجابيات
- لم يعُد وقت الاستجابة بسبب مستويات الضغط العالية مصدر قلق. لا شيء على الفور لضغط الملفات حيث يمكن جلبها مباشرةً.
السلبيات
- يجب ضغط مواد العرض مع كل إصدار. قد تزداد أوقات البناء بشكل كبير إذا تم استخدام مستويات ضغط عالية.
ضغط ثابت مع Node/Express وwebpack
بما أنّ الضغط الثابت يتضمّن ضغط الملفات مسبقًا، يجب استخدام webpack.
يمكن تعديل الإعدادات لضغط مواد العرض كجزء من خطوة التصميم. تشير رسالة الأشكال البيانية
يمكن استخدام brotli-webpack-plugin
لهذا الغرض.
ابدأ بإضافته كـ devDependency
في package.json
:
"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
: جميع مواد العرض التي تتطابق مع التعبير العادي هذا (أي مواد عرض JavaScript التي تنتهي بـ.js
).
على سبيل المثال، ستتم إعادة تسمية main.js
إلى main.js.br
.
وعند إعادة تحميل التطبيق وإعادة إنشائه، يتم إنشاء نسخة مضغوطة من الحزمة الرئيسية
تم إنشاؤها الآن. افتح Glitch Console لإلقاء نظرة على المحتوى النهائي.
دليل public/
الذي يعرضه خادم Node.
- انقر على زر الأدوات.
- انقر على الزر وحدة التحكّم.
- في وحدة التحكّم، شغِّل الأوامر التالية لتغييرها إلى
public
. الدليل وعرض كل ملفاته:
cd public
ls -lh
تم حفظ نسخة brotli المضغوطة من الحزمة، main.bundle.js.br
هنا أيضًا وهو أصغر حجمًا بنسبة 76% تقريبًا (225 كيلوبايت مقابل 53 كيلوبايت) من
main.bundle.js
بعد ذلك، اطلب من الخادم إرسال هذه الملفات المضغوطة باستخدام brotli عند الحاجة
يتم طلب إصدارات JavaScript الأصلية. ويمكن القيام بذلك من خلال تحديد نوع
المسار في 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()
استمرار التسلسل مع أي معاودة اتصال قد التالي.
تأكَّد من أنّ بعض المتصفحات قد لا تتوافق مع ضغط 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 لضغط مواد العرض بشكل أكبر.
الخاتمة
يوضّح هذا الدرس التطبيقي حول الترميز كيف يمكن لـ brotli
تقليل إجمالي أداء تطبيقك
الحجم. حيثما أمكن، تعد خوارزمية الضغط brotli
أكثر فعالية من
gzip