-
Notifications
You must be signed in to change notification settings - Fork 407
feat(eventListener): fix #798, improve EventTarget.addEventListener performance #812
Conversation
I added a performance test here: 3a017d3 Right away two things jump out.
The GC problem means that we are still creating too many objects. Can we do an audit and see if every one of these objects is needed? |
The issue is coming from try {
// In cross site contexts (such as WebDriver frameworks like Selenium),
// accessing the handler object here will cause an exception to be thrown which
// will fail tests prematurely.
validZoneHandler = data.handler && data.handler.toString() === '[object FunctionWrapper]';
} catch (error) {
// we can still try to add the data.handler even we are in cross site context
data.crossContext = true;
return data.invokeAddFunc(addFnSymbol, data.handler);
}
|
@mhevery , thank you for review! I tried several approaches and did some test.
Approach 1. current PR version.
Approach 2. comment the
|
@JiaLiPassion WOW, very impressive analysis! Kudos for such amazing work and insight! Yes approach 4/5 seems a way to go. It is our best hope to decrease the memory pressure and increases registration speed. In approach 5 how would task cancelation/rescheduling work? We have to make sure that this would continue to work. const someZone = Zone.current.fork({
name: 'someZone',
onScheduleTask:
(delegate: ZoneDelegate, current: Zone, target: Zone, task: Task):
Task => {
// Blacklist scroll, mouse, and request animation frame events.
if ((task.type === 'eventTask' || task.type === 'macroTask') &&
isBlacklistedEvent(task.source)) {
task.cancelScheduleRequest();
// Schedule task in root zone, note Zone.root != target,
// "target" Zone is Angular. Scheduling a task within Zone.root
// will prevent the infinite digest cycle from appearing.
return Zone.root.scheduleTask(task);
} else {
return delegate.scheduleTask(target, task);
}
}
});``` |
@mhevery , got it, I will try to find out Approach 5 work or not. |
Status
now the performance result is
native: 150ms 3.5x slower than native and 3x faster than current version.
native: 170 ms 3x slower than native and 3x faster than current version. changes from current implementation.add different handlers for same event , internal behavior changes
This is the biggest changes from current implementation.
will only run when browser is IE/Edge and cross context check is enabled by set Improvement point.Basically one point only.
Some codes may look ugly such as https://github.com/angular/zone.js/pull/812/files#diff-06332d8779803ae538dab973c558d328R218, the purpose is ** don't create additional objects ** Please review! Thank you! |
…ner performance
b27622f
to
5110e35
Compare
awesome progress...
…On Wed, Jun 21, 2017 at 7:16 PM, JiaLiPassion ***@***.***> wrote:
Progress.
Use Approach 5. still schedule event task, now the performance data will be
350~450 ms, it will be 3x native version, and I will continue to add some
optimization for zone.scheduleEventTask to remove some not needed
try/catch or new Function
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#812 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AAG1T5qS1_KLR6MMMnWftE2rrggxEci5ks5sGU_SgaJpZM4N2cXP>
.
|
@mhevery , thank you! currently all the test has passed, please review. And I will continue to check other tasks such as |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Minor changes requested
- It seems like we have added a lot of new code but have not deleted existing code. What is going?
- Could we somehow get this better packaged into
__load_patch
so that it is cleaner?
lib/browser/event-target.ts
Outdated
const zoneSymbolEventNames: any = {}; | ||
const globalSources: any = {}; | ||
|
||
const _global: any = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we get this from the patch function global? It would be better if we checked for global in exactly one place.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah, I will move this code into __load_patch
lib/browser/event-target.ts
Outdated
const BROWSER_TOOLS = 'function __BROWSERTOOLS_CONSOLE_SAFEFUNC() { [native code] }'; | ||
|
||
// predefine all __zone_symbol__ + eventName + true/false string | ||
eventNames.forEach((eventName: string) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could we use for
loop for perf reasons?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, will do.
lib/browser/event-target.ts
Outdated
}); | ||
|
||
// predefine all task.source string | ||
WTF_ISSUE_555.split(',').forEach((target: string) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could we use for
loop for perf reasons?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, will do
also thank you for the awesome work on investigating the perf and getting it down. |
@mhevery , I have updated the code.
target.addListener('msg', function() {
// here we can not get the event type which should be `msg`.
}); so we can't use But we can still benefit from other improvements, so I will move this PR's new
I will continue to make this code also work for |
@mhevery , I have updated the source.
new callback: 700ms
new callback: 440ms
Please review, Thank you. |
fix #798.
EventTarget.addEventListener
performance with @mhevery 's idea which described in Slow addEventListener performance. #798, we will not save aeventTask
list onevent target
, and will not go through thiseventTask
list to find whether we have already registered the event or not.instead we save the information to
callback
itself, sowill not slow down
nodejs
we still use the original way to savetaskList
,because in the
eventListener
callback, there is noeventName
information, andnodejs
support to add the identical listener multiple times.