จำลองรายการขนาดใหญ่ด้วย Angular CDK

ทําให้รายการขนาดใหญ่ตอบสนองได้มากขึ้นโดยใช้การเลื่อนเสมือน

Stephen Fluin
Stephen Fluin

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

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

ผู้ใช้อาจประสบปัญหาเมื่อโหลดหรือเลื่อนหน้าเว็บ ซึ่งทําให้ผู้ใช้หงุดหงิดและออกจากหน้าเว็บ

การเลื่อนเสมือนจริงใน Angular ด้วย คอมโพเนนต์ Dev Kit

การเลื่อนเสมือนเป็นเทคนิคหลักที่ใช้ในการจัดการกับปัญหาเกี่ยวกับมาตราส่วนเหล่านี้ การเลื่อนแบบเสมือนจะทำให้รายการมีการแสดงผลขนาดใหญ่มาก โดยใช้แถบเลื่อนที่มีขนาดเหมาะสม และสามารถไปยังส่วนต่างๆ ของรายการได้โดยไม่ต้องมีแอปพลิเคชันเพื่อเก็บรายการทั้งหมดไว้ในหน่วยความจำหรือแสดงผลบนหน้าเว็บ

ใน Angular การเลื่อนเสมือนจะให้บริการโดย Element Dev Kit (CDK) การแก้ไขวิธีทำซ้ำผ่านรายการและเมื่อระบุพารามิเตอร์การกำหนดค่าเพิ่มเติม 2 รายการ การเลื่อนเสมือนของ CDK จะจัดการการแสดงผลเสมือนของรายการโดยอัตโนมัติ ซึ่งจะปรับปรุงประสิทธิภาพและการตอบสนองของหน้าเว็บ

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

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

การตั้งค่าการเลื่อนเสมือน

ก่อนอื่นให้ตรวจสอบว่าคุณได้ติดตั้ง @angular/cdk โดยใช้โปรแกรมจัดการแพ็กเกจที่คุณชื่นชอบ หากต้องการติดตั้งโดยใช้ npm ให้เรียกใช้คำสั่งนี้ในเทอร์มินัล

npm install --save @angular/cdk

เพิ่ม ScrollingModule ลงในแอป

เมื่อติดตั้ง CDK แล้ว ให้นำเข้า ScrollingModule ซึ่งจัดการการเลื่อนเสมือนจากแพ็กเกจ @angular/cdk/scrolling จากนั้นเพิ่มลงในอาร์เรย์นำเข้าของโมดูล โดยทำดังนี้

import {ScrollingModule} from '@angular/cdk/scrolling';

...
imports: [
  ScrollingModule
...
]
...

สร้างวิวพอร์ต

หากต้องการดูวิธีการทำงานของแพ็กเกจ ให้ลองสร้างคอมโพเนนต์ด้วยรายการตัวเลขง่ายๆ ตั้งแต่ 0 ถึง 99,999 ดังนี้

@Component({
  template: `<div *ngFor="let item of list">{{item}}</div>`
})
export class ScrollComponent {
  list = Array.from({length: 100000}).map((_, i) => i);
}

เมื่อแสดงผลแอป เบราว์เซอร์จะต้องแสดงผลองค์ประกอบ <div> ทีละรายการ 100,000 รายการ การทำเช่นนี้อาจใช้ได้ดีสำหรับโหนดข้อความทั่วไป แต่ความซับซ้อนในเทมเพลตที่ซ้ำจะปรับขนาดได้ไม่ดี และ Listener เหตุการณ์จะเพิ่มขึ้นอย่างมาก

หากต้องการเพิ่มการเลื่อนเสมือนจริงและหลีกเลี่ยงปัญหาเหล่านั้น คุณต้องสร้างวิวพอร์ตโดยการรวมรายการไว้ในองค์ประกอบ <cdk-virtual-scroll-viewport> ดังนี้

@Component({
  template: `<cdk-virtual-scroll-viewport>
    <div *ngFor="let item of list">{{item}}</div>
    </cdk-virtual-scroll-viewport>`
})
export class ScrollComponent {
  list = Array.from({length: 100000}).map((_, i) => i);
}

เนื่องจาก ScrollingModule จะแสดงผลชุดย่อยของรายการในแบบไดนามิก คุณจึงต้องระบุความสูงของวิวพอร์ตผ่าน CSS มาตรฐาน นอกจากนี้ คุณยังต้องให้คําแนะนําเกี่ยวกับเนื้อหาในวิวพอร์ตโดยการระบุ itemSize โมดูลจะใช้ข้อมูลนี้ในการกำหนดจำนวนรายการที่จะเก็บใน DOM ในช่วงเวลาที่ระบุ และวิธีแสดงผลแถบเลื่อนที่มีขนาดเหมาะสม

@Component({
  template: `<cdk-virtual-scroll-viewport itemSize="18" style="height:80vh">
    <div *ngFor="let item of list">{{item}}</div>
    </cdk-virtual-scroll-viewport>`
})
export class ScrollComponent {
  list = Array.from({length: 100000}).map((_, i) => i);
}

สุดท้ายแปลง *ngFor เป็น *cdkVirtualFor

@Component({
  template: `<cdk-virtual-scroll-viewport itemSize="18" style="height:80vh">
    <div *cdkVirtualFor="let item of list">{{item}}</div>
    </cdk-virtual-scroll-viewport>`
})
export class ScrollComponent {
  list = Array.from({length: 100000}).map((_, i) => i);
}

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

ภาพย่อยของ CDK ของรายการในขณะที่ผู้ใช้เลื่อนดู

ก้าวไปให้ไกลกว่าเดิม

ความสามารถในการเลื่อนเสมือนจริงของ CDK ทำได้มากกว่าตัวอย่างพื้นฐานนี้มาก ในตัวอย่างแอป รายการทั้งหมดจะอยู่ในหน่วยความจำ แต่ระบบสามารถดึงข้อมูลรายการตามคำขอสำหรับแอปพลิเคชันที่ซับซ้อนกว่าได้ ดูข้อมูลเพิ่มเติมเกี่ยวกับความสามารถอื่นๆ ของ ScrollingModule และคำสั่ง cdkVirtualOf ได้โดยอ่านเกี่ยวกับ Scrolling ในเอกสารประกอบของ CDK

รูปภาพหลักโดย Mr Cup / Fabien Barral ใน Unsplash