การแยกโค้ดระดับเส้นทางใน Angular

ปรับปรุงประสิทธิภาพของแอปโดยใช้การแยกโค้ดระดับเส้นทาง

โพสต์นี้อธิบายวิธีตั้งค่าการแยกโค้ดระดับเส้นทางในแอปพลิเคชัน Angular ซึ่งจะช่วยลดขนาดกลุ่ม JavaScript และปรับปรุงเวลาในการโต้ตอบได้อย่างมาก

คุณดูตัวอย่างโค้ดได้จากบทความนี้ใน GitHub ตัวอย่างการกำหนดเส้นทาง Eager มีให้บริการใน eager Branch ตัวอย่างการแยกโค้ดระดับเส้นทางอยู่ในสาขาแบบ Lazy Loading

ทำไมการแยกโค้ดจึงมีความสำคัญ

ความซับซ้อนของเว็บแอปพลิเคชันมากขึ้นเรื่อยๆ ทำให้จำนวน JavaScript ที่จัดส่งไปยังผู้ใช้มีจำนวนเพิ่มขึ้นอย่างมาก ไฟล์ JavaScript ขนาดใหญ่อาจหน่วงเวลาการโต้ตอบอย่างเห็นได้ชัด ดังนั้นจึงเป็นทรัพยากรที่มีค่าใช้จ่ายสูง โดยเฉพาะอย่างยิ่งในอุปกรณ์เคลื่อนที่

วิธีที่มีประสิทธิภาพมากที่สุดในการลดขนาดแพ็กเกจ JavaScript โดยไม่ต้องสูญเสียฟีเจอร์ในแอปพลิเคชันของคุณ คือการใช้การแยกโค้ดในเชิงรุก

การแยกโค้ดช่วยให้คุณสามารถแบ่ง JavaScript ของแอปพลิเคชันออกเป็นหลายๆ ส่วนที่เชื่อมโยงกับเส้นทางหรือฟีเจอร์ต่างๆ ที่แตกต่างกัน วิธีนี้จะส่ง JavaScript ที่ต้องการให้กับผู้ใช้ในระหว่างการโหลดแอปพลิเคชันครั้งแรกเท่านั้น เพื่อลดเวลาในการโหลด

เทคนิคการแยกโค้ด

การแยกโค้ดทำได้ใน 2 ระดับ ได้แก่ ระดับคอมโพเนนต์และระดับเส้นทาง

  • ในการแยกโค้ดระดับคอมโพเนนต์ คุณจะย้ายคอมโพเนนต์ไปยังกลุ่ม JavaScript ของตัวเองและโหลดอย่างช้าๆ เมื่อจำเป็นต้องใช้
  • ในการแยกโค้ดระดับเส้นทาง คุณจะรวมฟังก์ชันการทำงานของแต่ละเส้นทางไว้เป็นกลุ่มแยกกัน เมื่อผู้ใช้ไปยังส่วนต่างๆ ของแอปพลิเคชัน ผู้ใช้จะดึงข้อมูลส่วนที่เกี่ยวข้องกับเส้นทางแต่ละเส้นทาง และรับฟังก์ชันการทำงานที่เกี่ยวข้องเมื่อต้องการ

โพสต์นี้มุ่งเน้นที่การตั้งค่าการแยกระดับเส้นทางใน Angular

แอปพลิเคชันตัวอย่าง

ก่อนที่จะเจาะลึกวิธีใช้การแยกโค้ดระดับเส้นทางใน Angular มาดูตัวอย่างแอปกัน

ตรวจสอบการติดตั้งใช้งานโมดูลของแอป ภายใน AppModule มีการกำหนดไว้ 2 เส้นทาง ได้แก่ เส้นทางเริ่มต้นที่เชื่อมโยงกับ HomeComponent และ nyan เส้นทางที่เชื่อมโยงกับ NyanComponent ดังนี้

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

การแยกโค้ดระดับเส้นทาง

หากต้องการตั้งค่าการแยกโค้ด คุณต้องเปลี่ยนโครงสร้างเส้นทางที่ต้องการ nyan ใหม่

Angular CLI เวอร์ชัน 8.1.0 ทำทุกอย่างให้คุณได้ด้วยคำสั่งนี้

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)
}

มีข้อแตกต่างสำคัญ 2 ประการจากความกระตือรือร้น นั่นก็คือ

  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 แบบ Lazy Loading ในสภาพแวดล้อมในเครื่องของคุณ ให้ทำดังนี้

  1. กด "Control+Shift+J" (หรือ "Command+Option+J" ใน Mac) เพื่อเปิดเครื่องมือสำหรับนักพัฒนาเว็บ
  2. คลิกแท็บเครือข่าย

  3. คลิก NYAN ในแอปตัวอย่าง

  4. โปรดทราบว่าไฟล์ nyan-nyan-module.js จะปรากฏในแท็บเครือข่าย

การโหลดแบบ Lazy Loading ของแพ็กเกจ 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. ใช้เครื่องมือสร้างโมดูลแบบ Lazy Loading ของ Angular CLI เพื่อสร้างเส้นทางที่โหลดแบบไดนามิกโดยอัตโนมัติ
  2. เพิ่มสัญญาณบอกสถานะการโหลดเมื่อผู้ใช้ไปยังเส้นทางแบบ Lazy Loading เพื่อแสดงว่ามีการดำเนินการที่ดำเนินอยู่