Skip to content

Commit b70d13d

Browse files
committed
perf(virtual-scroll): improve virtual-scroll performance
1 parent c377236 commit b70d13d

File tree

9 files changed

+470
-309
lines changed

9 files changed

+470
-309
lines changed

src/components/content/content.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -500,10 +500,6 @@ export class Content extends Ion implements AfterViewInit, OnDestroy {
500500
removeArrayItem(this._imgs, img);
501501
}
502502

503-
/**
504-
* @private
505-
*/
506-
507503
/**
508504
* @private
509505
* DOM WRITE
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { Component, NgModule } from '@angular/core';
2+
import { IonicApp, IonicModule } from '../../../..';
3+
4+
5+
@Component({
6+
templateUrl: 'main.html'
7+
})
8+
export class E2EPage {
9+
10+
}
11+
12+
13+
@Component({
14+
template: '<ion-nav [root]="root"></ion-nav>'
15+
})
16+
export class E2EApp {
17+
root = E2EPage;
18+
}
19+
20+
21+
@NgModule({
22+
declarations: [
23+
E2EApp,
24+
E2EPage
25+
],
26+
imports: [
27+
IonicModule.forRoot(E2EApp)
28+
],
29+
bootstrap: [IonicApp],
30+
entryComponents: [
31+
E2EApp,
32+
E2EPage
33+
]
34+
})
35+
export class AppModule {}

src/components/virtual-scroll/test/list/app-module.ts

Lines changed: 74 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,28 +6,47 @@ import { IonicApp, IonicModule } from '../../../..';
66
templateUrl: 'main.html'
77
})
88
export class E2EPage {
9-
items: Array<{title: string; id: number}>;
9+
items: Array<{id: number, url: string, gif: string}> = [];
10+
imgDomain = 'http://localhost:8900';
11+
responseDelay = 1500;
12+
itemCount = 15;
13+
showGifs = false;
1014

1115
constructor() {
12-
this.fillList();
16+
// take a look at the gulp task: test.imageserver
17+
var xhr = new XMLHttpRequest();
18+
xhr.open('GET', `${this.imgDomain}/reset`, true);
19+
xhr.onreadystatechange = () => {
20+
if (xhr.readyState === 4) {
21+
this.fillList();
22+
}
23+
};
24+
xhr.send();
1325
}
1426

1527
fillList() {
16-
this.items = [];
17-
for (let i = 0; i < 500; i++) {
28+
this.items.length = 0;
29+
let gifIndex = Math.ceil(Math.random() * gifs.length) - 1;
30+
31+
for (let i = 0; i < this.itemCount; i++) {
1832
this.items.push({
19-
title: 'Item ' + i,
20-
id: i
33+
id: i,
34+
url: `${this.imgDomain}/?d=${this.responseDelay}&id=${i}`,
35+
gif: gifs[gifIndex]
2136
});
37+
gifIndex++;
38+
if (gifIndex >= gifs.length) {
39+
gifIndex = 0;
40+
}
2241
}
2342
}
2443

2544
emptyList() {
26-
this.items = [];
45+
this.items.length = 0;
2746
}
2847

29-
itemTapped(ev: any, item: {title: string, date: string}) {
30-
console.log(`itemTapped: ${item.title}`);
48+
toggleGifs() {
49+
this.showGifs = !this.showGifs;
3150
}
3251

3352
reload() {
@@ -36,6 +55,52 @@ export class E2EPage {
3655

3756
}
3857

58+
const gifs = [
59+
'https://media.giphy.com/media/cFdHXXm5GhJsc/giphy.gif',
60+
'https://media.giphy.com/media/5JjLO6t0lNvLq/giphy.gif',
61+
'https://media.giphy.com/media/ZmdIZ8K4fKEEM/giphy.gif',
62+
'https://media.giphy.com/media/lKXEBR8m1jWso/giphy.gif',
63+
'https://media.giphy.com/media/PjplWH49v1FS0/giphy.gif',
64+
'https://media.giphy.com/media/SyVyFtBTTVb5m/giphy.gif',
65+
'https://media.giphy.com/media/LWqQ5glpSMjny/giphy.gif',
66+
'https://media.giphy.com/media/l396Dat26yQOdfWgw/giphy.gif',
67+
'https://media.giphy.com/media/zetsDd1oSNd96/giphy.gif',
68+
'https://media.giphy.com/media/F6PFPjc3K0CPe/giphy.gif',
69+
'https://media.giphy.com/media/L0GJP0ZxdnVbW/giphy.gif',
70+
'https://media.giphy.com/media/26ufbLWPFHkhwXcpW/giphy.gif',
71+
'https://media.giphy.com/media/r3jTnU6iEwpbO/giphy.gif',
72+
'https://media.giphy.com/media/6Xbr4pVmJW4wM/giphy.gif',
73+
'https://media.giphy.com/media/FPmzkXGFVhp2U/giphy.gif',
74+
'https://media.giphy.com/media/p3yU7Rno2PvvW/giphy.gif',
75+
'https://media.giphy.com/media/vbBmb51klyyB2/giphy.gif',
76+
'https://media.giphy.com/media/ZAfpXz6fGrlYY/giphy.gif',
77+
'https://media.giphy.com/media/3oGRFvVyUdGBZeQiAw/giphy.gif',
78+
'https://media.giphy.com/media/NJbeypFZCHj2g/giphy.gif',
79+
'https://media.giphy.com/media/WpNO2ZXjhJ85y/giphy.gif',
80+
'https://media.giphy.com/media/xaw15bdmMEkgg/giphy.gif',
81+
'https://media.giphy.com/media/tLwQSHQo6hjTa/giphy.gif',
82+
'https://media.giphy.com/media/3dcoLqDDjd9pC/giphy.gif',
83+
'https://media.giphy.com/media/QFfs8ubyDkluo/giphy.gif',
84+
'https://media.giphy.com/media/10hYVVSPrSpZS0/giphy.gif',
85+
'https://media.giphy.com/media/EYJz9cfMa7WAU/giphy.gif',
86+
'https://media.giphy.com/media/Q21vzIHyTtmaQ/giphy.gif',
87+
'https://media.giphy.com/media/pzmUOeqhzJTck/giphy.gif',
88+
'https://media.giphy.com/media/G6kt1Gb4Luxy0/giphy.gif',
89+
'https://media.giphy.com/media/13wjHxAz6B6E9i/giphy.gif',
90+
'https://media.giphy.com/media/ANbbM3IzH9Tna/giphy.gif',
91+
'https://media.giphy.com/media/EQ5I7NF4BDYA/giphy.gif',
92+
'https://media.giphy.com/media/L7gHewOS8GOWY/giphy.gif',
93+
'https://media.giphy.com/media/nO16UrmQh7khW/giphy.gif',
94+
'https://media.giphy.com/media/eGuk6gQM3Q29W/giphy.gif',
95+
'https://media.giphy.com/media/8dpPMMlxmDEJO/giphy.gif',
96+
'https://media.giphy.com/media/5ox090BjCB8ME/giphy.gif',
97+
'https://media.giphy.com/media/Hzm8c1eMSq3CM/giphy.gif',
98+
'https://media.giphy.com/media/2APlzZshLu3LO/giphy.gif',
99+
'https://media.giphy.com/media/dgygjvNe7jckw/giphy.gif',
100+
'https://media.giphy.com/media/5g0mypSSPupO0/giphy.gif',
101+
'https://media.giphy.com/media/10JmxORlA6dEFW/giphy.gif',
102+
];
103+
39104

40105
@Component({
41106
template: '<ion-nav [root]="root"></ion-nav>'

src/components/virtual-scroll/test/list/main.html

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,25 @@
1515
<div padding>
1616
<button ion-button (click)="fillList()">Fill List</button>
1717
<button ion-button (click)="emptyList()">Empty List</button>
18+
<button ion-button (click)="toggleGifs()">Gifs</button>
19+
</div>
20+
21+
<div padding>
22+
<code>gulp test.imageserve</code>
1823
</div>
1924

2025
<ion-list [virtualScroll]="items">
2126

22-
<ion-item class="item-text-wrap" *virtualItem="let item" (click)="itemTapped(item)">
27+
<ion-item class="item-text-wrap" *virtualItem="let item; let itemBounds = bounds;">
2328
<ion-thumbnail item-left>
24-
<ion-img src="http://loremflickr.com/80/80/dog?{{item.id}}"></ion-img>
29+
<ion-img src="{{item.url}}" [bounds]="itemBounds"></ion-img>
2530
</ion-thumbnail>
2631

27-
<h2 class="text-wrap">{{item.title}}</h2>
32+
<h2 class="text-wrap">{{item.id}}, top: {{itemBounds.top}}, bottom: {{itemBounds.bottom}}, height: {{itemBounds.height}}</h2>
33+
34+
<!--<ion-thumbnail item-right>
35+
<ion-img src="{{item.gif}}" [bounds]="itemBounds"></ion-img>
36+
</ion-thumbnail>-->
2837
</ion-item>
2938

3039
</ion-list>

src/components/virtual-scroll/test/virtual-scroll.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ describe('VirtualScroll', () => {
289289
cells, records, nodes, viewContainer,
290290
itmTmp, hdrTmp, ftrTmp, true);
291291

292-
expect(nodes.length).toBe(6);
292+
expect(nodes.length).toBe(3);
293293

294294
expect(nodes[0].cell).toBe(2);
295295
expect(nodes[1].cell).toBe(3);
Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
import { Directive, TemplateRef, ViewContainerRef } from '@angular/core';
2+
import { VirtualContext } from './virtual-util';
23

34

45
/**
56
* @private
67
*/
78
@Directive({selector: '[virtualHeader]'})
89
export class VirtualHeader {
9-
constructor(public templateRef: TemplateRef<Object>) {}
10+
constructor(public templateRef: TemplateRef<VirtualContext>) {}
1011
}
1112

1213

@@ -15,7 +16,7 @@ export class VirtualHeader {
1516
*/
1617
@Directive({selector: '[virtualFooter]'})
1718
export class VirtualFooter {
18-
constructor(public templateRef: TemplateRef<Object>) {}
19+
constructor(public templateRef: TemplateRef<VirtualContext>) {}
1920
}
2021

2122

@@ -24,5 +25,5 @@ export class VirtualFooter {
2425
*/
2526
@Directive({selector: '[virtualItem]'})
2627
export class VirtualItem {
27-
constructor(public templateRef: TemplateRef<Object>, public viewContainer: ViewContainerRef) {}
28+
constructor(public templateRef: TemplateRef<VirtualContext>, public viewContainer: ViewContainerRef) {}
2829
}

src/components/virtual-scroll/virtual-scroll.scss

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22
// Virtual Scroll
33
// --------------------------------------------------
44

5+
.virtual-loading {
6+
opacity: 0;
7+
}
8+
59
.virtual-scroll {
610
position: relative;
711

@@ -20,6 +24,6 @@
2024
contain: content;
2125
}
2226

23-
.virtual-scroll .virtual-hidden {
27+
.virtual-scroll .virtual-last {
2428
display: none;
2529
}

0 commit comments

Comments
 (0)