لو الـ JavaScript bundle بتاعك 480KB وبعد Gzip بقى 142KB ومتقبّل الرقم ده على إنه أحسن حاجة ممكنة، انت بتدفع 21% bandwidth زيادة من غير سبب. Brotli على نفس الملف بالظبط بينزّل الحجم لـ 112KB بضبط سطرين في NGINX. كل المتصفحات الحديثة بتدعمه من سنة 2017، ومفيش سبب تقني لإنك لسه شغّال على Gzip لوحده في 2026.
Brotli في 2026: ليه Gzip لوحده مش كفاية لموقع إنتاج
المشكلة باختصار
Gzip اتعمل سنة 1992 وبيستخدم خوارزمية DEFLATE اللي اتصمّمت على hardware ضعيف زمان. كل request في 2026 لسه بيتضغط بنفس الخوارزمية رغم إن الـ CPU بقت أسرع 200 مرة. النتيجة: المستخدم بيحمّل ملفات أكبر من اللازم، والـ Largest Contentful Paint بياخد ثانية زيادة على شبكة 4G ضعيفة، والشركة بتدفع bandwidth زيادة على CDN في الآخر.
المشكلة بالظبط في إن أغلب فرق الـ DevOps حطّت gzip on في NGINX سنة 2015 ومحدش رجع راجع الإعداد لما Brotli بقى متاح. الفرق مش هامشي: على ملفات HTML الفرق ممكن يوصل لـ 31% توفير، وعلى JavaScript حوالي 21%، وعلى CSS حوالي 17%.
Brotli بمثال شنطة السفر
تخيّل إنك بتسافر وعندك شنطة فاضية وكمية هدوم. لو طويت الهدوم بطريقة عادية وحطّيتهم في الشنطة، بتاخد 20 قطعة. لو رصصتهم بطريقة vacuum compression (شفط الهوا)، نفس الشنطة بالظبط بتاخد 25 قطعة. الفرق مش في حجم الشنطة، الفرق في طريقة ترتيب اللي جوّاها.
Brotli هو الـ vacuum compression، Gzip هو الطي العادي.
علميًا، الفرق إن Brotli بيستخدم static dictionary مدمج فيه 13,504 كلمة وعبارة شائعة في الويب (أمثلة: function, return, div class, http://). بدل ما يضغط الكلمات دي من الصفر زي ما Gzip بيعمل، Brotli بيشاور عليها بـ index رقمي صغير. المعيار موثّق رسميًا في RFC 7932 اللي نشرته IETF سنة 2016.
الإعداد العملي على NGINX 1.25
NGINX من نسخة 1.21.5 بقى بيدعم Brotli عبر module اسمه ngx_brotli اللي طوّرته Google ونقلته بعد كده Cloudflare لمستودع منفصل. على Ubuntu 24.04 الإعداد بياخد 4 خطوات بس:
# 1) تثبيت الموديول الرسمي
sudo apt update
sudo apt install libnginx-mod-brotli
# 2) فتح ملف الإعداد
sudo nano /etc/nginx/nginx.conf
# 3) إضافة الإعداد التالي داخل http block
brotli on;
brotli_static on;
brotli_comp_level 6;
brotli_types text/plain text/css application/javascript application/json image/svg+xml application/xml;
# 4) إعادة تحميل الإعداد بدون downtime
sudo nginx -t && sudo systemctl reload nginx
بعد الـ reload، الرد الـ HTTP بيرجع header content-encoding: br بدل content-encoding: gzip للمتصفحات اللي بتدعم Brotli. للمتصفحات القديمة (لو وُجدت)، NGINX بيرجع تلقائيًا لـ Gzip.
الأرقام الفعلية على JS bundle 480KB
قياس فعلي على bundle React production build، 480KB قبل أي ضغط:
- الأصلي (uncompressed): 480KB
- Gzip level 6 (الافتراضي): 142KB — نسبة ضغط 70.4%
- Brotli level 6: 112KB — نسبة ضغط 76.7%
- Brotli level 11 (مع
brotli_static): 98KB — نسبة ضغط 79.6%
الفرق على شبكة 4G بسرعة 5Mbps حقيقي ومحسوس: المستخدم بيوفّر 44KB، يعني تقريبًا 70ms أقل في زمن التحميل لكل request. Cloudflare قاست الفرق على 100 ألف موقع ولقت متوسط توفير 22% على ملفات النصوص و 31% على HTML الديناميكي.
Trade-offs اللي لازم تعرفها قبل ما تفعّل
Brotli مش مجاني تمامًا. فيه 4 نقاط trade-off حقيقية:
- الضغط أبطأ من Gzip: Brotli level 11 بياخد حوالي 100ms على ملف 1MB مقابل 8ms لـ Gzip level 6. الحل العملي إنك تعتمد على
brotli_static onاللي بيخلي NGINX يخدم ملفات.brمضغوطة مسبقًا من الـ build pipeline. - CPU overhead أعلى عند الضغط الديناميكي: لو الـ API بترجّع JSON ديناميكي كبير، Brotli ممكن يضيف 5-12% على CPU compared to Gzip. الحل: استخدم
brotli_comp_level 4للضغط الديناميكي و level 11 للملفات الستاتيك بس. - Dictionary مخصّص للويب: الـ static dictionary بتاع Brotli فيه كلمات HTML/CSS/JS. لو بتضغط بيانات مش نصية (binary blobs، صور WebP) Brotli ممكن يكون أسوأ من Gzip بنسبة 2-4%.
- Browser support بيشتغل على HTTPS بس: Caniuse بيوضّح إن المتصفحات بترفض Brotli على HTTP plain لأسباب أمان. لو الموقع لسه على HTTP، Brotli هيتعمل skip تلقائيًا.
متى لا تستخدم Brotli
فيه 3 حالات Brotli فيها مش الخيار الصح، خليك صريح فيها:
- Internal services بدون TLS: الـ traffic بين microservices في cluster واحد غالبًا بدون HTTPS، وفي الحالة دي Brotli هيتعمل skip. خلّي Gzip أو حتى بدون ضغط لو الشبكة الداخلية فيها bandwidth واسع.
- ملفات أصغر من 1KB: الـ overhead بتاع dictionary lookup بيكون أكبر من المكسب. ضيف
brotli_min_length 1024;في الإعداد. - CPU-bound servers على low-end hardware: سيرفر بـ 2 vCPU و traffic 10K req/s ممكن يخنق على Brotli level 11 ديناميكي. ابدأ بـ level 4 وقيس
cpu.usageقبل ما تروح للـ level أعلى.
المصادر
- RFC 7932 — Brotli Compressed Data Format (IETF)
- Cloudflare Engineering Blog — Results experimenting with Brotli
- ngx_brotli — NGINX Brotli module من Google
- Caniuse — Brotli browser support matrix
- NGINX gzip module documentation
الخطوة التالية
افتح /etc/nginx/nginx.conf دلوقتي وضيف الـ 4 سطور اللي فوق، ثم nginx -t && nginx -s reload. بعد كده افتح DevTools في المتصفح، روح لـ Network tab، اختار أي ملف JS من موقعك، وشوف content-encoding في الـ response headers. لو الـ value بقى br، انت دلوقتي بتوفّر 21% من bandwidth على كل زائر، وسيرفرك بياكل CPU أقل من اللي كان بياكله مع Gzip level 9.