diff options
author | Divy Srivastava <dj.srivastava23@gmail.com> | 2022-12-01 06:35:32 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-12-01 20:05:32 +0530 |
commit | 824cb485c542305d16e0b9dcfda0ce4a06cf5038 (patch) | |
tree | b85bdce59764246048a3d1f032c9137fa7347217 /ext/web/02_event.js | |
parent | 98d062e3dcd8804bd959ea41f6a0103ccd87f283 (diff) |
perf(ext/websocket): skip Events constructor checks (#16365)
WebSocket internal events can bypass Event's webidl checks and
`ReflectDefineProperty` on the object value. Note, this intentionally
makes websocket events `isTrusted` configurable (not spec-compliant)
which hurts performance a lot.
Before:
```
Msg/sec: 167627.750000
Msg/sec: 168239.250000
Msg/sec: 169690.000000
```
After:
```
Msg/sec: 191065.500000
Msg/sec: 194745.250000
Msg/sec: 194746.000000
```
Diffstat (limited to 'ext/web/02_event.js')
-rw-r--r-- | ext/web/02_event.js | 68 |
1 files changed, 45 insertions, 23 deletions
diff --git a/ext/web/02_event.js b/ext/web/02_event.js index d915b5f20..fa1c94332 100644 --- a/ext/web/02_event.js +++ b/ext/web/02_event.js @@ -139,6 +139,8 @@ const _dispatched = Symbol("[[dispatched]]"); const _isTrusted = Symbol("[[isTrusted]]"); const _path = Symbol("[[path]]"); + // internal. + const _skipInternalInit = Symbol("[[skipSlowInit]]"); class Event { constructor(type, eventInitDict = {}) { @@ -152,29 +154,47 @@ this[_isTrusted] = false; this[_path] = []; - webidl.requiredArguments(arguments.length, 1, { - prefix: "Failed to construct 'Event'", - }); - type = webidl.converters.DOMString(type, { - prefix: "Failed to construct 'Event'", - context: "Argument 1", - }); - const eventInit = eventInitConverter(eventInitDict, { - prefix: "Failed to construct 'Event'", - context: "Argument 2", - }); - this[_attributes] = { - type, - ...eventInit, - currentTarget: null, - eventPhase: Event.NONE, - target: null, - timeStamp: DateNow(), - }; - ReflectDefineProperty(this, "isTrusted", { - enumerable: true, - get: isTrusted, - }); + if (!eventInitDict[_skipInternalInit]) { + webidl.requiredArguments(arguments.length, 1, { + prefix: "Failed to construct 'Event'", + }); + type = webidl.converters.DOMString(type, { + prefix: "Failed to construct 'Event'", + context: "Argument 1", + }); + const eventInit = eventInitConverter(eventInitDict, { + prefix: "Failed to construct 'Event'", + context: "Argument 2", + }); + this[_attributes] = { + type, + ...eventInit, + currentTarget: null, + eventPhase: Event.NONE, + target: null, + timeStamp: DateNow(), + }; + // [LegacyUnforgeable] + ReflectDefineProperty(this, "isTrusted", { + enumerable: true, + get: isTrusted, + }); + } else { + this[_attributes] = { + type, + data: eventInitDict.data ?? null, + bubbles: eventInitDict.bubbles ?? false, + cancelable: eventInitDict.cancelable ?? false, + composed: eventInitDict.composed ?? false, + currentTarget: null, + eventPhase: Event.NONE, + target: null, + timeStamp: DateNow(), + }; + // TODO(@littledivy): Not spec compliant but performance is hurt badly + // for users of `_skipInternalInit`. + this.isTrusted = false; + } } [SymbolFor("Deno.privateCustomInspect")](inspect) { @@ -1191,6 +1211,7 @@ bubbles: eventInitDict?.bubbles ?? false, cancelable: eventInitDict?.cancelable ?? false, composed: eventInitDict?.composed ?? false, + [_skipInternalInit]: eventInitDict?.[_skipInternalInit], }); this.data = eventInitDict?.data ?? null; @@ -1481,6 +1502,7 @@ setIsTrusted, setTarget, defineEventHandler, + _skipInternalInit, Event, ErrorEvent, CloseEvent, |