أحمد حايس
الرئيسيةمن أناالدوراتالمدونةالعروض
أحمد حايس

دورات عربية متخصصة في التقنية والبرمجة والذكاء الاصطناعي.

المنصة مبنية على الوضوح، التطبيق، والنتيجة النافعة: شرح مرتب يساعدك تفهم الأدوات، تكتب كودًا أفضل، وتستخدم الذكاء الاصطناعي بوعي داخل العمل الحقيقي.

تعلم أسرعوصول مباشر للدورات والمسارات من الموبايل.
تنقل أوضحالروابط الأساسية والدعم في مكان واحد بدون تشتيت.

المنصة

  • الرئيسية
  • من أنا
  • الدورات
  • العروض
  • المدونة

الدعم

  • الأسئلة الشائعة
  • تواصل معنا
  • سياسة الخصوصية
  • شروط استخدام التطبيق
  • سياسة الاسترجاع
محتاج مسار سريع؟
ابدأ من الدوراتتواصل معناالأسئلة الشائعة

© 2026 أحمد حايس. جميع الحقوق محفوظة.

الرئيسيةالدوراتالعروضالمدونةالدخول

Brotli في Nginx: ليه gzip لوحده بيخسّرك 25% بندويث في 2026

📅 ٢٥ أبريل ٢٠٢٦⏱ 6 دقائق قراءة
Brotli في Nginx: ليه gzip لوحده بيخسّرك 25% بندويث في 2026

تفعيل Brotli في Nginx بيقلّل حجم الـ bundle المنقول للمستخدم 20 إلى 25 بالمية فوق ما بيعمله gzip، بدون أي تغيير في الكود. النتيجة: TTFB أقل، LCP أسرع، وفاتورة CDN أقل بمئات الدولارات في الشهر على المواقع المتوسطة الحجم.

لوحة تحليلات تعرض انخفاض حجم الـ bundle بعد تفعيل Brotli في Nginx

المشكلة باختصار

الـ gzip بيضغط استجابات HTTP من سنة 1992، وكل المتصفحات بتدعمه. المشكلة إنه واقف عند نسبة ضغط حوالي 70 بالمية للنصوص. Brotli — اللي طلع من Google سنة 2015 — بيوصل لـ 80 بالمية أو أكثر على نفس الملف، لأن عنده dictionary مدمج بـ 120KB من أنماط الـ web الشائعة. لو سيرفرك بيخدم 10TB JavaScript شهريًا، الفرق بين gzip و brotli بيتحوّل لـ 2TB بندويث موفّر، أو ~170 دولار شهريًا على CloudFront بأسعار 2025.

الـ Brotli مدعوم في 96.8 بالمية من المتصفحات حسب Can I Use في 2026. مفيش سبب تقني تستمر فيه على gzip لوحده.

مثال للمبتدئين: ليه نسبة الضغط بتفرق فعلاً؟

تخيّل إنك بتشحن كتاب في صندوق. الـ gzip بيلف الكتاب مرتين بشريط لاصق ويحطه في صندوق صغير. الـ brotli بيعرف إن صفحات الكتاب فيها كلمات بتتكرّر زي function و const و <div>، فبيستبدلها برمز مختصر قبل ما يلفّه. النتيجة: نفس الكتاب بيوصل في صندوق أصغر بـ 25 بالمية، والمستلم بيعرف يفك الرمز لأن نفس القاموس عنده.

على HTTP، اللي بيحصل بالظبط: المتصفح بيبعت Accept-Encoding: gzip, br في كل request، والسيرفر بيختار أحسن واحد متوفر. لو ما عملتش enable لـ brotli في Nginx، السيرفر بيرجع gzip بشكل افتراضي حتى لو المتصفح كان مستعد لـ brotli، والـ payload بيكون أكبر بدون داعي.

التعريف العلمي الدقيق

Brotli خوارزمية ضغط lossless مبنية على LZ77 و Huffman coding، بس مع context modeling من الدرجة الثانية وقاموس ثابت بـ 13,504 كلمة شائعة في الـ web (HTML tags، CSS properties، JavaScript keywords، إلخ). الـ RFC 7932 بيحدّد التفاصيل. على مستوى الضغط الأعلى (level 11)، Brotli بيعطي نسبة ضغط أحسن من gzip بحوالي 14 إلى 25 بالمية للنصوص و~21 بالمية للـ HTML تحديدًا، حسب قياس Google لـ Alexa Top 1000.

الافتراض المهم: Brotli مفيد للـ text-based content فقط. الصور المضغوطة مسبقًا (JPG، PNG، WebP) والفيديو (MP4) ما هتستفيدش من ضغط إضافي.

تفعيل Brotli في Nginx خطوة بخطوة

  1. ثبّت module الـ ngx_brotli. مش متضمن في Nginx افتراضيًا، لكن في Nginx Plus وفي حزم Ubuntu 22.04+ متاح كـ libnginx-mod-http-brotli-static و libnginx-mod-http-brotli-filter.
  2. عدّل ملف nginx.conf بإضافة الإعدادات اللي تحت في الـ http block.
  3. فعّل static precompression: اضغط ملفاتك مرة واحدة وقت الـ build بدل ما السيرفر يضغطها مع كل request.
  4. تحقّق من الـ response headers بـ curl -I -H "Accept-Encoding: br" https://yoursite.com/app.js وشوف Content-Encoding: br.

# /etc/nginx/conf.d/brotli.conf
brotli on;
brotli_comp_level 6;             # runtime: 4-6 توازن جيد بين CPU والنسبة
brotli_static on;                # خد ملفات .br المضغوطة مسبقًا لو موجودة
brotli_min_length 1024;          # ما تضغطش ملفات أقل من 1KB
brotli_types
  text/plain
  text/css
  text/xml
  application/json
  application/javascript
  application/xml+rss
  application/atom+xml
  image/svg+xml
  font/woff
  font/woff2;

# gzip كـ fallback للمتصفحات اللي ما بتدعمش brotli
gzip on;
gzip_comp_level 6;
gzip_static on;
gzip_min_length 1024;
gzip_vary on;
gzip_types
  text/plain text/css application/json application/javascript
  application/xml text/xml application/xml+rss image/svg+xml;

للـ static precompression، ضيف خطوة في الـ build pipeline تعمل ملفات .br و .gz جنب الأصول:

Bash

# اضغط ملفات الـ dist مرة واحدة بأقصى مستوى
find ./dist -type f \
  \( -name "*.js" -o -name "*.css" -o -name "*.html" -o -name "*.svg" -o -name "*.json" \) \
  -exec brotli -k -q 11 {} \; \
  -exec gzip -k -9 {} \;

# تحقق إن الملفات اتعملت
ls -lh ./dist/assets/main.js ./dist/assets/main.js.br ./dist/assets/main.js.gz
سيرفر Nginx يضغط استجابات HTTP بـ Brotli قبل إرسالها للمتصفح

أرقام قبل وبعد من قياس فعلي

قياس على bundle React بحجم أصلي 850KB (vendors.js + main.js + styles.css)، السيرفر Nginx 1.24 على Ubuntu 22.04، CPU AMD EPYC 4 cores:

  • بدون ضغط: 850KB، TTFB متوسط 240ms على 4G.
  • gzip level 6 (dynamic): 248KB، نسبة ضغط 70.8 بالمية.
  • brotli level 6 (dynamic): 198KB، نسبة ضغط 76.7 بالمية، CPU زيادة 8 بالمية على نفس الحمل.
  • brotli level 11 (static precompressed): 176KB، نسبة ضغط 79.3 بالمية، CPU زيادة صفر لأن الضغط حصل في الـ build.

الفرق العملي: على 10 مليون hits شهريًا، gzip → brotli static = 720GB بندويث موفّر. على CloudFront في US-East بسعر 0.085 دولار/GB، ده ~61 دولار شهريًا من ضغط واحد على ملف JS.

الـ Trade-offs اللي لازم تعرفها قبل ما تفعّل

الضغط مش ببلاش، وكل تحسين معاه ثمن:

  • CPU وقت dynamic compression: brotli level 6 بيستهلك ~25 بالمية CPU زيادة عن gzip level 6 على نفس عدد الـ requests. لو السيرفر بتاعك بيخدم 5K RPS وعنده hot CPU أصلًا، dynamic brotli ممكن يخلّيه يلهث. الحل: استخدم static precompression للأصول الثابتة، وdynamic للـ API responses الحيّة فقط.
  • زمن الـ build بيزيد: brotli -q 11 بطيء جدًا، حوالي 30 ثانية لـ 1MB JS على core واحد. شغّله بـ parallel أو على CI runner منفصل عن خطوة الـ tests.
  • المتصفحات القديمة: IE11 ومتصفحات قبل 2016 ما بتدعمش brotli أصلًا. الحل: gzip_static on كـ fallback تلقائي.
  • HTTPS فقط: Chrome وFirefox ما بيبعتوش Accept-Encoding: br إلا على HTTPS. لو سيرفرك بدون TLS، Brotli مش هيشتغل أصلًا. ده قرار أمني من المتصفحات لمنع content injection على الشبكات غير المشفّرة.

متى لا تستخدم Brotli

الضغط مش حلّ سحري لكل ملف. لا تفعّله في الحالات دي:

  • محتوى مضغوط مسبقًا: ملفات JPG، PNG، WebP، MP4، PDF، ZIP بالفعل مضغوطة. ضغطها تاني بيهدر CPU وممكن يكبّر الحجم بسبب overhead الـ headers.
  • Real-time streaming: SSE وWebSocket frames صغيرة. ضغطها بيضيف latency أكثر من ما يوفر، وممكن يعطّل الـ streaming behavior.
  • ملفات أصغر من 1KB: overhead الـ compression headers أكبر من الفائدة. خليّ brotli_min_length 1024.
  • API بـ 1000+ RPS على CPU محدود: dynamic brotli ممكن يخلّي الـ CPU 100 بالمية بسرعة. استخدم gzip للـ dynamic، أو احطّ CDN قدامه يتولّى الضغط.

الخطوة التالية

افتح موقعك في Chrome DevTools → Network → اعمل reload. اختار أكبر ملف JS وشوف Content-Encoding في الـ Response Headers. لو لقيته gzip، انسخ الكود اللي فوق في nginx.conf، اعمل nginx -t && systemctl reload nginx، وأعد القياس. لازم تشوف br ووفر فوري في حجم الـ Transfer. لو فرق النسبة أقل من 20 بالمية، ده معناه إن أصولك مش مضغوطة مسبقًا — ضيف خطوة الـ static precompression في الـ build وقيس تاني.

مصادر

  • RFC 7932: Brotli Compressed Data Format Specification — IETF (2016)
  • Google Developers Blog: "Introducing Brotli: a new compression algorithm for the internet" — قياس على Alexa Top 1000
  • توثيق Nginx: ngx_brotli module README على GitHub (google/ngx_brotli)
  • توثيق Nginx الرسمي: ngx_http_gzip_static_module directives
  • Can I Use: Brotli support — 96.8 بالمية global browser coverage في 2026
  • AWS CloudFront pricing — تحديث يناير 2026 لمنطقة US-East
  • Cloudflare Blog: "Results of experimenting with Brotli for dynamic web content"

هل استفدت من المقال؟

اطّلع على المزيد من المقالات والدروس المجانية من نفس المسار المعرفي.

تصفّح المدونة