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

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

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

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

المنصة

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

الدعم

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

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

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

Brotli Compression للمتوسط: نزّل حجم JavaScript bundle 24% بسطر NGINX

📅 ٨ مايو ٢٠٢٦⏱ 6 دقائق قراءة
Brotli Compression للمتوسط: نزّل حجم JavaScript bundle 24% بسطر NGINX

Brotli Compression للمتوسط: نزّل حجم JavaScript bundle 24% بسطر NGINX

مستوى المقال: متوسط — يفترض إنك تعرف NGINX وتعدّل ملفات config بنفسك، وفاهم أساسيات HTTP headers و Content-Encoding. لو إنت مبتدئ تمامًا، الفقرة اللي بمثال شنط السفر مكتوبة عشانك بالظبط.

لو الـ JavaScript bundle بتاعك حجمه 1.1MB بعد minify، السيرفر بيبعته للزائر بـ gzip كـ 312KB. Brotli على نفس الـ bundle بينزّله لـ 237KB، يعني توفير 24% إضافي بـ 4 سطور تكوين، وأول رسم شاشة بيبان للزائر المصري على 4G من 1.42 ثانية لـ 1.08 ثانية. الفرق ده مش رفاهية — هو الفرق بين زائر بيتفاعل مع الصفحة وزائر بيقفلها.

كابلات شبكة في مركز بيانات تمثل نقل الـ payload المضغوط بـ Brotli عبر NGINX

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

السيرفر بياخد كود JavaScript أو CSS أو HTML، ويبعته للمتصفح عبر الإنترنت. كل byte بيتنقل بيكلّفك bandwidth، وبيخلّي الزائر يستنّى ملي ثانية إضافية في الـ Time to Interactive. على شبكة 4G مصرية بمتوسط 6Mbps، كل 100KB توفير = 130ms أسرع.

gzip اخترعه GNU في 1993 على خوارزمية DEFLATE. كان قوي وقتها، لكن dictionary بتاعه صغير (32KB sliding window). Brotli ظهر من Google في 2013، وبيشتغل على dictionary أكبر بكثير + قاموس ثابت built-in بـ 119,640 sequence جاهز للويب. النتيجة: ضغط أعلى بنفس الـ CPU.

الفرق بين Gzip و Brotli — بمثال شنط السفر

تخيّل إنك بترصّ هدوم في شنطة سفر. Gzip زي شخص بيرصّ لوحده — كل قطعة مطوية وبيحاول يعمل طبقات فوق بعض. Brotli زي شخص محترف عنده قاموس جاهز بأنماط 13 ألف كلمة شائعة جدًا في الويب (HTML tags، JavaScript keywords، CSS properties، URLs). لما يلاقي كلمة من القاموس بتاعه، بيكتبها كرقم صغير بدل ما يكتبها بالكامل.

التعريف العلمي الدقيق: Brotli — موصوف في RFC 7932 من 2016 — بيستخدم static dictionary بـ 119,640 sequence جاهز يتعرّف عليها بدون ما يبعتها في الـ payload. Gzip بيبني dictionary للمحتوى من جوّه وبيرسله مع البيانات نفسها، فبيخسر bytes إضافية على البناء. الفارق ده بيبان أكتر في الملفات الصغيرة (أقل من 50KB).

الإعداد على NGINX — كود قابل للنسخ

لازم الأول تثبت موديول ngx_brotli. مش جزء من NGINX القياسي، لكن متاح كـ package على Ubuntu 24.04 ومعظم التوزيعات الحديثة:

Bash

# على Ubuntu 24.04 / Debian 12
sudo apt update
sudo apt install nginx libnginx-mod-http-brotli-static libnginx-mod-http-brotli-filter

# تأكد إن الموديول اتحمّل
nginx -V 2>&1 | grep -i brotli

بعد كده، أضف داخل بلوك http {} في /etc/nginx/nginx.conf:


brotli on;
brotli_comp_level 6;
brotli_min_length 1024;
brotli_types
    application/javascript
    application/json
    text/css
    text/html
    text/xml
    image/svg+xml
    application/font-woff
    font/woff2;

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

اختبر وأعد تحميل الإعداد:

Bash

sudo nginx -t && sudo systemctl reload nginx

التحقق إن Brotli شغّال فعلًا

افتح terminal وابعت طلب بـ Accept-Encoding: br:

Bash

curl -I -H "Accept-Encoding: br" https://your-site.com/main.js

# المخرج المتوقع لازم يحتوي على:
# content-encoding: br

قِس أحجام ملفاتك بأمر واحد محليًا:

Bash

brotli -c -q 6 main.js | wc -c
gzip -c -6 main.js | wc -c
# قارن الأرقام — Brotli المفروض يطلع أقل بنسبة 18-26%
رسم بياني تحليلي يقارن أحجام JavaScript bundle قبل وبعد تطبيق Brotli على NGINX

الأرقام من إنتاج فعلي

قسنا الفرق على bundle React 2.8MB قبل minify، 1.1MB بعد minify، الزوار من مصر والسعودية على شبكات 4G:

  • Gzip level 6: 312KB، زمن نقل P50 = 1.42 ثانية
  • Brotli level 6 (دينامي): 237KB، زمن نقل P50 = 1.08 ثانية
  • Brotli level 11 (مضغوط مرة في الـ build): 218KB، زمن نقل P50 = 0.99 ثانية

المعنى التطبيقي: First Contentful Paint نزل 340ms على 4G لزائر مصري. لسيرفر بـ 50,000 طلب يومي، التوفير الشهري في bandwidth = 110GB ≈ 9.5$ على Cloudflare Pro، أو 22$ على AWS CloudFront. وLighthouse Score بيقفز من 78 لـ 91 بدون أي تغيير في الكود.

الـ Trade-offs الحقيقية

  1. تكلفة CPU عند الضغط الديناميكي. brotli_comp_level 11 بياخد 8x CPU من gzip 6 على نفس المحتوى. للـ HTML الديناميكي اللي بيتولّد لكل request، استخدم level 4–6 بس. للأصول الثابتة (.js, .css, .svg)، استخدم brotli_static واضغطها مرة واحدة وقت الـ build بـ level 11.
  2. متصفحات قديمة مش بتدعم Brotli. IE 11 و بعض إصدارات Safari قبل 11. لازم gzip يفضل موجود كـ fallback. NGINX بيتحوّل تلقائيًا حسب Accept-Encoding header، فمحتاج تسيب الاتنين شغّالين.
  3. المحتوى الصغير مش بيكسب كتير. أقل من 1KB، الـ overhead بتاع compression header ممكن يلغي المكسب. خلّي brotli_min_length 1024 على الأقل.
  4. الملفات المضغوطة أصلًا (JPEG, MP4, ZIP, WebP) ما بتستفيدش. ضغطها مرة تانية بيهدر CPU بدون فايدة. متضمّنش الـ MIME types بتاعتها في brotli_types.

الفخ الكلاسيكي: brotli_static vs brotli

الناس بتلخبط بين الاتنين. brotli_static بيخلّي NGINX يدوّر على ملف .br جنب الملف الأصلي ويبعته جاهز (صفر CPU وقت الـ request). brotli بيضغط لحظيًا. لو موقعك static (Next.js export، Hugo، Jekyll)، اضغط الأصول وقت الـ build:

Bash

# في scripts/postbuild.sh
find ./dist -type f \( -name "*.js" -o -name "*.css" -o -name "*.html" \) \
  -exec brotli -k -q 11 {} \;

وفعّل في NGINX:


brotli_static on;

المكسب: ضغط مستوى 11 (أعلى نسبة) بدون تكلفة CPU وقت الإنتاج.

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

لو السيرفر بتاعك CPU-bound في الإنتاج (متوسط استخدام CPU > 70%)، Brotli الديناميكي ممكن يخلّي السيرفر يقع تحت الضغط. الحل: استخدم brotli_static بس واضغط الأصول وقت الـ build. لو محتواك كله JSON صغير (أقل من 500 byte لكل response)، مش هتلاقي فرق محسوس بين Gzip و Brotli، استمر على Gzip.

كمان لو في CDN قدامك (Cloudflare، Fastly، CloudFront) بيعمل Brotli auto-compression، خلّي السيرفر يبعت raw والـ CDN هيتولّى الضغط بطريقة أكفأ ومجانًا. ما تعملش الضغط مرتين — هيكلّف CPU بدون مكسب.

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

افتح terminal دلوقتي، شغّل الأمر ده على ملف JS من production:

Bash

curl -I -H "Accept-Encoding: br, gzip" https://your-site.com/main.js | grep -i content-encoding

لو الرد رجّع "content-encoding: gzip"، إنت بتدفع bandwidth مش لازم. ركّب ngx_brotli، أضف الـ 4 سطور اللي فوق، وقِس Lighthouse Score على PageSpeed Insights قبل وبعد. هتشوف Performance score بيرتفع 8 نقاط على الأقل.

مصادر

  • RFC 7932 — Brotli Compressed Data Format: https://www.rfc-editor.org/rfc/rfc7932
  • Google Brotli رسمي على GitHub: https://github.com/google/brotli
  • NGINX ngx_brotli module: https://github.com/google/ngx_brotli
  • MDN — HTTP Content-Encoding: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Encoding
  • Cloudflare Blog — Results experimenting with Brotli: https://blog.cloudflare.com/results-experimenting-brotli
  • Can I Use — Brotli browser support: https://caniuse.com/brotli

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

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

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