Brotli وgzip: قلّل حجم ملفات JS وCSS من غير ما تغيّر الكود
مستوى القارئ: متوسط
لو عندك bundle حجمه 420KB، المقال ده هيساعدك تخليه يوصل للمتصفح حوالي 96KB باستخدام Brotli، من غير refactor ولا تغيير في React أو Vue أو Next.js.
المشكلة باختصار
الطريقة الشائعة الغلط إنك تبدأ بتكسير الـ bundle أو تغيير framework قبل ما تقيس النقل الفعلي على الشبكة. ركز: أحيانًا المشكلة مش إن الكود كتير، المشكلة إنك بتبعته خام.
الافتراض إن عندك ملفات نصية static مثل .js و.css و.html، وحجمها بعد الـ build واضح. في موقع تجارة إلكترونية بحدود 50K زيارة يوميًا، ملف main.js بحجم 420KB ممكن يضيف 300 إلى 800ms على شبكات 4G متوسطة، خصوصًا لو المستخدم أول مرة يفتح الموقع.
المفهوم بمثال بسيط
اعتبر إن عندك تقرير طويل هتبعته بالإيميل. ممكن تبعته كما هو، أو تضغطه في ملف ZIP. المستقبل يفك الضغط ويقرأ نفس التقرير. ده بالظبط اللي بيحصل مع gzip وBrotli، لكن على مستوى HTTP.
المتصفح يرسل في الطلب header اسمه Accept-Encoding. لو المتصفح كاتب br أو gzip، السيرفر يقدر يرد بملف مضغوط ويضيف Content-Encoding: br أو Content-Encoding: gzip. حسب MDN، هذا تفاوض محتوى عادي بين العميل والسيرفر، وليس تغييرًا في الملف الأصلي.
الفرق المهم: الضغط الديناميكي يعمل وقت كل request، بينما pre-compression يعمل وقت الـ build. أفضل طريقة هنا إنك تضغط الملفات مرة واحدة بعد البناء، وتخلي Nginx أو الـ CDN يقدّم النسخة الجاهزة.
الخطوات العملية
- ابنِ المشروع كالمعتاد:
npm run build. - اضغط الملفات النصية إلى
.brو.gzبعد الـ build. - فعّل Nginx لكي يرسل gzip ويبحث عن الملفات المضغوطة مسبقًا.
- تحقق من
Content-Encodingباستخدامcurl.
# داخل مجلد dist أو .next/static أو build حسب مشروعك
find dist -type f \( -name "*.js" -o -name "*.css" -o -name "*.html" \) -print0 \
| xargs -0 -I{} sh -c 'brotli -f -q 11 "{}" && gzip -f -k -9 "{}"'
# تحقق من الاستجابة
curl -I -H "Accept-Encoding: br" https://example.com/assets/main.js
curl -I -H "Accept-Encoding: gzip" https://example.com/assets/main.jsلو كل شيء شغال، المفروض تشوف header مثل: