ปรับปรุงประสิทธิภาพของแอปโดยใช้การแยกโค้ดระดับเส้นทาง
โพสต์นี้อธิบายวิธีตั้งค่าการแยกโค้ดระดับเส้นทางในแอปพลิเคชัน 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 ประการจากความกระตือรือร้น นั่นก็คือ
- คุณตั้งค่า
loadChildren
แทนcomponent
เมื่อใช้การแยกโค้ดระดับเส้นทาง คุณต้องชี้ไปที่โมดูลที่โหลดแบบไดนามิก แทนที่จะเป็นคอมโพเนนต์ - ใน
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 ในสภาพแวดล้อมในเครื่องของคุณ ให้ทำดังนี้
- กด "Control+Shift+J" (หรือ "Command+Option+J" ใน Mac) เพื่อเปิดเครื่องมือสำหรับนักพัฒนาเว็บ
คลิกแท็บเครือข่าย
คลิก NYAN ในแอปตัวอย่าง
โปรดทราบว่าไฟล์
nyan-nyan-module.js
จะปรากฏในแท็บเครือข่าย
ดูตัวอย่างนี้ได้ใน 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 ได้โดยใช้การแยกโค้ดระดับเส้นทาง
- ใช้เครื่องมือสร้างโมดูลแบบ Lazy Loading ของ Angular CLI เพื่อสร้างเส้นทางที่โหลดแบบไดนามิกโดยอัตโนมัติ
- เพิ่มสัญญาณบอกสถานะการโหลดเมื่อผู้ใช้ไปยังเส้นทางแบบ Lazy Loading เพื่อแสดงว่ามีการดำเนินการที่ดำเนินอยู่