تقسيم الرمز على مستوى المسار بتنسيق Angular

يمكنك تحسين أداء تطبيقك باستخدام ميزة "تقسيم الرموز على مستوى المسار".

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

يمكنك العثور على نماذج الرموز البرمجية من هذه المقالة على GitHub. يتوفر مثال التوجيه السريع في الفرع الصحيح. يمكنك العثور على مثال على تقسيم الرموز على مستوى المسار في الفرع المُهمّل.

أهمية تقسيم الرموز البرمجية

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

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

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

تقنيات تقسيم الرمز

يمكن تقسيم الرموز على مستويَين: مستوى المكوّن ومستوى المسار.

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

تركّز هذه المشاركة على إعداد عملية التقسيم على مستوى المسار في Angular.

نموذج طلب

قبل التعرّف على كيفية استخدام تقسيم الرموز على مستوى المسار في Angular، سنتعرّف على نموذج تطبيق:

راجِع عملية تنفيذ وحدات التطبيق. في AppModule، تم تحديد مسارَين: المسار التلقائي المرتبط بـ HomeComponent ومسار nyan المرتبط بـ NyanComponent:

@NgModule({
  ...
  imports: [
    BrowserModule,
    RouterModule.forRoot([
      {
        path: '',
        component: HomeComponent,
        pathMatch: 'full'
      },
      {
        path: 'nyan',
        component: NyanComponent
      }
    ])
  ],
  ...
})
export class AppModule {}

تقسيم الرموز على مستوى المسار

لإعداد ميزة "تقسيم الرموز البرمجية"، يجب إعادة تنظيم المسار السريع nyan.

يمكن للإصدار 8.1.0 من Angular CLI تنفيذ كل الإجراءات نيابةً عنك باستخدام هذا الأمر:

ng g module nyan --module app --route nyan

سيؤدي ذلك إلى إنشاء ما يلي: - وحدة توجيه جديدة باسم NyanModule - مسار في AppModule باسم nyan سيحمِّل NyanModule ديناميكيًا - مسار تلقائي في NyanModule - مكوّن باسم NyanComponent سيتم عرضه عندما يضغط المستخدم على المسار التلقائي

لنطّلِع على هذه الخطوات يدويًا لنفهم بشكل أفضل عملية تنفيذ تقسيم الرموز البرمجية باستخدام Angular.

عندما ينتقل المستخدم إلى مسار nyan، سيعرض جهاز التوجيه NyanComponent في مقبس جهاز التوجيه.

لاستخدام ميزة تقسيم الرموز البرمجية على مستوى المسار في Angular، اضبط السمة loadChildren لبيان المسار واجمعها مع استيراد ديناميكي:

{
  path: 'nyan',
  loadChildren: () => import('./nyan/nyan.module').then(m => m.NyanModule)
}

هناك اختلافان رئيسيان عن المسار السريع:

  1. تم ضبط loadChildren بدلاً من component. عند استخدام ميزة "تقسيم الرموز على مستوى المسار"، عليك الإشارة إلى الوحدات المحمَّلة ديناميكيًا بدلاً من المكونات.
  2. في loadChildren، بعد حلّ الوعد، يمكنك عرض NyanModule بدلاً من الإشارة إلى NyanComponent.

يحدّد المقتطف أعلاه أنّه عندما ينتقل المستخدم إلى nyan، يجب أن يحمّل Angular nyan.module ديناميكيًا من دليل nyan وأن يعرض المكوِّن المرتبط بالمسار التلقائي المعلَن في الوحدة.

يمكنك ربط المسار التلقائي بمكوّن باستخدام هذا البيان:

import { NgModule } from '@angular/core';
import { NyanComponent } from './nyan.component';
import { RouterModule } from '@angular/router';

@NgModule({
  declarations: [NyanComponent],
  imports: [
    RouterModule.forChild([{
      path: '',
      pathMatch: 'full',
      component: NyanComponent
    }])
  ]
})
export class NyanModule {}

يعرض هذا الرمز NyanComponent عندما ينتقل المستخدم إلى https://example.com/nyan.

للتحقّق من أنّ "مخطّط توجيه Angular" ينزِّل nyan.module بشكلٍ كسول في بيئتك المحلية:

  1. اضغط على Ctrl ‏+ Shift ‏+ J (أو Command ‏+ Option ‏+ J على نظام التشغيل Mac) لفتح DevTools.
  2. انقر على علامة التبويب الشبكة.

  3. انقر على NYAN في نموذج التطبيق.

  4. لاحظ أن ملف nyan-nyan-module.js يظهر في علامة التبويب "الشبكة".

التحميل البطيء لحِزم JavaScript من خلال تقسيم الرموز على مستوى المسار

يمكنك العثور على هذا المثال على GitHub.

عرض مؤشر تقدم

في الوقت الحالي، عندما ينقر المستخدم على الزر NYAN، لا يشير التطبيق إلى أنّه يُحمِّل JavaScript في الخلفية. لمنح المستخدم ملاحظات أثناء تحميل النص البرمجي، من الأفضل إضافة مؤشر سريان العمل.

لإجراء ذلك، ابدأ بإضافة علامة للمؤشر داخل عنصر router-outlet في app.component.html:

<router-outlet>
  <span class="loader" *ngIf="loading"></span>
</router-outlet>

بعد ذلك، أضِف فئة AppComponent لمعالجة أحداث التوجيه. ستضبط هذه الفئة علامة loading على true عند سماع الحدث RouteConfigLoadStart وستضبط العلامة على false عند سماع الحدث RouteConfigLoadEnd.

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  loading: boolean;
  constructor(router: Router) {
    this.loading = false;
    router.events.subscribe(
      (event: RouterEvent): void => {
        if (event instanceof NavigationStart) {
          this.loading = true;
        } else if (event instanceof NavigationEnd) {
          this.loading = false;
        }
      }
    );
  }
}

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

الخاتمة

يمكنك تصغير حجم حِزم تطبيقات Angular من خلال تطبيق ميزة "تقسيم الرموز على مستوى المسار":

  1. استخدِم أداة إنشاء الوحدات ذات التحميل الكسول في Angular CLI لتوفير الدعم التلقائي لمسار يتم تحميله ديناميكيًا.
  2. أضِف مؤشر تحميل عندما ينتقل المستخدم إلى مسار بطيء لعرض أنّ هناك إجراءً جاريًا.