perf(angular): proxy fast properties (#16888)

* perf(angular): proxy fast properties

* update stencil
This commit is contained in:
Manu MA
2018-12-28 18:37:24 +01:00
committed by GitHub
parent 8b140306ef
commit ca9ec3e18a
6 changed files with 400 additions and 388 deletions

File diff suppressed because it is too large Load Diff

View File

@ -31,7 +31,7 @@ export declare interface IonVirtualScroll {
export class IonVirtualScroll { export class IonVirtualScroll {
private differ?: IterableDiffer<any>; private differ?: IterableDiffer<any>;
private nativeEl: HTMLIonVirtualScrollElement; private el: HTMLIonVirtualScrollElement;
private refMap = new WeakMap<HTMLElement, EmbeddedViewRef<VirtualContext>> (); private refMap = new WeakMap<HTMLElement, EmbeddedViewRef<VirtualContext>> ();
@ContentChild(VirtualItem) itmTmp!: VirtualItem; @ContentChild(VirtualItem) itmTmp!: VirtualItem;
@ -122,23 +122,8 @@ export class IonVirtualScroll {
private iterableDiffers: IterableDiffers, private iterableDiffers: IterableDiffers,
elementRef: ElementRef, elementRef: ElementRef,
) { ) {
this.nativeEl = elementRef.nativeElement as HTMLIonVirtualScrollElement; this.el = elementRef.nativeElement as HTMLIonVirtualScrollElement;
this.nativeEl.nodeRender = this.nodeRender.bind(this); this.el.nodeRender = this.nodeRender.bind(this);
proxyInputs(this, this.nativeEl, [
'approxItemHeight',
'approxHeaderHeight',
'approxFooterHeight',
'headerFn',
'footerFn',
'items',
'itemHeight'
]);
proxyMethods(this, this.nativeEl, [
'checkEnd',
'checkRange',
'positionForItem'
]);
} }
ngOnChanges(changes: SimpleChanges): void { ngOnChanges(changes: SimpleChanges): void {
@ -208,3 +193,19 @@ function getElement(view: EmbeddedViewRef<VirtualContext>): HTMLElement {
} }
throw new Error('virtual element was not created'); throw new Error('virtual element was not created');
} }
proxyInputs(IonVirtualScroll, [
'approxItemHeight',
'approxHeaderHeight',
'approxFooterHeight',
'headerFn',
'footerFn',
'items',
'itemHeight'
]);
proxyMethods(IonVirtualScroll, [
'checkEnd',
'checkRange',
'positionForItem'
]);

View File

@ -2,8 +2,6 @@ import { Injectable } from '@angular/core';
import { BackButtonDetail, Platforms, getPlatforms, isPlatform } from '@ionic/core'; import { BackButtonDetail, Platforms, getPlatforms, isPlatform } from '@ionic/core';
import { Subject, Subscription } from 'rxjs'; import { Subject, Subscription } from 'rxjs';
import { proxyEvent } from '../util/util';
export interface BackButtonEmitter extends Subject<BackButtonDetail> { export interface BackButtonEmitter extends Subject<BackButtonDetail> {
subscribeWithPriority(priority: number, callback: () => Promise<any> | void): Subscription; subscribeWithPriority(priority: number, callback: () => Promise<any> | void): Subscription;
} }
@ -177,3 +175,10 @@ function readQueryParam(url: string, key: string) {
const results = regex.exec(url); const results = regex.exec(url);
return results ? decodeURIComponent(results[1].replace(/\+/g, ' ')) : null; return results ? decodeURIComponent(results[1].replace(/\+/g, ' ')) : null;
} }
function proxyEvent<T>(emitter: Subject<T>, el: EventTarget, eventName: string) {
el.addEventListener(eventName, (ev: Event | undefined | null) => {
// ?? cordova might emit "null" events
emitter.next(ev != null ? (ev as any).detail as T : undefined);
});
}

View File

@ -1,4 +1,4 @@
import { proxyMethod } from '../util/util'; import { proxyMethod } from './util';
export class OverlayBaseController<Opts, Overlay> { export class OverlayBaseController<Opts, Overlay> {
constructor(private ctrl: string) {} constructor(private ctrl: string) {}

View File

@ -1,20 +1,3 @@
import { ElementRef } from '@angular/core';
import { Subject } from 'rxjs';
export function inputs(instance: any, el: ElementRef, props: string[]) {
props.forEach(propName => {
Object.defineProperty(instance, propName, {
get: () => el.nativeElement[propName], set: (val: any) => el.nativeElement[propName] = val
});
});
}
export function proxyEvent<T>(emitter: Subject<T>, el: EventTarget, eventName: string) {
el.addEventListener(eventName, (ev: Event | undefined | null) => {
// ?? cordova might emit "null" events
emitter.next(ev != null ? (ev as any).detail as T : undefined);
});
}
export function proxyMethod(ctrlName: string, methodName: string, ...args: any[]) { export function proxyMethod(ctrlName: string, methodName: string, ...args: any[]) {
const controller = ensureElementInBody(ctrlName); const controller = ensureElementInBody(ctrlName);
@ -30,19 +13,3 @@ export function ensureElementInBody(elementName: string) {
} }
return element as HTMLStencilElement; return element as HTMLStencilElement;
} }
export function deepEqual(x: any, y: any) {
if (x === y) {
return true;
} else if (typeof x === 'object' && x != null && (typeof y === 'object' && y != null)) {
if (Object.keys(x).length !== Object.keys(y).length) { return false; }
for (const prop in x) {
if (y.hasOwnProperty(prop)) {
if (!deepEqual(x[prop], y[prop])) { return false; }
} else { return false; }
}
return true;
} else { return false; }
}

View File

@ -30,7 +30,7 @@
"ionicons": "4.5.1" "ionicons": "4.5.1"
}, },
"devDependencies": { "devDependencies": {
"@stencil/core": "0.16.1", "@stencil/core": "0.16.2-0",
"@stencil/sass": "0.1.1", "@stencil/sass": "0.1.1",
"@stencil/utils": "latest", "@stencil/utils": "latest",
"@types/jest": "^23.3.1", "@types/jest": "^23.3.1",