تسريع عرض MatTable في خطوات قليلة

غالبًا ما يحدث أن معظم التطبيق يتكون من قوائم وجداول مختلفة. لكي لا أعيد اختراع العجلة في كل مرة ، أنا ، مثل الكثير ، كثيرا ما تستخدم جداول المواد الزاويّة .

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

في مشروعي الأخير ، كان هناك جدول تمتلئ خلاياه في الغالب بمجالات مختلفة (يمكنك حتى القول أنه شكل واحد كبير).

واستغرق الأمر حوالي 8 ثوانٍ (40 × 40 طاولة).

فكيف يمكنك تحسين MatTable للقوائم الكبيرة؟

صورة

حالة اختبار


لمساعدة الآخرين على التعامل مع هذه المشكلة ، كتبت تطبيق اختبار صغير. كل جدول MatTable نفسه ، مع خمسة أعمدة (الأول هو معرف العنصر ، والباقي حقول نصية MatFormField عادية).



يبدو أنه جدول بسيط ، ولكن حتى جعل 100 استنزاف مثل هذا الجدول لا يستغرق أكثر أو أقل من ثانيتين (أوه ، هذه المادة وأدائها "الأفضل").



استغرق العرض نفسه في هذه الحالة فقط (860 مللي ثانية) ، ومع ذلك ، تجمدت الصفحة لمدة 2.2 ثانية وكان المستخدم منزعجًا.

حسنًا ، لنحاول تقديم جدول يحتوي على 300 صف. ولفة الطبل ، نحن ننتظر قليلاً ونرى أنه تم إنفاق 10 ثوانٍ تقريبًا على البرمجة النصية والعرض الكلي. أي أنه في حالة رغبة المستخدم في عرض مثل هذا الجدول في 300 صف ، فإن صفحته ستتجمد لمدة 10 ثوانٍ. هذا أمر مخيف للغاية ومدهش (في الواقع ليس كذلك).



في الواقع ، كنت لا أزال أحاول قياس الوقت الذي سيستغرقه رسم 1000 عنصر ، لكن جهاز i7 المثير للشفقة لم أستطع تحمله وكانت الصفحة تتساقط باستمرار.
سنحاول القيام بذلك لاحقًا مع تطبيق الحل بالفعل.

حل للمشكلة


وهكذا ، يمكن للجميع أخذ القياسات باستخدام الأدوات المساعدة القائمة على المتصفح ، ولكن لا يوجد حل لهذه المشكلة.

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

تم العثور على مشكلة. الآن يبقى لمعرفة كيفية حلها. يتبادر إلى الذهن الحل الأول. إذا كانت المشكلة تعالج جميع البيانات دفعة واحدة ، فأنت بحاجة إلى جعل الجدول يعالج البيانات في أجزاء.

ولكن كيف نفعل ذلك؟

دعونا نفكر في ما لدينا لهذا من خارج منطقة الجزاء. أول ما يتبادر إلى الذهن هو وظيفة Track By. عند تغيير مصدر البيانات ، لن يتم إعادة عرض الجدول بالكامل ، ولكن فقط تغييراته.

دعنا نضيف هذه الوظيفة إلى جدولنا:

<mat-table [trackBy]="trackByFn" [dataSource]="commonDataSource">

حسنًا ، ولكن ليس لدينا مثل هذا الشرط الذي يؤدي إلى تغيير بيانات الجدول بطريقة أو بأخرى ، وهذا ليس ما تدور حوله المحادثة الآن. ولكن ماذا لو كتبنا الأنابيب ، والتي ، عند تهيئة مصدر البيانات ، ستكسر البيانات وتعطيها للجدول على دفعات. في المقابل ، ستساعد وظيفة trackBy على تجنب العارض الكامل.

@Pipe({
  name: 'splitSchedule'
})
export class SplitPipe implements PipeTransform {
  public transform(value: any, takeBy: number = 4, throttleTime: number = 40): Observable<Array<any>> {
    return Array.isArray(value)
      ? this.getSplittedThread(value, takeBy, throttleTime)
      : of(value);
  }

  private getSplittedThread(data: Array<any>, takeBy: number, throttleTime: number): Observable<Array<any>> {
    const repeatNumber = Math.ceil(data.length / takeBy);
    return timer(0, throttleTime).pipe(
      map((current) => data.slice(0, takeBy * ++current)),
      take(repeatNumber)
    );
  }
}

إليك قطعة صغيرة من التعليمات البرمجية ستساعد جهازك على تقديم مثل هذه الجداول الكبيرة.

تطبيق هذا الأنبوب على مصدر البيانات لدينا.


<mat-table [trackBy]="trackByFn"
           [dataSource]="commonDataSource | splitSchedule | async">

الآن دعنا نحاول أخذ القياسات. تقديم 100 و 300 و 1000 عنصر.







وماذا نرى؟ ما هو النجاح حقا ليس ما كنا نتوقعه:

  • تم تقديم 300 عنصر بشكل أسرع بمعدل ثانية واحدة
  • تم تقديم 1000 في 11 ثانية ولم تموت علامة التبويب
  • وعرض 100 عنصر بشكل عام 150 مللي ثانية أطول

ولكن لا تتسرع في استخلاص النتائج ، فلنلقي نظرة أولاً على سلوك الصفحة في كلتا الحالتين.





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

آمل أن تساعد هذه المقالة شخصًا ما.

كود المصدر لتطبيق الاختبار موجود على Stack Blitz .

All Articles