New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.

Issue 710184 link

Starred by 2 users

Issue metadata

Status: Available
Owner: ----
Cc:
Components:
EstimatedDays: ----
NextAction: 2017-04-21
OS: All
Pri: 2
Type: Bug

Blocked on:
issue 712946



Sign in to add a comment

Defining custom elements is slow in Chrome

Project Member Reported by zhaoz@google.com, Apr 10 2017

Issue description

Tested on Chrome 57 on Nexus 5 I'm seeing element registration time taking 2x to 3x as much as generating the classes.

This is basically the code that would be necessary at startup before elements can bootup.

Test code is here: https://jsbin.com/yijinag/edit?html,js


From sorvell@ the `define` call seems to take about half as long on Safari.
 
Cc: hayato@chromium.org
Components: Blink>HTML>CustomElements
Labels: -Pri-3 -OS-Chrome Performance Pri-2
NextAction: 2017-04-21
Hayato or I will take a look. Half as long on Safari on what hardware?

Comment 2 by zhaoz@google.com, Apr 11 2017

Labels: -OS-Android OS-All
sorvell@ did the timing on that.

That said, I tried it on my macbook (retina, 15", mid 2014) running Sierra 10.12.3 and was able to reproduce this.

This version works on safari: https://output.jsbin.com/buqihekiqo

comparison between canary (59.0.3068.1 (Official Build) canary (64-bit))
and webkit technical preview.

Chrome canary:
x-foo -- class: 58.83999999999999 -- register: 95.63999999999999
x-bar -- class: 21.95999999999998 -- register: 92.09500000000003
x-blah -- class: 27.975000000000023 -- register: 90.61000000000001

Webkit Technical Preview:
x-foo -- class: 30.499999999999943 -- register: 32.100000000000136
x-bar -- class: 50.09999999999991 -- register: 37.60000000000002
x-blah -- class: 25.500000000000114 -- register: 33.10000000000002
Owner: dominicc@chromium.org
Status: Started (was: Untriaged)
Here's a perf profile. It looks like we spend a good chunk of time in Map::Set so let's start there. Now that there's TraceWrapper maybe we don't need to use maps so much?
out-ce.svg
2.3 MB Download
Blockedon: 712946
Here's another version which does more iterations and reports results without devtools open: https://jsbin.com/lokecuriyi/edit?js,output

I've uploaded a WIP patch here: https://codereview.chromium.org/2828643002

Before (times from my Z840):

x-foo -- class: 11 -- register: 23
x-bar -- class: 9 -- register: 19
x-blah -- class: 9 -- register: 17

After:

x-foo -- class: 15 -- register: 9
x-bar -- class: 12 -- register: 9
x-blah -- class: 11 -- register: 8

Your benchmark is a bit noisy and we'd benefit from using confidence intervals, but this is apparently faster. Garbage collection costs will have changed and I haven't measured them yet, however I believe tracing is incremental so I'm hopeful.
OK this patch is ready for review now: <https://codereview.chromium.org/2828643002>

Here's where <https://jsbin.com/kazajelubu/edit?js,output> is on my Z840 with 1000 elements:

Chrome 58.0.3029.81 (Official Build) (64-bit):

x-foo -- class: 8 -- register: 16
x-bar -- class: 9 -- register: 15
x-blah -- class: 11 -- register: 15

This patch:

x-foo -- class: 8 -- register: 9
x-bar -- class: 11 -- register: 7
x-blah -- class: 7 -- register: 10

These numbers are really noisy. On a different local benchmark, creating an empty class and defining it did cost about 16 usec and now costs about 8 usec.

There might be fat left in copying the observed attributes list from JavaScript which is why the difference is not as pronounced as the little benchmark on jsbin.

I noticed that the scalability of custom element definition registration is not great before *nor* after this change, but its once you get into the millions of *definitions* (not elements) on desktop that things start to fall over, so I think that's probably OK. I doubt authors will use millions of definitions. I think it's just garbage collection that makes it fall over.
Project Member

Comment 7 by bugdroid1@chromium.org, May 30 2017

The following revision refers to this bug:
  https://chromium.googlesource.com/chromium/src.git/+/d670e21d5c985e6a57f3f66e5bddf4e6f26c74c7

commit d670e21d5c985e6a57f3f66e5bddf4e6f26c74c7
Author: Dominic Cooney <dominicc@chromium.org>
Date: Tue May 30 03:27:35 2017

Remove custom element definition recursion check.

This check used to be important but now the spec disallows any
recursive registration so we do not need this constructor-specific
check any more.

Bug: 710184
Change-Id: I056997e7608e3327f9eb01d4e548eade062991ac
Reviewed-on: https://chromium-review.googlesource.com/515244
Reviewed-by: Kentaro Hara <haraken@chromium.org>
Commit-Queue: Dominic Cooney <dominicc@chromium.org>
Cr-Commit-Position: refs/heads/master@{#475415}
[modify] https://crrev.com/d670e21d5c985e6a57f3f66e5bddf4e6f26c74c7/third_party/WebKit/Source/bindings/core/v8/ScriptCustomElementDefinitionBuilder.cpp
[modify] https://crrev.com/d670e21d5c985e6a57f3f66e5bddf4e6f26c74c7/third_party/WebKit/Source/bindings/core/v8/ScriptCustomElementDefinitionBuilder.h

Cc: jbroman@chromium.org
With these patches and the ones in flight (up to <https://chromium-review.googlesource.com/c/520444/1>) define is roughly 2x faster than it was, but we're still roughly 2x slower than Safari 10.2 TP w/ WebKit 12604.1.22.

I will keep digging.
Project Member

Comment 11 by bugdroid1@chromium.org, Jun 2 2017

The following revision refers to this bug:
  https://chromium.googlesource.com/chromium/src.git/+/30a6b0e99b44267c4798f54e46cf81f82f399630

commit 30a6b0e99b44267c4798f54e46cf81f82f399630
Author: Dominic Cooney <dominicc@chromium.org>
Date: Fri Jun 02 00:56:19 2017

Don't hash custom element names when looking up definitions.

Mapping a custom element constructor to its definition used to look in
a JavaScript map from constructor to custom element name string, and
then hash that name to look up the custom element definition in the
registry.

After this change the JavaScript map values are IDs so the definition
can be retrieved directly from a vector. This avoids marshaling the
name string from V8 to C++, and avoids hashing the string, to look up
a definition. (There's still a map from name to ID on the side so that
CustomElementRegistry.get can look up definitions by name, but it is
not used in common operations like creating a custom element.)

Bug: 710184
Change-Id: I90ee5759bf692b5a2df43a4a59ef4fac94d22f2c
Reviewed-on: https://chromium-review.googlesource.com/520543
Commit-Queue: Dominic Cooney <dominicc@chromium.org>
Reviewed-by: Kentaro Hara <haraken@chromium.org>
Reviewed-by: Hayato Ito <hayato@chromium.org>
Cr-Commit-Position: refs/heads/master@{#476504}
[modify] https://crrev.com/30a6b0e99b44267c4798f54e46cf81f82f399630/third_party/WebKit/Source/bindings/core/v8/ScriptCustomElementDefinition.cpp
[modify] https://crrev.com/30a6b0e99b44267c4798f54e46cf81f82f399630/third_party/WebKit/Source/bindings/core/v8/ScriptCustomElementDefinition.h
[modify] https://crrev.com/30a6b0e99b44267c4798f54e46cf81f82f399630/third_party/WebKit/Source/bindings/core/v8/ScriptCustomElementDefinitionBuilder.cpp
[modify] https://crrev.com/30a6b0e99b44267c4798f54e46cf81f82f399630/third_party/WebKit/Source/bindings/core/v8/ScriptCustomElementDefinitionBuilder.h
[modify] https://crrev.com/30a6b0e99b44267c4798f54e46cf81f82f399630/third_party/WebKit/Source/core/dom/custom/CustomElementDefinition.h
[modify] https://crrev.com/30a6b0e99b44267c4798f54e46cf81f82f399630/third_party/WebKit/Source/core/dom/custom/CustomElementDefinitionBuilder.h
[modify] https://crrev.com/30a6b0e99b44267c4798f54e46cf81f82f399630/third_party/WebKit/Source/core/dom/custom/CustomElementRegistry.cpp
[modify] https://crrev.com/30a6b0e99b44267c4798f54e46cf81f82f399630/third_party/WebKit/Source/core/dom/custom/CustomElementRegistry.h
[modify] https://crrev.com/30a6b0e99b44267c4798f54e46cf81f82f399630/third_party/WebKit/Source/core/dom/custom/CustomElementRegistryTest.cpp
[modify] https://crrev.com/30a6b0e99b44267c4798f54e46cf81f82f399630/third_party/WebKit/Source/core/dom/custom/CustomElementTestHelpers.cpp
[modify] https://crrev.com/30a6b0e99b44267c4798f54e46cf81f82f399630/third_party/WebKit/Source/core/dom/custom/CustomElementTestHelpers.h

Project Member

Comment 12 by bugdroid1@chromium.org, Jun 2 2017

The following revision refers to this bug:
  https://chromium.googlesource.com/chromium/src.git/+/5606514830ad80953196a5b5ae9b8793e555ada8

commit 5606514830ad80953196a5b5ae9b8793e555ada8
Author: Dominic Cooney <dominicc@chromium.org>
Date: Fri Jun 02 03:08:57 2017

Reuse the TryCatch scope whe retrieving custom element properties.

Defining a custom element retrieves various properties. Previously
each retrieval used a separate TryCatch, which turns out to be
expensive. This makes them reuse a single TryCatch.

Bug: 710184
Change-Id: Ieadd5ba9c9197fd4a4a0b6b1faf3861d1df53f3b
Reviewed-on: https://chromium-review.googlesource.com/520962
Reviewed-by: Kentaro Hara <haraken@chromium.org>
Commit-Queue: Dominic Cooney <dominicc@chromium.org>
Cr-Commit-Position: refs/heads/master@{#476542}
[modify] https://crrev.com/5606514830ad80953196a5b5ae9b8793e555ada8/third_party/WebKit/Source/bindings/core/v8/ScriptCustomElementDefinitionBuilder.cpp
[modify] https://crrev.com/5606514830ad80953196a5b5ae9b8793e555ada8/third_party/WebKit/Source/bindings/core/v8/ScriptCustomElementDefinitionBuilder.h

Project Member

Comment 13 by bugdroid1@chromium.org, Jun 5 2017

The following revision refers to this bug:
  https://chromium.googlesource.com/chromium/src.git/+/a3ba2766d681b998cde9ca478cac8d3a7bbed218

commit a3ba2766d681b998cde9ca478cac8d3a7bbed218
Author: Dominic Cooney <dominicc@chromium.org>
Date: Mon Jun 05 05:32:35 2017

Tag custom element constructors with IDs for their definitions.

A constructor can be defined as a custom element in multiple contexts
simultaneously. With Reflect.construct the one constructor can mint
custom elements with different definitions. So the HTMLElement()
constructor needs to map from new.target (the constructor) to the tag
name and set of callbacks to use in that context.

Previously this was done with a JavaScript map, keyed by constructor,
which hung off the CustomElementRegistry. However that is slow. This
uses a v8::Private that is unique to a context to store the definition
ID on the constructor directly.

Bug: 710184
Change-Id: If03562bdcc3b6ffcb67c099f8b3939e2e0f73936
Reviewed-on: https://chromium-review.googlesource.com/520444
Commit-Queue: Dominic Cooney <dominicc@chromium.org>
Reviewed-by: Kentaro Hara <haraken@chromium.org>
Cr-Commit-Position: refs/heads/master@{#476947}
[modify] https://crrev.com/a3ba2766d681b998cde9ca478cac8d3a7bbed218/third_party/WebKit/Source/bindings/core/v8/ScriptCustomElementDefinition.cpp
[modify] https://crrev.com/a3ba2766d681b998cde9ca478cac8d3a7bbed218/third_party/WebKit/Source/platform/bindings/V8PerContextData.h
[modify] https://crrev.com/a3ba2766d681b998cde9ca478cac8d3a7bbed218/third_party/WebKit/Source/platform/bindings/V8PrivateProperty.h

Project Member

Comment 14 by sheriffbot@chromium.org, Jul 20 2017

Labels: Hotlist-Google

Comment 15 by zhaoz@google.com, Sep 27 2017

Any reason why this is restricted to Google only?

Comment 16 by kochi@chromium.org, Sep 29 2017

Labels: allpublic
Maybe the original reporter is @google.com address?

Labels: -Performance Performance-Browser
Owner: ----
Status: Available (was: Started)
Bulk edit bugs owned by dominicc@
Project Member

Comment 19 by sheriffbot@chromium.org, Jan 15

Labels: Hotlist-Recharge-Cold
Status: Untriaged (was: Available)
This issue has been Available for over a year. If it's no longer important or seems unlikely to be fixed, please consider closing it out. If it is important, please re-triage the issue.

Sorry for the inconvenience if the bug really should have been left as Available.

For more details visit https://www.chromium.org/issue-tracking/autotriage - Your friendly Sheriffbot
Labels: -Hotlist-Recharge-Cold
Status: Available (was: Untriaged)
Chrome 73 canary:
"x-foo -- class: 43.03000005893409 -- register: 101.30000009667128"
"x-bar -- class: 38.8449999736622 -- register: 101.00500006228685"
"x-blah -- class: 20.06999996956438 -- register: 101.00499994587153"

Safari TP 73:
"x-foo -- class: 65 -- register: 49"
"x-bar -- class: 65 -- register: 53.00000000000006"
"x-blah -- class: 50 -- register: 52"

Sign in to add a comment