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

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

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

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

المنصة

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

الدعم

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

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

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

CI بطيء؟ npm cache في GitHub Actions ينزل install لـ 55 ثانية

📅 ٢٥ أبريل ٢٠٢٦⏱ 4 دقائق قراءة
CI بطيء؟ npm cache في GitHub Actions ينزل install لـ 55 ثانية

CI بطيء؟ npm cache في GitHub Actions ينزل install لـ 55 ثانية

لو كل Pull Request عندك بيستنى 4 دقائق على npm ci، المقال ده هيخليك تقلل الانتظار غالبًا لأقل من دقيقة في التشغيلات المتكررة، بدون ما تخبي تغييرات dependencies.

مستوى القارئ: متوسط

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

اللي بيحصل فعلاً إن GitHub Actions بيبدأ غالبًا من runner نظيف. معنى كده إن npm ci بينزل packages من جديد، حتى لو package-lock.json متغيرش من آخر run. في مشروع React أو Next.js متوسط، خطوة التثبيت ممكن تاخد من 3 إلى 5 دقائق، بينما الاختبارات نفسها تاخد أقل من دقيقة.

الطريقة الشائعة الغلط هي إنك تعمل cache لـ node_modules كله. الطريقة دي بتفشل لما نظام التشغيل أو نسخة Node أو lockfile يتغيروا. البديل الأفضل: خلّي actions/setup-node يعمل cache لمجلد npm العالمي، وسيب npm ci يبني node_modules بشكل نظيف من lockfile.

رسم يوضح انخفاض زمن npm ci في GitHub Actions من 250 ثانية إلى 55 ثانية بعد تفعيل cache

مثال واقعي قبل الحل

افترض إن عندك repo فيه 900 dependency، وبيطلع 25 Pull Request في اليوم. لو npm ci بياخد 250 ثانية في كل run، فأنت بتصرف حوالي 104 دقائق يوميًا في تثبيت مكرر. بعد cache hit مستقر، الرقم ممكن ينزل إلى 55–65 ثانية. ده وفر تقريبي 75% في خطوة التثبيت، وليس في كامل الـ pipeline.

ركز في النقطة دي: الـ cache لا يسرّع الاختبارات نفسها. هو يقلل وقت تحميل tarballs وإعادة بناء جزء من dependency install. لو test suite عندك بطيء 12 دقيقة، cache npm مش هيحل أصل المشكلة.

الإعداد العملي

أفضل طريقة في npm هي استخدام actions/setup-node مع cache: 'npm'. الأداة تستخدم lockfile لتوليد cache key، وتستدعي actions/cache تحت الغطاء. مثال workflow كامل:

YAML
name: ci

on:
  pull_request:
  push:
    branches: [main]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6

      - uses: actions/setup-node@v6
        with:
          node-version: 24
          cache: npm
          cache-dependency-path: package-lock.json

      - name: Install dependencies
        run: npm ci

      - name: Run tests
        run: npm test

لو عندك monorepo، متحطش مسار واحد بالغلط. استخدم مسارات lockfiles الفعلية:

YAML
- uses: actions/setup-node@v6
  with:
    node-version: 24
    cache: npm
    cache-dependency-path: |
      apps/web/package-lock.json
      packages/ui/package-lock.json

الافتراض هنا إنك تستخدم npm مع package-lock.json. لو بتستخدم pnpm أو Yarn، نفس الفكرة موجودة، لكن cache input والمسارات تختلف.

إزاي تقيس قبل وبعد

متقولش “الـ CI بقى أسرع” وخلاص. افتح آخر 5 runs قبل التعديل، وسجّل زمن خطوة Install dependencies. بعد التعديل، شغّل pipeline مرتين. أول run غالبًا cache miss وهيكون قريب من القديم. ثاني وثالث run هم اللي يهموك.

رسم خطي يقارن زمن تثبيت npm في خمس تشغيلات CI قبل وبعد استخدام setup-node cache

مثال قياس معقول:

  • قبل cache: 248s، 252s، 246s.
  • أول run بعد التعديل: 251s بسبب cache miss.
  • بعد cache hit: 62s، 55s، 58s.

لو ما شفتش فرق، راجع هل cache-dependency-path صحيح، وهل workflow بيشتغل على نفس branch أو بيرجع للـ default branch cache حسب قواعد GitHub.

الـ trade-off هنا

المكسب واضح: زمن أقل في كل PR وتكلفة Actions أقل لو بتدفع بالدقائق. الثمن: cache storage ممكن يوصل للحد الافتراضي، وGitHub قد يحذف caches غير المستخدمة بعد مدة. كمان cache key غلط ممكن يعمل cache thrashing، يعني caches كتير بتتعمل وتتطرد بدون فائدة.

علشان كده، لا تستخدم key واسع جدًا زي npm-${{ runner.os }} فقط. خليه مربوط بـ lockfile. ولما تغير dependencies، cache جديد يتولد طبيعيًا. ده بالظبط المطلوب.

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

لا تستخدمها لو install step أصلاً أقل من 20 ثانية. التعقيد هنا مش مستاهل. لا تعتمد عليها كحل لمشكلة tests بطيئة أو build بطيء؛ دي مشاكل مختلفة. ولا تعمل cache لـ node_modules في مشروع بيتغير فيه Node version أو native modules كتير، لأن احتمالية الأعطال هتزيد.

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

  • actions/setup-node: caching npm dependencies
  • GitHub Actions dependency caching reference
  • npm ci documentation

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

افتح workflow الأساسي عندك، وضيف cache: npm وcache-dependency-path. بعد 3 runs، قارن زمن خطوة npm ci فقط، مش زمن الـ pipeline كله.

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

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

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