fix: don't share eventPath

This commit is contained in:
shirakaba
2022-12-22 12:13:44 +09:00
parent 23961af38d
commit 6cb8a83c82

View File

@@ -14,13 +14,6 @@ const timeOrigin = Date.now();
*/ */
const emptyArray: ListenerEntry[] = []; const emptyArray: ListenerEntry[] = [];
/**
* Recycling the event path array rather than allocating a new one each time
* saves about 210 nanoseconds per dispatchTo() call (and avoids memory pressure
* and GC).
*/
const recycledEventPath: Observable[] = [];
enum EventPropagationState { enum EventPropagationState {
resume, resume,
stop, stop,
@@ -153,6 +146,13 @@ export class DOMEvent implements Event {
// an event listener callback will end up modifying the listeners array. // an event listener callback will end up modifying the listeners array.
private declare listeners: ListenerEntry[]; private declare listeners: ListenerEntry[];
/**
* Recycling the event path array rather than allocating a new one each time
* saves about 210 nanoseconds per dispatchTo() call (and avoids memory pressure
* and GC).
*/
private readonly recycledEventPath: Observable[] = [];
/** /**
* Returns the event's timestamp as the number of milliseconds measured * Returns the event's timestamp as the number of milliseconds measured
* relative to the time origin. * relative to the time origin.
@@ -200,15 +200,15 @@ export class DOMEvent implements Event {
* [Button, StackLayout, Page] // 'bubble' * [Button, StackLayout, Page] // 'bubble'
*/ */
private getEventPath(responder: Observable, path: 'capture' | 'bubble'): Observable[] { private getEventPath(responder: Observable, path: 'capture' | 'bubble'): Observable[] {
recycledEventPath.splice(0, recycledEventPath.length, responder); this.recycledEventPath.splice(0, this.recycledEventPath.length, responder);
if (!responder.isViewBase()) { if (!responder.isViewBase()) {
return recycledEventPath; return this.recycledEventPath;
} }
// Determining the function up-front (rather than inside the loop) saves // Determining the function up-front (rather than inside the loop) saves
// 50 nanoseconds per dispatchTo() call. // 50 nanoseconds per dispatchTo() call.
const insert = path === 'capture' ? recycledEventPath.unshift.bind(recycledEventPath) : recycledEventPath.push.bind(recycledEventPath); const insert = path === 'capture' ? this.recycledEventPath.unshift.bind(this.recycledEventPath) : this.recycledEventPath.push.bind(this.recycledEventPath);
let nextResponder = responder.parent; let nextResponder = responder.parent;
while (nextResponder) { while (nextResponder) {
@@ -218,7 +218,7 @@ export class DOMEvent implements Event {
// to then walk from Frame to Application or something. // to then walk from Frame to Application or something.
nextResponder = nextResponder?.parent; nextResponder = nextResponder?.parent;
} }
return recycledEventPath; return this.recycledEventPath;
} }
/** @deprecated */ /** @deprecated */