Improve videos list client performance
authorChocobozzz <me@florianbigard.com>
Thu, 20 Sep 2018 12:21:57 +0000 (14:21 +0200)
committerChocobozzz <me@florianbigard.com>
Thu, 20 Sep 2018 12:21:57 +0000 (14:21 +0200)
client/src/app/shared/video/abstract-video-list.html
client/src/app/shared/video/abstract-video-list.ts
client/src/app/shared/video/video-miniature.component.html
client/src/app/shared/video/video-miniature.component.ts
client/src/hmr.ts

index 4ad4e3568a260a7c336ffdb0efb32e0ee59b38f4..d543ab7c12172d34d4f1de4c1b28c07d8a3934fd 100644 (file)
@@ -11,8 +11,8 @@
     (nearOfTop)="onNearOfTop()" (nearOfBottom)="onNearOfBottom()" (pageChanged)="onPageChanged($event)"
     class="videos" #videosElement
   >
-    <div *ngFor="let videos of videoPages" class="videos-page">
-      <my-video-miniature *ngFor="let video of videos" [video]="video" [user]="user" [ownerDisplayType]="ownerDisplayType"></my-video-miniature>
+    <div *ngFor="let videos of videoPages; trackBy: pageByVideoId" class="videos-page">
+      <my-video-miniature *ngFor="let video of videos; trackBy: videoById" [video]="video" [user]="user" [ownerDisplayType]="ownerDisplayType"></my-video-miniature>
     </div>
   </div>
 </div>
index 53b0444785859e96b97bb435c709eccdfac293f6..6a758ebe02412338f1ac997f6ce886c0fa4d7069 100644 (file)
@@ -81,6 +81,15 @@ export abstract class AbstractVideoList implements OnInit, OnDestroy {
     if (this.resizeSubscription) this.resizeSubscription.unsubscribe()
   }
 
+  pageByVideoId (index: number, page: Video[]) {
+    // Video are unique in all pages
+    return page[0].id
+  }
+
+  videoById (index: number, video: Video) {
+    return video.id
+  }
+
   onNearOfTop () {
     this.previousPage()
   }
@@ -166,7 +175,7 @@ export abstract class AbstractVideoList implements OnInit, OnDestroy {
     const min = this.minPageLoaded()
 
     if (min > 1) {
-      this.loadMoreVideos(min - 1)
+      this.loadMoreVideos(min - 1, true)
     }
   }
 
index 9cf3fb32107a5817bf1d3d6aa465ca2ef72ebbed..cfc483018d7471934e04fbd43253418743c31fd3 100644 (file)
@@ -1,11 +1,11 @@
 <div class="video-miniature">
-  <my-video-thumbnail [video]="video" [nsfw]="isVideoBlur()"></my-video-thumbnail>
+  <my-video-thumbnail [video]="video" [nsfw]="isVideoBlur"></my-video-thumbnail>
 
   <div class="video-miniature-information">
     <a
       tabindex="-1"
       class="video-miniature-name"
-      [routerLink]="[ '/videos/watch', video.uuid ]" [attr.title]="video.name" [ngClass]="{ 'blur-filter': isVideoBlur() }"
+      [routerLink]="[ '/videos/watch', video.uuid ]" [attr.title]="video.name" [ngClass]="{ 'blur-filter': isVideoBlur }"
     >
       {{ video.name }}
     </a>
index 07193ebd580d1cd5f02bd391a7c870faf1d9de4b..27098f4b4a0c097c5987572328d7b8dab1e5d7bb 100644 (file)
@@ -1,4 +1,4 @@
-import { Component, Input, OnInit } from '@angular/core'
+import { ChangeDetectionStrategy, Component, Input, OnInit } from '@angular/core'
 import { User } from '../users'
 import { Video } from './video.model'
 import { ServerService } from '@app/core'
@@ -8,13 +8,16 @@ export type OwnerDisplayType = 'account' | 'videoChannel' | 'auto'
 @Component({
   selector: 'my-video-miniature',
   styleUrls: [ './video-miniature.component.scss' ],
-  templateUrl: './video-miniature.component.html'
+  templateUrl: './video-miniature.component.html',
+  changeDetection: ChangeDetectionStrategy.OnPush
 })
 export class VideoMiniatureComponent implements OnInit {
   @Input() user: User
   @Input() video: Video
   @Input() ownerDisplayType: OwnerDisplayType = 'account'
 
+  isVideoBlur: boolean
+
   private ownerDisplayTypeChosen: 'account' | 'videoChannel'
 
   constructor (private serverService: ServerService) { }
@@ -35,10 +38,8 @@ export class VideoMiniatureComponent implements OnInit {
     } else {
       this.ownerDisplayTypeChosen = 'videoChannel'
     }
-  }
 
-  isVideoBlur () {
-    return this.video.isVideoNSFWForUser(this.user, this.serverService.getConfig())
+    this.isVideoBlur = this.video.isVideoNSFWForUser(this.user, this.serverService.getConfig())
   }
 
   displayOwnerAccount () {
index 4d707a250e1244cbc9dc889b390258f2f9528f9c..d5306a7a2879de9677e226deab878d965a006402 100644 (file)
@@ -1,11 +1,19 @@
 import { NgModuleRef, ApplicationRef } from '@angular/core'
 import { createNewHosts } from '@angularclass/hmr'
+import { enableDebugTools } from '@angular/platform-browser'
 
 export const hmrBootstrap = (module: any, bootstrap: () => Promise<NgModuleRef<any>>) => {
   let ngModule: NgModuleRef<any>
   module.hot.accept()
   bootstrap()
-    .then(mod => ngModule = mod)
+    .then(mod => {
+      ngModule = mod
+
+      const applicationRef = ngModule.injector.get(ApplicationRef);
+      const componentRef = applicationRef.components[ 0 ]
+      // allows to run `ng.profiler.timeChangeDetection();`
+      enableDebugTools(componentRef)
+    })
   module.hot.dispose(() => {
     const appRef: ApplicationRef = ngModule.injector.get(ApplicationRef)
     const elements = appRef.components.map(c => c.location.nativeElement)