تقسيم الرمز على مستوى المسار بتنسيق 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. أضِف مؤشر تحميل عندما ينتقل المستخدم إلى مسار بطيء لعرض أنّ هناك إجراءً جاريًا.