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

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

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

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

المنصة

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

الدعم

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

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

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

Brotli مش gzip: قلّل JS من 420KB لـ 96KB بدون لمس الكود

📅 ٢٥ أبريل ٢٠٢٦⏱ 4 دقائق قراءة
Brotli مش gzip: قلّل JS من 420KB لـ 96KB بدون لمس الكود

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 متوسطة، خصوصًا لو المستخدم أول مرة يفتح الموقع.

مخطط يوضح ضغط ملفات JavaScript وCSS مسبقًا ثم إرسالها للمتصفح عبر Content-Encoding

المفهوم بمثال بسيط

اعتبر إن عندك تقرير طويل هتبعته بالإيميل. ممكن تبعته كما هو، أو تضغطه في ملف ZIP. المستقبل يفك الضغط ويقرأ نفس التقرير. ده بالظبط اللي بيحصل مع gzip وBrotli، لكن على مستوى HTTP.

المتصفح يرسل في الطلب header اسمه Accept-Encoding. لو المتصفح كاتب br أو gzip، السيرفر يقدر يرد بملف مضغوط ويضيف Content-Encoding: br أو Content-Encoding: gzip. حسب MDN، هذا تفاوض محتوى عادي بين العميل والسيرفر، وليس تغييرًا في الملف الأصلي.

الفرق المهم: الضغط الديناميكي يعمل وقت كل request، بينما pre-compression يعمل وقت الـ build. أفضل طريقة هنا إنك تضغط الملفات مرة واحدة بعد البناء، وتخلي Nginx أو الـ CDN يقدّم النسخة الجاهزة.

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

  1. ابنِ المشروع كالمعتاد: npm run build.
  2. اضغط الملفات النصية إلى .br و.gz بعد الـ build.
  3. فعّل Nginx لكي يرسل gzip ويبحث عن الملفات المضغوطة مسبقًا.
  4. تحقق من Content-Encoding باستخدام curl.
Bash
# داخل مجلد 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 مثل:

Content-Encoding: br
Vary: Accept-Encoding

إعداد Nginx قابل للنسخ

لو Nginx عندك يدعم gzip static، استخدم الإعداد التالي كبداية. Brotli في Nginx غالبًا يحتاج module إضافي أو دعم من الـ CDN، لذلك لو الاستضافة عندك فيها Cloudflare أو Fastly أو BunnyCDN، فعّل Brotli من هناك بدل ما تركّب module بنفسك.

server {
  listen 443 ssl http2;
  server_name example.com;

  root /var/www/app/dist;

  gzip on;
  gzip_static on;
  gzip_vary on;
  gzip_comp_level 6;
  gzip_min_length 1024;
  gzip_types text/plain text/css application/javascript application/json image/svg+xml;

  location / {
    try_files $uri $uri/ /index.html;
  }
}

الـ trade-off هنا واضح. gzip_comp_level 6 متوازن للإنتاج. هتكسب حجم نقل أقل، لكن لو فعلت ضغط ديناميكي عالي جدًا على CPU ضعيف، ممكن تزود زمن الاستجابة تحت الضغط. لذلك pre-compression أفضل للملفات static.

الأرقام قبل وبعد

في مثال واقعي لملف main.js حجمه 420KB، gzip نزله إلى 118KB، وBrotli نزله إلى 96KB. هذه أرقام تقريبية لكنها قريبة من اللي هتشوفه مع JavaScript وCSS لأنهم ملفات نصية قابلة للضغط.

مخطط أعمدة يقارن حجم ملف JavaScript قبل الضغط وبعد gzip وبعد Brotli

web.dev يذكر أن Brotli قد يعطي نتائج أصغر من gzip للنصوص، خصوصًا JavaScript وHTML وCSS. لكن ركز: الحجم الأصغر لا يعني دائمًا استجابة أسرع لو الضغط يتم لحظيًا على كل طلب. لذلك كرر القياس عندك.

متى لا تستخدم هذه الطريقة

لا تضغط صور JPEG أو PNG أو AVIF بهذه الطريقة. الملفات دي مضغوطة بالفعل، وMDN يوضح أن إعادة ضغط بيانات مضغوطة قد لا تقلل الحجم، بل قد تزوده. لا تستخدمها أيضًا لو الـ CDN عندك يضغط كل شيء تلقائيًا وأنت لا تتحكم في headers، لأنك قد تضيع وقت build بدون مكسب واضح.

كذلك لا تبدأ بـ Brotli quality 11 على كل request ديناميكي. استخدمه للـ static pre-compression. لو عندك API JSON يتغير باستمرار، gzip أو Brotli dynamic بجودة متوسطة قد يكون كافيًا، والقرار هنا لازم يتقاس بـ p95 latency وCPU.

مصادر اعتمد عليها المقال

  • MDN: Accept-Encoding وContent-Encoding
  • web.dev: ضغط النصوص باستخدام Brotli
  • Nginx: ngx_http_gzip_module
  • Node.js: zlib وBrotli APIs

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

الخطوة التالية: افتح Network tab، اختار أكبر ملف JavaScript أو CSS، وسجّل حجمه بدون ضغط ومع Content-Encoding. لو الفرق أكبر من 60%، فعّل pre-compression في الـ build قبل أي refactor.

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

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

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