أداء المواقع · تحسين JavaScript

تقليل حجم ملفات JavaScript: تقنيات عملية لتسريع تحميل الصفحات

تعرف إلى طرق تقليل حجم ملفات JavaScript عبر إزالة الكود غير المستخدم والضغط وتقسيم الحزم والتحميل عند الحاجة، مع أمثلة وخطوات قياس عملية.

تقليل حجم ملفات JavaScript — شاشة برمجة وأكواد لتحسين سرعة تحميل الصفحات
تقنيات عملية لتقليل JavaScript الذي تحمّله الصفحة وتنفّذه عند البداية.

قد تبدو صفحة الويب سريعة عند فتحها على حاسوب المطوّر، ثم تصبح ثقيلة على هاتف متوسط أو اتصال بطيء. في حالات كثيرة لا تكون المشكلة في عدد الأسطر المكتوبة فقط، بل في كمية JavaScript التي يضطر المتصفح إلى تنزيلها وتحليلها وتجهيزها للتنفيذ وتشغيلها قبل أن تستجيب الواجهة بسلاسة.

تقليل حجم ملفات JavaScript لا يعني ضغط الكود عشوائيًا أو حذف وظائف يحتاجها المستخدم. الهدف هو إرسال أقل قدر ممكن من الكود الضروري لكل صفحة، وتأجيل ما يمكن تأجيله، ثم قياس النتيجة. يتناول هذا الدليل التقنيات الأكثر فائدة، سواء كنت تعمل بموقع تقليدي أو تطبيق مبني بأداة مثل Vite أو webpack.

لماذا يؤثر حجم JavaScript في سرعة الموقع؟

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

يمكن أن تؤدي الحزم الكبيرة إلى تأخر ظهور التفاعل الأول، أو تجميد قصير للواجهة أثناء التنفيذ، خصوصًا على الأجهزة محدودة القدرة. ويرتبط تقليل العمل على المسار الرئيسي بتحسين استجابة الصفحة، وقد يساعد في تحسين مقياس INP عندما يكون JavaScript الزائد سببًا للمشكلة. لا توجد نسبة تحسن مضمونة؛ النتيجة تعتمد على التطبيق والجهاز والشبكة.

1. قِس حجم الملفات قبل إجراء التغييرات

ابدأ بأدوات المتصفح بدل التخمين. افتح Chrome DevTools ثم تبويب Network، وأعد تحميل الصفحة مع تفعيل تعطيل الذاكرة المؤقتة أثناء الاختبار. رشّح الطلبات إلى JS وراجع الحجم المنقول، والحجم الفعلي، ووقت التنزيل. بعد ذلك افتح Coverage من قائمة الأدوات لتعرف مقدار الكود الذي لم يُستخدم في المسار الذي اختبرته.

استخدم Lighthouse أو PageSpeed Insights لتحديد الملفات التي تستهلك وقتًا في التنفيذ، لكن لا تعتبر التحذير وحده دليلًا على سبب المشكلة. اختبر الصفحة الرئيسية وصفحة داخلية وتفاعلًا فعليًا، لأن الكود غير المستخدم أثناء تحميل الصفحة قد يكون ضروريًا بعد فتح قائمة أو إرسال نموذج.

2. احذف الاعتماديات والكود غير المستخدم

راجع الحزم في package.json، وابحث عن مكتبات أضيفت لتجربة قصيرة أو استُبدلت ببديل أخف. حذف اعتماد غير مستخدم أفضل من محاولة ضغطه. كذلك راجع الدوال والملفات القديمة التي لم تعد تستدعى، وتجنب تحميل مكتبة كاملة من أجل وظيفة صغيرة يمكن تنفيذها بواجهة المتصفح الأصلية.

لا تحذف كودًا لمجرد أن Coverage أظهره باللون غير المستخدم؛ قد يكون مسارًا نادرًا لم يحدث أثناء الاختبار. كرر الاختبار مع الحالات المهمة، واكتب اختبارات أو قائمة تحقق قبل حذف أي جزء من الوظائف.

3. استخدم Tree Shaking لاستبعاد الصادرات غير المطلوبة

تستطيع أدوات البناء الحديثة حذف أجزاء من المكتبات التي لا يستخدمها المشروع، وهي تقنية تُعرف باسم Tree Shaking. تزداد فعاليتها عندما تكون الوحدات مبنية على ES Modules وتكون الاستيرادات واضحة وثابتة.

// استيراد كل الوظائف قد يجعل تحليل الاستخدام أصعب
import * as helpers from './helpers.js';

// استورد الوظيفة التي تحتاجها فقط
import { formatPrice } from './helpers.js';

console.log(formatPrice(29.9));

هذا التغيير وحده لا يضمن ملفًا أصغر في كل مشروع؛ يجب أن تكون أداة البناء مهيأة لتحسين نسخة الإنتاج، وأن تكون الحزم قابلة للتحليل، وألا تمنع الآثار الجانبية حذف أجزاء غير مستخدمة. اختبر ناتج البناء النهائي ولا تقارن ملفات التطوير بملفات الإنتاج.

4. قسّم الحزم وحمّل الميزات عند الحاجة

بدل إرسال كل وظائف التطبيق عند أول زيارة، قسّم الكود إلى أجزاء بحسب الصفحة أو الميزة. تسمح الاستيرادات الديناميكية بتحميل وحدة عندما يحتاج إليها المستخدم، مثل محرر متقدم أو لوحة رسوم بيانية أو أداة تصدير.

const openReportButton = document.querySelector('#open-report');

openReportButton?.addEventListener('click', async () => {
  try {
    const { renderReport } = await import('./report.js');
    renderReport();
  } catch (error) {
    console.error('تعذر تحميل التقرير', error);
  }
});

في هذا المثال لا يُطلب ملف التقرير إلا عند الضغط على الزر. في تطبيقات الواجهات، يمكن تطبيق المبدأ نفسه على المسارات أو المكونات الثقيلة. انتبه إلى عرض حالة تحميل مناسبة، والتعامل مع فشل الشبكة، وتجنب تقسيم كل دالة صغيرة إلى ملف مستقل؛ كثرة الطلبات قد تضيف تكلفة اتصال وتزيد تعقيد التخزين المؤقت.

5. صغّر الملفات واضغطها في الإنتاج

التصغير أو Minification يزيل المسافات والتعليقات غير اللازمة ويختصر بعض الأسماء عندما يكون ذلك آمنًا. أما ضغط النقل باستخدام Brotli أو Gzip فيقلل حجم البيانات المرسلة عبر HTTP. هاتان خطوتان مختلفتان ومتكاملتان: التصغير يغيّر صياغة الملف، والضغط يقلل حجم نقله.

غالبًا ما تتولى أدوات البناء مثل Vite أو webpack إعداد نسخة الإنتاج. تأكد من تشغيل أمر البناء الصحيح، ثم افحص إعدادات الاستضافة أو CDN لمعرفة هل تُرسل ملفات JavaScript مع ضغط مناسب. لا تضغط ملفات مضغوطة مسبقًا مرة أخرى، ولا تنشر ملفات التطوير التي تتضمن خرائط مصدر أو أدوات تشخيص غير لازمة للجمهور إلا إذا كان هناك سبب واضح.

6. حمّل السكريبتات بطريقة لا تعطل تحليل HTML

في المواقع التقليدية، يمكن أن يؤدي سكريبت عادي في رأس الصفحة إلى إيقاف تحليل HTML حتى يُنزّل ويُنفّذ. إذا كان السكريبت لا يحتاج إلى العمل قبل اكتمال تحليل المستند، فاستخدم defer:

<script src="/assets/js/site.js" defer></script>

تُنزّل الملفات ذات defer بالتوازي مع تحليل HTML وتُنفّذ بعد اكتماله، مع الحفاظ على ترتيب السكريبتات المؤجلة الكلاسيكية. أما async فيناسب ملفات مستقلة لا تعتمد على ترتيب تنفيذ محدد. لا تبدّل بينهما دون فهم الاعتماديات؛ فقد يؤدي ذلك إلى أخطاء إذا احتاج ملف إلى مكتبة لم تُنفّذ بعد.

7. راجع مكتبات الطرف الثالث

أدوات التحليلات والإعلانات والدردشة ومقاطع الفيديو قد تضيف JavaScript من مصادر خارجية. راجع ما تستخدمه فعلًا، وأزل التكرار، وحمّل الأدوات غير الأساسية بعد موافقة المستخدم أو عند الحاجة حيثما كان ذلك مناسبًا للخصوصية ومتطلبات الخدمة. يمكن مثلًا عدم إنشاء مشغل فيديو كامل قبل أن يضغط الزائر على زر التشغيل.

لا تؤخر سكريبتًا ضروريًا للوظائف أو الامتثال لمجرد تحسين نتيجة الاختبار. افحص أيضًا ما إذا كانت المكتبة محمّلة مرتين بإصدارات مختلفة، وما إذا كان بالإمكان استخدام ميزة أصلية في المتصفح بدل إضافة اعتماد جديد.

8. فعّل التخزين المؤقت بأسماء ملفات مناسبة

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

لا تجعل التخزين المؤقت بديلًا عن تقليل الكود؛ الزائر الجديد لا يملك نسخة مخزنة بعد، كما أن المستخدم قد يزور صفحة تحتاج إلى حزمة جديدة. توازن بين حجم الحزم، وعدد الطلبات، وإمكانية إعادة استخدامها عبر الصفحات.

9. قارن النتائج بطريقة صحيحة

سجّل خط الأساس قبل التعديل، ثم غيّر عاملًا واحدًا في كل مرة. قارن حجم JavaScript المنقول، وحجم الحزمة غير المضغوط، ووقت التنفيذ، واستجابة التفاعل. أعد الاختبار أكثر من مرة وفي ظروف متقاربة، وراقب بيانات المستخدمين الفعلية بعد النشر عندما تكون متاحة.

  • هل انخفض حجم JavaScript الذي يُحمّل عند بداية الصفحة؟
  • هل بقيت النماذج والقوائم والتفاعلات تعمل؟
  • هل زادت الطلبات أو تأخر تحميل ميزة مهمة بعد تقسيم الحزم؟
  • هل تحسنت استجابة التفاعل على هاتف فعلي أو محاكاة مناسبة؟

للمزيد عن الصورة الكاملة للأداء، راجع دليل تحسين سرعة الموقع وشرح Core Web Vitals. ولتحسين طريقة تحميل الموارد من HTML، اطلع على دليل أداء HTML وخصائص التحميل.

خطة تنفيذ سريعة للمشروع

  1. افحص Network وCoverage وحدد أكبر الملفات وأقلها استخدامًا.
  2. أزل المكتبات المكررة والوظائف القديمة بعد التأكد من عدم الحاجة إليها.
  3. فعّل Tree Shaking والتصغير في نسخة الإنتاج وتحقق من إعدادات الضغط.
  4. قسّم الميزات الثقيلة واستخدم التحميل الديناميكي حيث يكون منطقيًا.
  5. راجع ترتيب تحميل السكريبتات ومكتبات الطرف الثالث والتخزين المؤقت.
  6. أعد الاختبارات الوظيفية وقارن النتائج قبل النشر وبعده.

الخلاصة

أفضل طريقة لتقليل حجم ملفات JavaScript هي ألا ترسل للمستخدم كودًا لا يحتاج إليه في اللحظة الحالية. ابدأ بالقياس، ثم نظّف الاعتماديات، واستفد من Tree Shaking وتقسيم الحزم والتصغير والضغط، وحمّل الميزات الثقيلة عند الطلب. لا تعتمد على رقم الحجم وحده؛ النجاح الحقيقي هو صفحة أسرع مع بقاء جميع الوظائف المهمة سليمة.

الكاتب وصاحب الموقع: imad limrani

مراجع تقنية