Skip to content

Commit dec5a0b

Browse files
committed
perf(item): reorder is only added to the DOM if needed
I have measured the performance impact of this change, since we use the push change detector strategy, the *ngIf is only evaluated once. Items wrapped around an element with the ListReorder directive will receive a hidden `<ion-reorder>` in their DOM, but items that are not wrapped (i.e. they CAN NOT be reordered) will not even have the `<ion-reorder>` element in their DOM. fixes #9065
1 parent ac157c0 commit dec5a0b

File tree

5 files changed

+28
-45
lines changed

5 files changed

+28
-45
lines changed

src/components/item/item-reorder-gesture.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ export class ItemReorderGesture {
4747
console.error('ion-reorder does not contain $ionComponent');
4848
return false;
4949
}
50-
this.reorderList.reorderPrepare();
50+
this.reorderList._reorderPrepare();
5151

5252
let item = reorderMark.getReorderNode();
5353
if (!item) {
@@ -63,13 +63,13 @@ export class ItemReorderGesture {
6363
this.lastToIndex = indexForItem(item);
6464

6565
this.windowHeight = window.innerHeight - AUTO_SCROLL_MARGIN;
66-
this.lastScrollPosition = this.reorderList.scrollContent(0);
66+
this.lastScrollPosition = this.reorderList._scrollContent(0);
6767

6868
this.offset = pointerCoord(ev);
6969
this.offset.y += this.lastScrollPosition;
7070

7171
item.classList.add(ITEM_REORDER_ACTIVE);
72-
this.reorderList.reorderStart();
72+
this.reorderList._reorderStart();
7373
return true;
7474
}
7575

@@ -97,7 +97,7 @@ export class ItemReorderGesture {
9797
this.lastToIndex = toIndex;
9898
this.lastYcoord = posY;
9999
this.emptyZone = false;
100-
this.reorderList.reorderMove(fromIndex, toIndex, this.selectedItemHeight);
100+
this.reorderList._reorderMove(fromIndex, toIndex, this.selectedItemHeight);
101101
}
102102
} else {
103103
this.emptyZone = true;
@@ -133,7 +133,7 @@ export class ItemReorderGesture {
133133
} else {
134134
reorderInactive();
135135
}
136-
this.reorderList.reorderEmit(fromIndex, toIndex);
136+
this.reorderList._reorderEmit(fromIndex, toIndex);
137137
}
138138

139139
private itemForCoord(coord: PointerCoordinates): HTMLElement {
@@ -142,9 +142,9 @@ export class ItemReorderGesture {
142142

143143
private scroll(posY: number): number {
144144
if (posY < AUTO_SCROLL_MARGIN) {
145-
this.lastScrollPosition = this.reorderList.scrollContent(-SCROLL_JUMP);
145+
this.lastScrollPosition = this.reorderList._scrollContent(-SCROLL_JUMP);
146146
} else if (posY > this.windowHeight) {
147-
this.lastScrollPosition = this.reorderList.scrollContent(SCROLL_JUMP);
147+
this.lastScrollPosition = this.reorderList._scrollContent(SCROLL_JUMP);
148148
}
149149
return this.lastScrollPosition;
150150
}

src/components/item/item-reorder.ts

Lines changed: 7 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -133,19 +133,10 @@ export interface ReorderIndexes {
133133
})
134134
export class ItemReorder {
135135

136-
/** @private */
137136
_enableReorder: boolean = false;
138-
139-
/** @private */
140137
_visibleReorder: boolean = false;
141-
142-
/** @private */
143138
_reorderGesture: ItemReorderGesture;
144-
145-
/** @private */
146139
_lastToIndex: number = -1;
147-
148-
/** @private */
149140
_element: HTMLElement;
150141

151142
/**
@@ -196,10 +187,7 @@ export class ItemReorder {
196187
}
197188
}
198189

199-
/**
200-
* @private
201-
*/
202-
reorderPrepare() {
190+
_reorderPrepare() {
203191
let ele = this._element;
204192
let children: any = ele.children;
205193
for (let i = 0, ilen = children.length; i < ilen; i++) {
@@ -209,18 +197,12 @@ export class ItemReorder {
209197
}
210198
}
211199

212-
/**
213-
* @private
214-
*/
215-
reorderStart() {
200+
_reorderStart() {
216201
this.setElementClass('reorder-list-active', true);
217202
}
218203

219-
/**
220-
* @private
221-
*/
222-
reorderEmit(fromIndex: number, toIndex: number) {
223-
this.reorderReset();
204+
_reorderEmit(fromIndex: number, toIndex: number) {
205+
this._reorderReset();
224206
if (fromIndex !== toIndex) {
225207
this._zone.run(() => {
226208
this.ionItemReorder.emit({
@@ -231,21 +213,15 @@ export class ItemReorder {
231213
}
232214
}
233215

234-
/**
235-
* @private
236-
*/
237-
scrollContent(scroll: number) {
216+
_scrollContent(scroll: number) {
238217
let scrollTop = this._content.getScrollTop() + scroll;
239218
if (scroll !== 0) {
240219
this._content.scrollTo(0, scrollTop, 0);
241220
}
242221
return scrollTop;
243222
}
244223

245-
/**
246-
* @private
247-
*/
248-
reorderReset() {
224+
_reorderReset() {
249225
let children = this._element.children;
250226
let len = children.length;
251227

@@ -257,10 +233,7 @@ export class ItemReorder {
257233
this._lastToIndex = -1;
258234
}
259235

260-
/**
261-
* @private
262-
*/
263-
reorderMove(fromIndex: number, toIndex: number, itemHeight: number) {
236+
_reorderMove(fromIndex: number, toIndex: number, itemHeight: number) {
264237
if (this._lastToIndex === -1) {
265238
this._lastToIndex = fromIndex;
266239
}

src/components/item/item-sliding-gesture.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ const DRAG_THRESHOLD = 10;
1010
const MAX_ATTACK_ANGLE = 20;
1111

1212
export class ItemSlidingGesture extends PanGesture {
13+
1314
private preSelectedContainer: ItemSliding = null;
1415
private selectedContainer: ItemSliding = null;
1516
private openContainer: ItemSliding = null;

src/components/item/item.ts

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
import { ChangeDetectionStrategy, Component, ContentChild, ContentChildren, Directive, ElementRef, Input, QueryList, Renderer, ViewChild, ViewEncapsulation } from '@angular/core';
1+
import { ChangeDetectionStrategy, Component, ContentChild, ContentChildren, Directive, ElementRef, Input, QueryList, Renderer, Optional, ViewChild, ViewEncapsulation } from '@angular/core';
22

33
import { Button } from '../button/button';
44
import { Config } from '../../config/config';
55
import { Form } from '../../util/form';
66
import { Icon } from '../icon/icon';
77
import { Ion } from '../ion';
88
import { Label } from '../label/label';
9+
import { ItemReorder } from './item-reorder';
910

1011

1112
/**
@@ -283,7 +284,7 @@ import { Label } from '../label/label';
283284
'<ng-content select="ion-select,ion-input,ion-textarea,ion-datetime,ion-range,[item-content]"></ng-content>' +
284285
'</div>' +
285286
'<ng-content select="[item-right],ion-radio,ion-toggle"></ng-content>' +
286-
'<ion-reorder></ion-reorder>' +
287+
'<ion-reorder *ngIf="_shouldHaveReorder"></ion-reorder>' +
287288
'</div>' +
288289
'<div class="button-effect"></div>',
289290
host: {
@@ -297,6 +298,7 @@ export class Item extends Ion {
297298
_inputs: Array<string> = [];
298299
_label: Label;
299300
_viewLabel: boolean = true;
301+
_shouldHaveReorder: boolean = false;
300302

301303
/**
302304
* @private
@@ -324,9 +326,15 @@ export class Item extends Ion {
324326
this._setMode('item', val);
325327
}
326328

327-
constructor(form: Form, config: Config, elementRef: ElementRef, renderer: Renderer) {
329+
constructor(
330+
form: Form,
331+
config: Config,
332+
elementRef: ElementRef,
333+
renderer: Renderer,
334+
@Optional() reorder: ItemReorder
335+
) {
328336
super(config, elementRef, renderer);
329-
337+
this._shouldHaveReorder = !!reorder;
330338
this.mode = config.get('mode');
331339
this.id = form.nextId().toString();
332340
}

src/navigation/nav-controller-base.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import { TransitionController } from '../transitions/transition-controller';
2424
* This class is for internal use only. It is not exported publicly.
2525
*/
2626
export class NavControllerBase extends Ion implements NavController {
27+
2728
_children: any[] = [];
2829
_ids: number = -1;
2930
_init = false;

0 commit comments

Comments
 (0)