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

Issue 620142 link

Starred by 16 users

Issue metadata

Status: Fixed
Owner:
Closed: Jun 2016
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: ----
Pri: 1
Type: Bug-Regression

Blocked on:
issue 624220



Sign in to add a comment

Deleting many options from select element has become very slow.

Reported by stu...@ziprecruiter.com, Jun 14 2016

Issue description

Chrome Version       : 53.0.2763.0 (Official Build) dev (64-bit)
URLs (if applicable) : https://jsfiddle.net/gus4787g/5/
Other browsers tested:
    Firefox: OK - 47.0

What steps will reproduce the problem?
(1) Delete many options from a select.


What is the expected result?
It should be quick.

What happens instead?
It is very slow.

Please provide any additional information below. Attach a screenshot if
possible.

This code worked fine in previous versions of Chrome. Now it is very slow and causes the page to become unresponsive.
 

Comment 1 by lbe...@gmail.com, Jun 15 2016

This may be a duplicate of https://bugs.chromium.org/p/chromium/issues/detail?id=615488.
Cc: pucchakayala@chromium.org cbiesin...@chromium.org
 Issue 615488  has been merged into this issue.

Comment 3 by phistuck@gmail.com, Jun 15 2016

Reduced test case without jQuery -
https://jsfiddle.net/qLt94cvc/
Another one without using appendChild explicitly, using innerHTML = "" instead -
https://jsfiddle.net/y9xenbtx/
Labels: -Type-Bug -Pri-3 Needs-Bisect Pri-1 Type-Bug-Regression
Status: Untriaged (was: Unconfirmed)
Components: Blink>HTML Blink>DOM
Hmm, according to the reporter's trace in the duplicate bug, there's a *lot* of calls to Node::updateDistribution, which take 8ms each.

According to my own trace (Canary), there's a lot of calls to HTMLSelectElement::selectOption, at 9ms each.
trace_Wed_Jun_15_2016_6.08.09_PM.json.gz
10.3 MB Download

Comment 6 by lbe...@gmail.com, Jun 15 2016

Just to note, this affects Chrome 51+ (see  Issue 615488 ).
Components: -Blink>HTML Blink>Forms
Owner: hayato@chromium.org
Status: Assigned (was: Untriaged)
hayato, could you take a first look at this since cbiesinger mentions Node::updateDistribution.

Comment 8 by tkent@chromium.org, Jun 16 2016

Cc: hayato@chromium.org
Components: -Blink>DOM -Blink>Forms Blink>Forms>Select
Owner: tkent@chromium.org
Probably this is a regression by my CL: https://codereview.chromium.org/1837463002

Workaround:
 - Remove the OPTIONS in the reverse order, or
 - Adding "multiple" to the SELECT element during the OPTION removal.

Removing select elements is still fast when the select is not attached to the DOM.
So a quick workaround for us was to detach the select from the DOM, mutate it, and re-attach it.


 
Labels: -Needs-Bisect
Project Member

Comment 11 by bugdroid1@chromium.org, Jun 17 2016

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

commit 8e352afa95e7b7e9ef0d3cd383d3bac58467097c
Author: tkent <tkent@chromium.org>
Date: Fri Jun 17 07:46:53 2016

Add a performance test for removing OPTIONs from a SELECT element.

BUG= 620142 

Review-Url: https://codereview.chromium.org/2079743002
Cr-Commit-Position: refs/heads/master@{#400392}

[add] https://crrev.com/8e352afa95e7b7e9ef0d3cd383d3bac58467097c/third_party/WebKit/PerformanceTests/DOM/select-single-remove.html

Comment 12 by tkent@chromium.org, Jun 20 2016

Status: Started (was: Assigned)
Project Member

Comment 13 by bugdroid1@chromium.org, Jun 20 2016

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

commit 49796c5e364e736e2ae3b8a12660b136b1135c9f
Author: tkent <tkent@chromium.org>
Date: Mon Jun 20 09:09:24 2016

Fix a wrong test landed in r400392.

We need to clear |selected| state on every test run because every OPTION is
selected after removeChild().

This CL makes select-single-remove.html very slower.

BUG= 620142 
TBR=keishi@chromium.org

Review-Url: https://codereview.chromium.org/2079233002
Cr-Commit-Position: refs/heads/master@{#400639}

[modify] https://crrev.com/49796c5e364e736e2ae3b8a12660b136b1135c9f/third_party/WebKit/PerformanceTests/DOM/select-single-remove.html

Project Member

Comment 14 by bugdroid1@chromium.org, Jun 21 2016

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

commit 1b32ab54ae3451e24152fc1e433b7e1cb44ac56e
Author: tkent <tkent@chromium.org>
Date: Tue Jun 21 05:50:13 2016

Improve performance to remove OPTIONs from a single-selection SELECT.

LayoutMenuList::updateOptionsHeightWidth() is an O(n) function to get maximum
OPTION width and height.

We had a bad performance because it is called whenever we remove a selected
OPTION from a SELECT. This CL changes the timing of updateOptionsHeightWidth().

Old:
  It was called by updateFromElement() after an OPTION is
  added/removed. updateOptionsHeightWidth() makes layout dirty only if maximum
  width/height was changed.

New:
  OPTION addition/removal makes maximum width/height dirty and makes layout
  dirty, and updateOptionsHeightWidth() is called only if the maximum
  width/height is referred.

The new behavior makes layout dirty more frequently, however it reduces the
number of updateOptionsHeightWidth() calls significantly.

This CL makes PerformanceTests/DOM/select-single-remove.html faster.
On my local machine, 5.1 runs/s -> 45.1 runs/s

Test update:
* http/tests/webfont/popup-menu-load-webfont-after-open.html
  LayoutMenuList correctly updates its width and height after this CL.
* fast/repaint/control-clip.html
  Extra invalidation as expected.

BUG= 620142 

Review-Url: https://codereview.chromium.org/2077343002
Cr-Commit-Position: refs/heads/master@{#400903}

[modify] https://crrev.com/1b32ab54ae3451e24152fc1e433b7e1cb44ac56e/third_party/WebKit/LayoutTests/TestExpectations
[modify] https://crrev.com/1b32ab54ae3451e24152fc1e433b7e1cb44ac56e/third_party/WebKit/Source/core/inspector/InspectorTraceEvents.cpp
[modify] https://crrev.com/1b32ab54ae3451e24152fc1e433b7e1cb44ac56e/third_party/WebKit/Source/core/inspector/InspectorTraceEvents.h
[modify] https://crrev.com/1b32ab54ae3451e24152fc1e433b7e1cb44ac56e/third_party/WebKit/Source/core/layout/LayoutMenuList.cpp
[modify] https://crrev.com/1b32ab54ae3451e24152fc1e433b7e1cb44ac56e/third_party/WebKit/Source/core/layout/LayoutMenuList.h

Project Member

Comment 15 by bugdroid1@chromium.org, Jun 21 2016

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

commit 67cb9c6f16539c0b128c181a7fdaff5b77019ec8
Author: Rebaseline Bot <blink-rebaseline-bot@chromium.org>
Date: Tue Jun 21 06:54:18 2016

Auto-rebaseline for r400903

https://chromium.googlesource.com/chromium/src/+/1b32ab54a

BUG= 620142 
TBR=tkent@chromium.org

Review URL: https://codereview.chromium.org/2084693003 .

Cr-Commit-Position: refs/heads/master@{#400913}

[modify] https://crrev.com/67cb9c6f16539c0b128c181a7fdaff5b77019ec8/third_party/WebKit/LayoutTests/TestExpectations
[modify] https://crrev.com/67cb9c6f16539c0b128c181a7fdaff5b77019ec8/third_party/WebKit/LayoutTests/platform/linux/fast/repaint/control-clip-expected.txt
[modify] https://crrev.com/67cb9c6f16539c0b128c181a7fdaff5b77019ec8/third_party/WebKit/LayoutTests/platform/linux/http/tests/webfont/popup-menu-load-webfont-after-open-expected.png
[modify] https://crrev.com/67cb9c6f16539c0b128c181a7fdaff5b77019ec8/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/repaint/control-clip-expected.txt
[modify] https://crrev.com/67cb9c6f16539c0b128c181a7fdaff5b77019ec8/third_party/WebKit/LayoutTests/platform/mac-mac10.10/http/tests/webfont/popup-menu-load-webfont-after-open-expected.png
[modify] https://crrev.com/67cb9c6f16539c0b128c181a7fdaff5b77019ec8/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/repaint/control-clip-expected.txt
[modify] https://crrev.com/67cb9c6f16539c0b128c181a7fdaff5b77019ec8/third_party/WebKit/LayoutTests/platform/mac-mac10.9/http/tests/webfont/popup-menu-load-webfont-after-open-expected.png
[modify] https://crrev.com/67cb9c6f16539c0b128c181a7fdaff5b77019ec8/third_party/WebKit/LayoutTests/platform/mac/fast/repaint/control-clip-expected.txt
[modify] https://crrev.com/67cb9c6f16539c0b128c181a7fdaff5b77019ec8/third_party/WebKit/LayoutTests/platform/mac/http/tests/webfont/popup-menu-load-webfont-after-open-expected.png
[modify] https://crrev.com/67cb9c6f16539c0b128c181a7fdaff5b77019ec8/third_party/WebKit/LayoutTests/platform/win/fast/repaint/control-clip-expected.txt
[modify] https://crrev.com/67cb9c6f16539c0b128c181a7fdaff5b77019ec8/third_party/WebKit/LayoutTests/platform/win/http/tests/webfont/popup-menu-load-webfont-after-open-expected.png
[delete] https://crrev.com/31145e9ef2f85e04708485c1598cfe8bef91ab37/third_party/WebKit/LayoutTests/platform/win7/http/tests/webfont/popup-menu-load-webfont-after-open-expected.png

Comment 16 by lbe...@gmail.com, Jun 21 2016

Thanks for working on this issue. Please note that from the performance comparison provided here: https://bugs.chromium.org/p/chromium/issues/detail?id=615488#c5 it seems that while this fix may address the performance issue, from the numbers provided it appears that there is still a pretty severe performance issue. 

c#14 shows a 9x improvement, but from the previously uploaded videos we were observing a 28x slowdown from Chrome 50 to 51 (~2.5 seconds to 85 seconds respectively). 

We'll test in Canary as soon as this revision lands, but can some additional investigation be done to see if it is possible to get the performance back to what is was like in 50?

Thanks!

Comment 17 by tkent@chromium.org, Jun 22 2016

Labels: M-53
Status: Fixed (was: Started)
53.0.2776.0 canary has the fix.

> https://jsfiddle.net/qLt94cvc/

Removing 10,000 OPTIONs takes:
 - 20.284 sec with Google Chrome 51 stable
 - 1.548 sec with 53.0.2776.0 canary
 - 2.029 sec with Firefox 47.0

Unfortunately it's hard to merge the fix to 52 branch because of LayoutMenuList.* had other changes after the branch cut.

Comment 18 by lbe...@gmail.com, Jun 22 2016

Is there any way to get this into Chrome 52? Waiting for a fix until September is going to be tough.
Cc: dglazkov@chromium.org
Labels: Merge-Request-52
This bug is really hurting some users. It seems worth merging even if the effort is non-trivial. Can PM's weigh in?

+dglazkov to get his perspective on this major perf problem.

Comment 20 by dimu@google.com, Jun 23 2016

Labels: -Merge-Request-52 Merge-Approved-52 Hotlist-Merge-Approved
Your change meets the bar and is auto-approved for M52 (branch: 2743)
Wow, even a wait for Chrome 52 to get that fixed is a real pain to deal with. Estimated release date is for end of july. Dropdown menus are an essential part of the web, you can't tell people every websites with <select> menus could turn very slow for few weeks. Chrome needs to find a way to be more reactive for this kind of major regression performance and stability bugs. Each day, you'll loose users (here!). It takes time to get new users, it takes 2 seconds to loose them forever. 

Comment 22 by phistuck@gmail.com, Jun 23 2016

#21 - it is only slow when you have many (many) options, which is, from what I can tell -
- Not that common (especially emptying those select boxes).
- Bad user experience, so websites usually use an automatic completion feature instead.
#22
It might not be that common for regular websites, but sales web applications (ex: salesforces) are using a lot of <select> menus that are emptied and refilled frequently for many good reasons. I'm just thinking about carts having many dropdown menus to manage quantities, items, etc. Also, autocompletion feature might be a good temporary patch, but is trickier to handle data validation and since is't not a native HTML feature, it surely comes with a none-negligeable performance cost.

In any way, my point is when there's a native html feature that is experiencing major performance issues, this should always be addressed asap and not only expected to be fixed within the next 1-2-3 months. I don't know how Chrome's team does its tests and I'm pretty sure they are doing a wonderful job, however they should maybe develop a more in-depth performance stress-test platform to supervise all common html/css/javascript operations before releasing a new version. Our users and partners markets are all running on Chrome for our sales app and it's been very stresful to handle.

Cheers.

Comment 24 by phistuck@gmail.com, Jun 23 2016

#23 -
At least for the quantities, <input type=number min=0 max=20> would also work.

I think there are alternatives and yes, some of them require a non trivial implementation (though jQuery UI and similar provide them).

There are performance tests. There are also real world website performance tests, however, they are focused on home pages (I think) of the top 1000 websites or something like that. You cannot test everything in advance, unfortunately.
Fortunately, a test was added for option removal, so this breakage should not repeat itself.

Since this use case is not used in a lot of places (I reckon), its urgency is lowered, especially since the fix is not trivial. Chrome 52 will be out in a month or so (not three). I understand your frustration, but putting all of the users at risk due to a non trivial merge is generally not something Chrome does, but who knows.
Owner: schenney@chromium.org
Taking ownership for the merge. Will assign back to tkent when done.
I've landed the manual merge into m52. I'm not 100% certain I did it correctly, so it would be very nice if someone could test m52 with the fiddle from #17.
Project Member

Comment 27 by bugdroid1@chromium.org, Jun 24 2016

Labels: -merge-approved-52 merge-merged-2743
The following revision refers to this bug:
  https://chromium.googlesource.com/chromium/src.git/+/e5e943c56399f02d9ffe9de622d38733fb956cbf

commit e5e943c56399f02d9ffe9de622d38733fb956cbf
Author: Stephen Chenney <schenney@chromium.org>
Date: Fri Jun 24 13:39:18 2016

Improve performance to remove OPTIONs from a single-selection SELECT.

Manual merge from m53 to m52.

LayoutMenuList::updateOptionsHeightWidth() is an O(n) function to get maximum
OPTION width and height.

We had a bad performance because it is called whenever we remove a selected
OPTION from a SELECT. This CL changes the timing of updateOptionsHeightWidth().

Old:
  It was called by updateFromElement() after an OPTION is
  added/removed. updateOptionsHeightWidth() makes layout dirty only if maximum
  width/height was changed.

New:
  OPTION addition/removal makes maximum width/height dirty and makes layout
  dirty, and updateOptionsHeightWidth() is called only if the maximum
  width/height is referred.

The new behavior makes layout dirty more frequently, however it reduces the
number of updateOptionsHeightWidth() calls significantly.

This CL makes PerformanceTests/DOM/select-single-remove.html faster.
On my local machine, 5.1 runs/s -> 45.1 runs/s

Test update:
* http/tests/webfont/popup-menu-load-webfont-after-open.html
  LayoutMenuList correctly updates its width and height after this CL.
* fast/repaint/control-clip.html
  Extra invalidation as expected.

TBR=tkent@chromium.org
BUG= 620142 
Review-Url: https://codereview.chromium.org/2077343002
Cr-Commit-Position: refs/heads/master@{#400903}
(cherry picked from commit 1b32ab54ae3451e24152fc1e433b7e1cb44ac56e)

Review URL: https://codereview.chromium.org/2093563005 .

Cr-Commit-Position: refs/branch-heads/2743@{#466}
Cr-Branched-From: 2b3ae3b8090361f8af5a611712fc1a5ab2de53cb-refs/heads/master@{#394939}

[modify] https://crrev.com/e5e943c56399f02d9ffe9de622d38733fb956cbf/third_party/WebKit/Source/core/inspector/InspectorTraceEvents.cpp
[modify] https://crrev.com/e5e943c56399f02d9ffe9de622d38733fb956cbf/third_party/WebKit/Source/core/inspector/InspectorTraceEvents.h
[modify] https://crrev.com/e5e943c56399f02d9ffe9de622d38733fb956cbf/third_party/WebKit/Source/core/layout/LayoutMenuList.cpp
[modify] https://crrev.com/e5e943c56399f02d9ffe9de622d38733fb956cbf/third_party/WebKit/Source/core/layout/LayoutMenuList.h

Back to tkent because he deserves the credit for fixing this.

I verified a chrome build in the 2743 branch and all was good.
Cc: joh...@chromium.org
 Issue 623604  has been merged into this issue.
Blocking: 623891
Labels: -M-53 M-52
This isn't fully fixed - it's still quadratic in m53 with tkent's patch, whereas it used to take linear time in m50. See https://bugs.chromium.org/p/chromium/issues/detail?id=623891#c2

Since this patch has already been merged, let's continue investigating this in that bug.

Comment 32 by tkent@chromium.org, Jun 28 2016

The remaining issue is  Issue 577989 .

Comment 33 by tkent@chromium.org, Jun 28 2016

Blocking: -623891

Comment 34 by tkent@chromium.org, Jun 28 2016

Blocking: 623891
Cc: schenney@chromium.org tkent@chromium.org
 Issue 623891  has been merged into this issue.

Comment 35 by e...@chromium.org, Jun 28 2016

Cc: e...@chromium.org kojii@chromium.org ajha@chromium.org
 Issue 611169  has been merged into this issue.

Comment 36 by tkent@chromium.org, Jun 29 2016

Blockedon: 624220

Comment 37 by tkent@chromium.org, Jun 29 2016

Blocking: -623891
I have some quick hack ideas to improve the performance more.  It's tracked in  Issue 624220 .

Project Member

Comment 38 by bugdroid1@chromium.org, Jun 29 2016

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

commit 6aa050448c3f5a8e6749e059ec9ec62adb685a70
Author: tkent <tkent@chromium.org>
Date: Wed Jun 29 04:10:28 2016

Improve performance to remove an OPTION from a SELECT element.

This CL optimize HTMLSelectElement::resetToDefaultSelection(). We can quit the
loop if a selected OPTION was removed.

Removing 20,000 OPTIONs: 7,595ms -> 6,358ms

BUG= 620142 ,  624220 

Review-Url: https://codereview.chromium.org/2108883003
Cr-Commit-Position: refs/heads/master@{#402709}

[modify] https://crrev.com/6aa050448c3f5a8e6749e059ec9ec62adb685a70/third_party/WebKit/Source/core/html/HTMLSelectElement.cpp
[modify] https://crrev.com/6aa050448c3f5a8e6749e059ec9ec62adb685a70/third_party/WebKit/Source/core/html/HTMLSelectElement.h

Project Member

Comment 39 by bugdroid1@chromium.org, Jun 29 2016

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

commit 8881397e890dd70a187a957ae6910f141d378eb5
Author: tkent <tkent@chromium.org>
Date: Wed Jun 29 04:41:22 2016

Improve performance of SELECT element by optimizing Vector.

Replace Vector::clear() with Vector::resize(0) to avoid to deallocate Vector
buffers.

Removing 20,000 OPTIONs: 7,595ms -> 5,779ms

BUG= 620142 ,  624220 

Review-Url: https://codereview.chromium.org/2105863003
Cr-Commit-Position: refs/heads/master@{#402720}

[modify] https://crrev.com/8881397e890dd70a187a957ae6910f141d378eb5/third_party/WebKit/Source/core/html/HTMLSelectElement.cpp

Project Member

Comment 40 by bugdroid1@chromium.org, Jun 29 2016

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

commit 25445ac85b61754a12be2ccc65ddb1ef5aa96635
Author: tkent <tkent@chromium.org>
Date: Wed Jun 29 10:03:22 2016

Improve performance of HTMLSelectElement::setActiveSelectionAnchor().

Do not update m_cachedStateForActiveSelection if it's a
menulist. m_cachedStateForActiveSelection is used only in listboxes.

Removing 20,000 OPTIONs: 4,787ms -> 3,772ms

BUG= 620142 ,  624220 

Review-Url: https://codereview.chromium.org/2104883004
Cr-Commit-Position: refs/heads/master@{#402765}

[modify] https://crrev.com/25445ac85b61754a12be2ccc65ddb1ef5aa96635/third_party/WebKit/Source/core/html/HTMLSelectElement.cpp
[modify] https://crrev.com/25445ac85b61754a12be2ccc65ddb1ef5aa96635/third_party/WebKit/Source/core/html/HTMLSelectElement.h

Project Member

Comment 41 by bugdroid1@chromium.org, Jun 29 2016

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

commit 454e5952a2623d05d272939c01b4b09535be40a3
Author: tkent <tkent@chromium.org>
Date: Wed Jun 29 10:12:19 2016

Improve performance of HTMLSelectElement::resetToDefaultSelection().

If we remove a selected OPTION from a SELECT element, selectOption() called from
resetToDefaultSelection() doesn't need to call deselectItemsWithoutValidation()
because there are no other selected OPTIONs.

- !multiple() doesn't imply DeselectOtherOptions.  Updates existing callsites of
  selectOption().
- Make SelectOptionFlags mandatory.

Removing 20,000 OPTIONs: 6,348ms -> 5,324ms

BUG= 620142 ,  624220 

Review-Url: https://codereview.chromium.org/2110003002
Cr-Commit-Position: refs/heads/master@{#402767}

[modify] https://crrev.com/454e5952a2623d05d272939c01b4b09535be40a3/third_party/WebKit/Source/core/html/HTMLSelectElement.cpp
[modify] https://crrev.com/454e5952a2623d05d272939c01b4b09535be40a3/third_party/WebKit/Source/core/html/HTMLSelectElement.h

tkent wrote:
> The remaining issue is  Issue 577989 .

Are you sure?  Issue 577989  was filed around the m49 timeframe, whereas the major regression occurred between m50 and m51. The small improvements in  issue 624220  are nice, but this used to be two orders of magnitude faster (39ms to remove 20000 options, as opposed to 3772ms after all patches in this bug and  issue 624220 ).

Do we know what CL caused the rest of the regression (beyond what you already fixed in https://codereview.chromium.org/2077343002)? If not, perhaps we should bisect?
Ok, I can confirm that the initial regression was caused by https://codereview.chromium.org/1837463002

Comment 44 by tkent@chromium.org, Jun 30 2016

yes, I'm very sure of it.  The culprit change added selectOption() call during removeChid(), and we can't remove selectOption() according to the HTML specification.


Project Member

Comment 45 by bugdroid1@chromium.org, Jun 30 2016

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

commit ef9c38f033c0f5b11defe2210d2d00737c41b76e
Author: tkent <tkent@chromium.org>
Date: Thu Jun 30 05:26:52 2016

Improve performance of HTMLSelectElement::m_listItems update.

This CL introduces a fast path to update m_listItems directly instead of throwing
it away and reconstructing it. The fast path supports:
 - Prepend an OPTION to a SELECT element
 - Append an OPTION to a SELECT element
 - Remove an OPTION child from a SELECT element or an OPTGROUP element.

Removing 20,000 OPTIONs: 2,813ms -> 200ms

BUG= 620142 ,  624220 

Review-Url: https://codereview.chromium.org/2110303002
Cr-Commit-Position: refs/heads/master@{#403093}

[modify] https://crrev.com/ef9c38f033c0f5b11defe2210d2d00737c41b76e/third_party/WebKit/Source/core/html/HTMLSelectElement.cpp
[modify] https://crrev.com/ef9c38f033c0f5b11defe2210d2d00737c41b76e/third_party/WebKit/Source/core/html/HTMLSelectElement.h

Labels: TE-Verified-M52 TE-Verified-52.0.2743.60
Tested the issue on windows 7, Linux Ubuntu 14.04 and Mac 10.11.5 using chrome version 52.0.2743.60 with the below steps

1.Opened the URL https://jsfiddle.net/qLt94cvc/ from comment #17
2.Got the popup as done adding!,clicked ok.
3.Observed the time taken approximately 1.7 sec for the done removing! pop up.

Please find the attached screen cast for the same.
Adding TE-Verified label.

Thnaks, 
620142.mp4
2.1 MB View Download
> The culprit change added selectOption() call during removeChid(), and we can't remove selectOption() according to the HTML specification.

Naive question: why can't we just mark selectedIndex as dirty, and lazily compute it the next time it is needed (not just during layout, since that causes  issue 335876 , but also lazily compute it when it is accessed for any reason)? Then 20000 successive calls to removeChild would be fast as long as you don't e.g. read the selectedIndex property in between each call (which is unlikely).
> why can't we just mark selectedIndex as dirty, and lazily compute it the next time it is needed

It's almost equivalent to what we did before crrev.com/383480.  Each of OPTION elements has selection state, and it should work even if an OPTION was removed from a SELECT element.  So, we need to flush the selection state on every OPTION removal.

Project Member

Comment 49 by bugdroid1@chromium.org, Jul 1 2016

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

commit ee4ea0dc58d29004697c7357dc7aadca01f74c03
Author: Kent Tamura <tkent@chromium.org>
Date: Fri Jul 01 05:34:56 2016

Merge "Improve performance to remove an OPTION from a SELECT element." to M52

This CL optimize HTMLSelectElement::resetToDefaultSelection(). We can quit the
loop if a selected OPTION was removed.

Removing 20,000 OPTIONs: 7,595ms -> 6,358ms

BUG= 620142 ,  624220 

Review-Url: https://codereview.chromium.org/2108883003
Cr-Commit-Position: refs/heads/master@{#402709}
(cherry picked from commit 6aa050448c3f5a8e6749e059ec9ec62adb685a70)

Review URL: https://codereview.chromium.org/2113953002 .

Cr-Commit-Position: refs/branch-heads/2743@{#560}
Cr-Branched-From: 2b3ae3b8090361f8af5a611712fc1a5ab2de53cb-refs/heads/master@{#394939}

[modify] https://crrev.com/ee4ea0dc58d29004697c7357dc7aadca01f74c03/third_party/WebKit/Source/core/html/HTMLSelectElement.cpp
[modify] https://crrev.com/ee4ea0dc58d29004697c7357dc7aadca01f74c03/third_party/WebKit/Source/core/html/HTMLSelectElement.h

Using my own synthetic test (see https://bugs.chromium.org/p/chromium/issues/detail?id=623891 ), I just conducted the following series of benchmarks:

Removal of many options, each with a 100-random-character text node attached.

                                  5000 Options         20000 Options
Chrome 50.0.2661.75  (Old):       12 ms                50 ms
Chrome 51.0.2704.106 (Stable):    (several minutes)    (not measured)
Chrome 52.0.2743.60  (Beta):      294 ms               7030 ms
Chrome 53.0.2783.2   (Dev):       290 ms               7229 ms


More detailed measurements for Chrome 52.0.2743.60 (Beta):
#options		time in ms
1000			38
2000			77
3000			140
4000			233
5000			335
6000			411
7000			552
8000			801
9000			973
10000			1331
11000			1747
12000			1871
13000			2578
14000			3463
15000			3825
16000			4519
17000			4691
18000			5946
19000			7261
20000			8488


Judging from these results, complexity is still in O(n^2), even with the patches already merged into Chrome 52 and 53 thus far (see https://bugs.chromium.org/p/chromium/issues/detail?id=624220#c8 ). The actual function might be something like y=0.02*x^2 (as originally indicated here https://bugs.chromium.org/p/chromium/issues/detail?id=623891#c1 ).

Sign in to add a comment