feat: add a flag in bootstrap to enable coalesce event change detection to improve performance (#30533)

PR Close #30533
This commit is contained in:
JiaLiPassion
2019-05-17 20:50:02 +09:00
committed by atscott
parent c5894e08bc
commit 44623a1161
9 changed files with 146 additions and 20 deletions

View File

@ -20,7 +20,6 @@ import {createMouseEvent, el} from '../../../testing/src/browser_util';
let zone: NgZone;
describe('EventManager', () => {
beforeEach(() => {
doc = getDOM().supportsDOMEvents() ? document : getDOM().createHtmlDocument();
zone = new NgZone({});
@ -296,7 +295,7 @@ import {createMouseEvent, el} from '../../../testing/src/browser_util';
expect(receivedEvents).toEqual([]);
});
it('should run blockListedEvents handler outside of ngZone', () => {
it('should run blackListedEvents handler outside of ngZone', () => {
const Zone = (window as any)['Zone'];
const element = el('<div><div></div></div>');
doc.body.appendChild(element);
@ -312,13 +311,45 @@ import {createMouseEvent, el} from '../../../testing/src/browser_util';
let remover = manager.addEventListener(element, 'scroll', handler);
getDOM().dispatchEvent(element, dispatchedEvent);
expect(receivedEvent).toBe(dispatchedEvent);
expect(receivedZone.name).toBe(Zone.root.name);
expect(receivedZone.name).not.toEqual('angular');
receivedEvent = null;
remover && remover();
getDOM().dispatchEvent(element, dispatchedEvent);
expect(receivedEvent).toBe(null);
});
it('should only trigger one Change detection when bubbling', (done: DoneFn) => {
doc = getDOM().supportsDOMEvents() ? document : getDOM().createHtmlDocument();
zone = new NgZone({shouldCoalesceEventChangeDetection: true});
domEventPlugin = new DomEventsPlugin(doc, zone, null);
const element = el('<div></div>');
const child = el('<div></div>');
element.appendChild(child);
doc.body.appendChild(element);
const dispatchedEvent = createMouseEvent('click');
let receivedEvents: any = [];
let stables: any = [];
const handler = (e: any) => { receivedEvents.push(e); };
const manager = new EventManager([domEventPlugin], zone);
let removerChild: any;
let removerParent: any;
zone.run(() => {
removerChild = manager.addEventListener(child, 'click', handler);
removerParent = manager.addEventListener(element, 'click', handler);
});
zone.onStable.subscribe((isStable: any) => { stables.push(isStable); });
getDOM().dispatchEvent(child, dispatchedEvent);
requestAnimationFrame(() => {
expect(receivedEvents.length).toBe(2);
expect(stables.length).toBe(1);
removerChild && removerChild();
removerParent && removerParent();
done();
});
});
});
})();
@ -332,12 +363,12 @@ class FakeEventManagerPlugin extends EventManagerPlugin {
addEventListener(element: any, eventName: string, handler: Function) {
this.eventHandler[eventName] = handler;
return () => { delete (this.eventHandler[eventName]); };
return () => { delete this.eventHandler[eventName]; };
}
}
class FakeNgZone extends NgZone {
constructor() { super({enableLongStackTrace: false}); }
constructor() { super({enableLongStackTrace: false, shouldCoalesceEventChangeDetection: true}); }
run<T>(fn: (...args: any[]) => T, applyThis?: any, applyArgs?: any[]): T { return fn(); }
runOutsideAngular(fn: Function) { return fn(); }
}

View File

@ -175,7 +175,7 @@ export function stringifyElement(el: any /** TODO #9100 */): string {
}
export function createNgZone(): NgZone {
return new NgZone({enableLongStackTrace: true});
return new NgZone({enableLongStackTrace: true, shouldCoalesceEventChangeDetection: false});
}
export function isCommentNode(node: Node): boolean {