-
Notifications
You must be signed in to change notification settings - Fork 29.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
lib: define Event.isTrusted in the prototype #46974
lib: define Event.isTrusted in the prototype #46974
Conversation
9235d8d
to
6cf3af6
Compare
Do we understand why the spec'ed implementation is so much slower? Is it something that V8 could improve? |
I think https://bugs.chromium.org/p/v8/issues/detail?id=8447 might be relevant |
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.
Seems like a good tradeoff to me: obscure and largely irrelevant property vs. big performance jump.
Don't conform to the spec with isTrusted. The spec defines it as `LegacyUnforgeable` but defining it in the constructor has a big performance impact and the property doesn't seem to be useful outside of browsers. Refs: nodejs/performance#32
6cf3af6
to
f7c80d9
Compare
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.
🚀
Given that we are intentionally deviating from the spec here, the docs should be updated to reflect that deviation |
Landed in 74b9cf2 |
Don't conform to the spec with isTrusted. The spec defines it as `LegacyUnforgeable` but defining it in the constructor has a big performance impact and the property doesn't seem to be useful outside of browsers. Refs: nodejs/performance#32 PR-URL: #46974 Reviewed-By: Yagiz Nizipli <[email protected]> Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: James M Snell <[email protected]>
Don't conform to the spec with isTrusted. The spec defines it as `LegacyUnforgeable` but defining it in the constructor has a big performance impact and the property doesn't seem to be useful outside of browsers. Refs: nodejs/performance#32 PR-URL: #46974 Reviewed-By: Yagiz Nizipli <[email protected]> Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: James M Snell <[email protected]>
Don't conform to the spec with isTrusted. The spec defines it as `LegacyUnforgeable` but defining it in the constructor has a big performance impact and the property doesn't seem to be useful outside of browsers. Refs: nodejs/performance#32 PR-URL: #46974 Reviewed-By: Yagiz Nizipli <[email protected]> Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: James M Snell <[email protected]>
Don't conform to the spec with isTrusted. The spec defines it as `LegacyUnforgeable` but defining it in the constructor has a big performance impact and the property doesn't seem to be useful outside of browsers. Refs: nodejs/performance#32 PR-URL: #46974 Reviewed-By: Yagiz Nizipli <[email protected]> Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: James M Snell <[email protected]>
Don't conform to the spec with isTrusted. The spec defines it as `LegacyUnforgeable` but defining it in the constructor has a big performance impact and the property doesn't seem to be useful outside of browsers. Refs: nodejs/performance#32 PR-URL: #46974 Reviewed-By: Yagiz Nizipli <[email protected]> Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: James M Snell <[email protected]>
Don't conform to the spec with isTrusted. The spec defines it as `LegacyUnforgeable` but defining it in the constructor has a big performance impact and the property doesn't seem to be useful outside of browsers. Refs: nodejs/performance#32 PR-URL: #46974 Reviewed-By: Yagiz Nizipli <[email protected]> Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: James M Snell <[email protected]>
Don't conform to the spec with isTrusted. The spec defines it as `LegacyUnforgeable` but defining it in the constructor has a big performance impact and the property doesn't seem to be useful outside of browsers. Refs: nodejs/performance#32 PR-URL: nodejs#46974 Reviewed-By: Yagiz Nizipli <[email protected]> Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: James M Snell <[email protected]>
This PR optimizes `Event` constructor - ~Added a fast path for empty `eventInitDict`~ Removed `EventInit` dictionary converter - Don't make `isTrusted` a [LegacyUnforgeable](https://webidl.spec.whatwg.org/#LegacyUnforgeable) property. Doing so makes it non-spec compliant but calling `Object/Reflect.defineProperty` on the constructor is a big bottleneck. Node did the same a few months ago nodejs/node#46974. In my opinion, the performance gains are worth deviating from the spec for a browser-related property. **This PR** ``` cpu: 13th Gen Intel(R) Core(TM) i9-13900H runtime: deno 1.36.1 (x86_64-unknown-linux-gnu) benchmark time (avg) iter/s (min … max) p75 p99 p995 ------------------------------------------------------------------------------- ----------------------------- event constructor no init 36.69 ns/iter 27,257,504.6 (33.36 ns … 42.45 ns) 37.71 ns 39.61 ns 40.07 ns event constructor 36.7 ns/iter 27,246,776.6 (33.35 ns … 56.03 ns) 37.73 ns 40.14 ns 41.74 ns ``` **main** ``` cpu: 13th Gen Intel(R) Core(TM) i9-13900H runtime: deno 1.36.1 (x86_64-unknown-linux-gnu) benchmark time (avg) iter/s (min … max) p75 p99 p995 ------------------------------------------------------------------------------- ----------------------------- event constructor no init 380.48 ns/iter 2,628,275.8 (366.66 ns … 399.39 ns) 384.58 ns 398.27 ns 399.39 ns event constructor 480.33 ns/iter 2,081,882.6 (466.67 ns … 503.47 ns) 484.27 ns 501.28 ns 503.47 ns ``` ```js Deno.bench("event constructor no init", () => { const event = new Event("foo"); }); Deno.bench("event constructor", () => { const event = new Event("foo", { bubbles: true, cancelable: false }); }); ``` towards #20167
This PR optimizes `Event` constructor - ~Added a fast path for empty `eventInitDict`~ Removed `EventInit` dictionary converter - Don't make `isTrusted` a [LegacyUnforgeable](https://webidl.spec.whatwg.org/#LegacyUnforgeable) property. Doing so makes it non-spec compliant but calling `Object/Reflect.defineProperty` on the constructor is a big bottleneck. Node did the same a few months ago nodejs/node#46974. In my opinion, the performance gains are worth deviating from the spec for a browser-related property. **This PR** ``` cpu: 13th Gen Intel(R) Core(TM) i9-13900H runtime: deno 1.36.1 (x86_64-unknown-linux-gnu) benchmark time (avg) iter/s (min … max) p75 p99 p995 ------------------------------------------------------------------------------- ----------------------------- event constructor no init 36.69 ns/iter 27,257,504.6 (33.36 ns … 42.45 ns) 37.71 ns 39.61 ns 40.07 ns event constructor 36.7 ns/iter 27,246,776.6 (33.35 ns … 56.03 ns) 37.73 ns 40.14 ns 41.74 ns ``` **main** ``` cpu: 13th Gen Intel(R) Core(TM) i9-13900H runtime: deno 1.36.1 (x86_64-unknown-linux-gnu) benchmark time (avg) iter/s (min … max) p75 p99 p995 ------------------------------------------------------------------------------- ----------------------------- event constructor no init 380.48 ns/iter 2,628,275.8 (366.66 ns … 399.39 ns) 384.58 ns 398.27 ns 399.39 ns event constructor 480.33 ns/iter 2,081,882.6 (466.67 ns … 503.47 ns) 484.27 ns 501.28 ns 503.47 ns ``` ```js Deno.bench("event constructor no init", () => { const event = new Event("foo"); }); Deno.bench("event constructor", () => { const event = new Event("foo", { bubbles: true, cancelable: false }); }); ``` towards denoland#20167
This PR optimizes `Event` constructor - ~Added a fast path for empty `eventInitDict`~ Removed `EventInit` dictionary converter - Don't make `isTrusted` a [LegacyUnforgeable](https://webidl.spec.whatwg.org/#LegacyUnforgeable) property. Doing so makes it non-spec compliant but calling `Object/Reflect.defineProperty` on the constructor is a big bottleneck. Node did the same a few months ago nodejs/node#46974. In my opinion, the performance gains are worth deviating from the spec for a browser-related property. **This PR** ``` cpu: 13th Gen Intel(R) Core(TM) i9-13900H runtime: deno 1.36.1 (x86_64-unknown-linux-gnu) benchmark time (avg) iter/s (min … max) p75 p99 p995 ------------------------------------------------------------------------------- ----------------------------- event constructor no init 36.69 ns/iter 27,257,504.6 (33.36 ns … 42.45 ns) 37.71 ns 39.61 ns 40.07 ns event constructor 36.7 ns/iter 27,246,776.6 (33.35 ns … 56.03 ns) 37.73 ns 40.14 ns 41.74 ns ``` **main** ``` cpu: 13th Gen Intel(R) Core(TM) i9-13900H runtime: deno 1.36.1 (x86_64-unknown-linux-gnu) benchmark time (avg) iter/s (min … max) p75 p99 p995 ------------------------------------------------------------------------------- ----------------------------- event constructor no init 380.48 ns/iter 2,628,275.8 (366.66 ns … 399.39 ns) 384.58 ns 398.27 ns 399.39 ns event constructor 480.33 ns/iter 2,081,882.6 (466.67 ns … 503.47 ns) 484.27 ns 501.28 ns 503.47 ns ``` ```js Deno.bench("event constructor no init", () => { const event = new Event("foo"); }); Deno.bench("event constructor", () => { const event = new Event("foo", { bubbles: true, cancelable: false }); }); ``` towards #20167
We have been discussing in nodejs/performance#32 whether deviating from the spec with regards to
Event.isTrusted
would be acceptable for Node.js in order to avoid a significant performance hit. The spec defines the property asLegacyUnforgeable
, but defining the property in the prototype instead of the constructor produces the following numbers:I'd like to have some feedback whether a change like this would be ok for Node.js (not being in the browser), specially from people more familiar with the standard. If that's the case I'll update the tests that are currently failing. Thanks!