مستوى المقال: مبتدئ. الشرح ده موجّه للي بدأ شغل front-end أو DevOps حديثًا وبيشوف موقعه بطيء على الموبايل وميعرفش ليه. لو عندك 3+ سنين خبرة في تحسين الأداء، الأرقام هتفيدك لكن المفهوم نفسه أساسي.
لو الـ main.js بتاع موقعك حجمه 1.2MB والمتصفح بياخد 2.8 ثانية يحمّله على شبكة 4G، السيرفر مش ضعيف. المشكلة إنك بترسل الملف بضغط Gzip بحجم 482KB، في حين Brotli بيوصله لـ 365KB بنفس المحتوى تمامًا. الفرق 24% أقل، بدون لمس سطر واحد من الكود.
إيه الفرق بين Brotli و Gzip؟
تخيّل إنك بتشتغل في شركة شحن. عندك صندوق فيه 100 كتاب، وعايز توصّله لعميل في مدينة تانية. قدامك طريقتين تغلّفه بيهم:
- Gzip: زي ورق تغليف عادي. بيلف الصندوق ويقلّل حجمه شوية. سريع وكل شركات الشحن في الدنيا بتقبله.
- Brotli: زي ورق تغليف ذكي. بيدرس شكل الكتب الأول، يطوي كل كتاب بشكل أمثل، ويلف الكل بحبل أرفع. الصندوق بيطلع أصغر فعلًا، لكن التغليف بياخد دقيقة زيادة في البداية.
على الإنترنت، الـ JavaScript و CSS بتوع موقعك زي الصندوق ده. كل ما الصندوق أصغر، كل ما وصل أسرع للعميل. Brotli بيغلّف الملفات بشكل أذكى من Gzip، فبتوصل للمتصفح بحجم أقل، فالموقع بيظهر أسرع.
الشرح العلمي بالتفاصيل
Gzip اتطلق سنة 1992 وبيستخدم خوارزمية DEFLATE اللي بتجمع بين LZ77 (لإيجاد الأنماط المتكررة) و Huffman coding (لترميز الأحرف بأطوال متغيرة). Brotli اتطلق من Google سنة 2015 وبيضيف 3 تحسينات أساسية:
- قاموس ثابت داخلي فيه 13,504 كلمة شائعة من ملفات HTML و JavaScript و CSS و عربي و إنجليزي ولغات تانية. ده معناه إن الكلمات اللي بتتكرر زي
functionأوreturnأوclassNameبتتشار إليها برقم صغير من القاموس بدل ما تتكتب كل مرة. - context modeling أفضل: الخوارزمية بتتنبأ بالحرف الجاي بناءً على آخر حرفين، مش حرف واحد بس زي Gzip.
- مستويات ضغط من 0 لـ 11. كل ما المستوى أعلى، الضغط أقوى، لكن الـ CPU بيتعب أكتر.
النتيجة على bundle حقيقي 1,228KB (React 18 + lodash + moment + كود تطبيق متوسط):
- Gzip level 6 (الافتراضي): 482KB — وقت ضغط 38ms.
- Brotli level 4: 412KB — وقت ضغط 42ms.
- Brotli level 11: 365KB — وقت ضغط 8,400ms.
اللي بيحصل فعلاً إن المتصفحات الحديثة بتدعم Brotli من سنة 2017 على HTTPS فقط (Chrome 50+، Firefox 44+، Safari 11+، Edge 15+). كل ما المستخدم يفتح موقعك، المتصفح بيقول للسيرفر "أنا بقبل br أو gzip" في الـ header Accept-Encoding، والسيرفر بيختار الأفضل المتاح.
إزاي تفعّل Brotli في NGINX خطوة بخطوة
الإعداد ده مبني على فرضية إن عندك NGINX 1.21+ على Ubuntu 22.04 و موقع HTTPS شغّال. لو NGINX أقدم، حدّثه الأول أو ركّب الـ module من المصدر يدويًا.
# 1. ثبت الـ Brotli module على Ubuntu
sudo apt update
sudo apt install libnginx-mod-http-brotli-filter libnginx-mod-http-brotli-static
# 2. افتح ملف الإعداد
sudo nano /etc/nginx/nginx.conf
ضيف الـ block ده داخل قسم http { }:
brotli on;
brotli_comp_level 5;
brotli_min_length 256;
brotli_types
text/plain
text/css
application/javascript
application/json
application/xml
image/svg+xml
font/woff2;
# خلي Gzip شغّال كـ fallback للمتصفحات القديمة
gzip on;
gzip_comp_level 6;
gzip_types text/plain text/css application/javascript application/json;
اختبر الإعداد وأعد التشغيل:
sudo nginx -t
sudo systemctl reload nginx
# تأكد إن Brotli بيشتغل فعلًا
curl -H "Accept-Encoding: br" -I https://your-site.com/main.js
# لازم تشوف: content-encoding: br
ليه اخترنا level 5 مش 11؟
هنا الـ trade-off اللي معظم الناس بتقع فيه. Brotli level 11 بيدّيك أعلى ضغط (نزول حوالي 28% مقارنة بـ Gzip)، لكنه بياخد 8.4 ثانية لضغط ملف 1.2MB. ده مقبول لو الضغط بيحصل مرة واحدة وقت الـ build، لكنه كارثة لو السيرفر بيضغط في كل request.
التوزيع الأمثل اللي بيستخدمه فريق Cloudflare:
- الملفات الثابتة (JS، CSS، fonts): اضغطها static بمستوى 11 وقت الـ build. NGINX يقدمها مباشرة من القرص بـ
brotli_static on;بدون أي CPU وقت الـ request. - الـ HTML الديناميكي وردود JSON: استخدم Brotli level 4 أو 5 أونلاين. الفرق عن Gzip بيكون 12-15% لكن استهلاك CPU تقريبًا نفس Gzip.
متى Brotli بيكون اختيار غلط
مش كل حالة بتستفيد من Brotli. تجنّبه في الحالات دي:
- الملف أصلًا مضغوط زي JPEG و PNG و MP4. الضغط مرة تانية بيكبّر الحجم 2-4% بدل ما يقلّله. NGINX بيتجنب ده تلقائيًا لو
brotli_typesمش شاملة الـ image types. - الملف أقل من 256 byte. الـ overhead أعلى من الفايدة.
brotli_min_lengthبيحميك. - السيرفر CPU-bound بالفعل. لو الـ CPU على 85%+ في الأوقات العادية، Brotli online هيخلّيها 95%+. الحل: استعمل Brotli static فقط للملفات الجاهزة.
- كل عملائك على متصفحات قديمة جدًا (IE11، Opera Mini). دول مش بيدعموا Brotli، وهيقعوا على Gzip تلقائيًا. مفيش ضرر، لكن مفيش فايدة كمان.
الأرقام اللي تتوقعها بعد التفعيل
قياس فعلي على موقع e-commerce عربي بـ 22,000 زيارة يوميًا، بدون أي تغيير في الكود:
- JavaScript transfer size: من 487KB لـ 372KB (-24%).
- CSS transfer size: من 84KB لـ 61KB (-27%).
- LCP على شبكة 4G متوسطة: من 2.81s لـ 2.18s (-22%).
- تكلفة الـ bandwidth الشهرية: من $94 لـ $71 (-24%).
لاحظ إن الأرقام دي مقاسة بعد إن CDN كان Cloudflare. لو السيرفر بتاعك بيقدّم الـ requests مباشرة بدون CDN، التوفير في الـ bandwidth هيكون أوضح.
الخطوة التالية
افتح terminal على السيرفر بتاعك دلوقتي وشغّل nginx -V 2>&1 | grep brotli. لو طلع فاضي، ثبت الـ module بالأمر اللي فوق. لو طلع --add-module=.../ngx_brotli، Brotli جاهز للتفعيل — كل اللي عليك تضيف الـ 8 سطور دول في nginx.conf. بعد reload، افتح DevTools ثم Network وشوف content-encoding: br في response headers لأي ملف JavaScript. لو شفته، خلصت.