Bug 75508

Summary: Analyze stylesheet scope to minimize style recalcs
Product: WebKit Reporter: Antti Koivisto <koivisto>
Component: CSSAssignee: Nobody <webkit-unassigned>
Status: RESOLVED FIXED    
Severity: Normal CC: dglazkov, hyatt, kling, macpherson, manyoso, mihaip, phiw2, pnormand, rolandsteiner, sam, staikos, tonikitoo, webkit.review.bot
Priority: P2    
Version: 528+ (Nightly build)   
Hardware: Unspecified   
OS: Unspecified   
Attachments:
Description Flags
patch
webkit.review.bot: commit-queue-
Chromium build fix plus some cleanups
none
update to tot hyatt: review+

Antti Koivisto
Reported 2012-01-03 18:22:50 PST
It is a relatively common pattern to use inline stylesheets in document body where all rules are scoped using descendant selector <style> #foo {...} #foo div {...} #foo .bar {...} </style> When this pattern is used it is also common that the rules only apply to elements that come after the style element. When the set of active stylesheets changes we invalidate and recompute the entire document style. This is very expensive. We can detect the case above and avoid the style recalc.
Attachments
patch (28.84 KB, patch)
2012-01-03 18:58 PST, Antti Koivisto
webkit.review.bot: commit-queue-
Chromium build fix plus some cleanups (28.94 KB, patch)
2012-01-04 08:18 PST, Antti Koivisto
no flags
update to tot (28.86 KB, patch)
2012-01-04 09:00 PST, Antti Koivisto
hyatt: review+
Antti Koivisto
Comment 1 2012-01-03 18:58:57 PST
Created attachment 121038 [details] patch On engadget.com, this patch cuts the time spent in style recalcs to roughly half. There are further savings from reduced relayouts. In total the engine CPU time used over the page load is reduced by ~10%.
WebKit Review Bot
Comment 2 2012-01-03 19:40:54 PST
Comment on attachment 121038 [details] patch Attachment 121038 [details] did not pass chromium-ews (chromium-xvfb): Output: http://queues.webkit.org/results/11082256
Antti Koivisto
Comment 3 2012-01-04 08:18:11 PST
Created attachment 121113 [details] Chromium build fix plus some cleanups
Antti Koivisto
Comment 4 2012-01-04 09:00:02 PST
Created attachment 121115 [details] update to tot
Dave Hyatt
Comment 5 2012-01-04 09:28:35 PST
Comment on attachment 121115 [details] update to tot I think RecalcStyleOnlyifNeeded would be better than PendingStylesheetCompleted. r=me
Antti Koivisto
Comment 6 2012-01-04 10:55:26 PST
Antti Koivisto
Comment 7 2012-01-04 12:05:28 PST
Philippe Normand
Comment 8 2012-01-05 07:02:43 PST
(In reply to comment #7) > http://trac.webkit.org/changeset/104060 It seems this patch broke a test in GTK: http://build.webkit.org/results/GTK%20Linux%2064-bit%20Release/r104153%20(15719)/fast/forms/textarea-metrics-diff.txt --- /home/slave/webkitgtk/gtk-linux-64-release/build/layout-test-results/fast/forms/textarea-metrics-expected.txt +++ /home/slave/webkitgtk/gtk-linux-64-release/build/layout-test-results/fast/forms/textarea-metrics-actual.txt @@ -88,84 +88,84 @@ Testing CSS1Compat document. Properties = none -PASS CSS1Compatdoc.getElementById('no-styles').clientWidth is 54 -PASS CSS1Compatdoc.getElementById('no-styles').clientHeight is 54 -PASS CSS1Compatdoc.getElementById('no-styles').offsetWidth is 56 -PASS CSS1Compatdoc.getElementById('no-styles').offsetHeight is 56 -PASS CSS1Compatdoc.getElementById('no-styles').scrollWidth is 54 -PASS CSS1Compatdoc.getElementById('no-styles').scrollHeight is 54 +FAIL CSS1Compatdoc.getElementById('no-styles').clientWidth should be 54. Was 48. +FAIL CSS1Compatdoc.getElementById('no-styles').clientHeight should be 54. Was 48. +FAIL CSS1Compatdoc.getElementById('no-styles').offsetWidth should be 56. Was 50. +FAIL CSS1Compatdoc.getElementById('no-styles').offsetHeight should be 56. Was 50. +FAIL CSS1Compatdoc.getElementById('no-styles').scrollWidth should be 54. Was 48. +FAIL CSS1Compatdoc.getElementById('no-styles').scrollHeight should be 54. Was 48. Properties = disabled: "true", -PASS CSS1Compatdoc.getElementById('-disabled-true-').clientWidth is 54 -PASS CSS1Compatdoc.getElementById('-disabled-true-').clientHeight is 54 -PASS CSS1Compatdoc.getElementById('-disabled-true-').offsetWidth is 56 -PASS CSS1Compatdoc.getElementById('-disabled-true-').offsetHeight is 56 -PASS CSS1Compatdoc.getElementById('-disabled-true-').scrollWidth is 54 -PASS CSS1Compatdoc.getElementById('-disabled-true-').scrollHeight is 54 +FAIL CSS1Compatdoc.getElementById('-disabled-true-').clientWidth should be 54. Was 48. +FAIL CSS1Compatdoc.getElementById('-disabled-true-').clientHeight should be 54. Was 48. +FAIL CSS1Compatdoc.getElementById('-disabled-true-').offsetWidth should be 56. Was 50. +FAIL CSS1Compatdoc.getElementById('-disabled-true-').offsetHeight should be 56. Was 50. +FAIL CSS1Compatdoc.getElementById('-disabled-true-').scrollWidth should be 54. Was 48. +FAIL CSS1Compatdoc.getElementById('-disabled-true-').scrollHeight should be 54. Was 48. Properties = innerHTML: "A", -PASS CSS1Compatdoc.getElementById('-innerHTML-A-').clientWidth is 54 -PASS CSS1Compatdoc.getElementById('-innerHTML-A-').clientHeight is 54 -PASS CSS1Compatdoc.getElementById('-innerHTML-A-').offsetWidth is 56 -PASS CSS1Compatdoc.getElementById('-innerHTML-A-').offsetHeight is 56 -PASS CSS1Compatdoc.getElementById('-innerHTML-A-').scrollWidth is 54 -PASS CSS1Compatdoc.getElementById('-innerHTML-A-').scrollHeight is 54 +FAIL CSS1Compatdoc.getElementById('-innerHTML-A-').clientWidth should be 54. Was 48. +FAIL CSS1Compatdoc.getElementById('-innerHTML-A-').clientHeight should be 54. Was 48. +FAIL CSS1Compatdoc.getElementById('-innerHTML-A-').offsetWidth should be 56. Was 50. +FAIL CSS1Compatdoc.getElementById('-innerHTML-A-').offsetHeight should be 56. Was 50. +FAIL CSS1Compatdoc.getElementById('-innerHTML-A-').scrollWidth should be 54. Was 48. +FAIL CSS1Compatdoc.getElementById('-innerHTML-A-').scrollHeight should be 54. Was 48. Properties = innerHTML: "AAAAAAAAA", -PASS CSS1Compatdoc.getElementById('-innerHTML-AAAAAAAAA-').clientWidth is 37 -PASS CSS1Compatdoc.getElementById('-innerHTML-AAAAAAAAA-').clientHeight is 54 -PASS CSS1Compatdoc.getElementById('-innerHTML-AAAAAAAAA-').offsetWidth is 56 -PASS CSS1Compatdoc.getElementById('-innerHTML-AAAAAAAAA-').offsetHeight is 56 -PASS CSS1Compatdoc.getElementById('-innerHTML-AAAAAAAAA-').scrollWidth is 37 -FAIL CSS1Compatdoc.getElementById('-innerHTML-AAAAAAAAA-').scrollHeight should be 64. Was 104. +FAIL CSS1Compatdoc.getElementById('-innerHTML-AAAAAAAAA-').clientWidth should be 37. Was 31. +FAIL CSS1Compatdoc.getElementById('-innerHTML-AAAAAAAAA-').clientHeight should be 54. Was 48. +FAIL CSS1Compatdoc.getElementById('-innerHTML-AAAAAAAAA-').offsetWidth should be 56. Was 50. +FAIL CSS1Compatdoc.getElementById('-innerHTML-AAAAAAAAA-').offsetHeight should be 56. Was 50. +FAIL CSS1Compatdoc.getElementById('-innerHTML-AAAAAAAAA-').scrollWidth should be 37. Was 31. +FAIL CSS1Compatdoc.getElementById('-innerHTML-AAAAAAAAA-').scrollHeight should be 64. Was 184. Properties = innerHTML: "A", disabled: "true", -PASS CSS1Compatdoc.getElementById('-innerHTML-A-disabled-true-').clientWidth is 54 -PASS CSS1Compatdoc.getElementById('-innerHTML-A-disabled-true-').clientHeight is 54 -PASS CSS1Compatdoc.getElementById('-innerHTML-A-disabled-true-').offsetWidth is 56 -PASS CSS1Compatdoc.getElementById('-innerHTML-A-disabled-true-').offsetHeight is 56 -PASS CSS1Compatdoc.getElementById('-innerHTML-A-disabled-true-').scrollWidth is 54 -PASS CSS1Compatdoc.getElementById('-innerHTML-A-disabled-true-').scrollHeight is 54 +FAIL CSS1Compatdoc.getElementById('-innerHTML-A-disabled-true-').clientWidth should be 54. Was 48. +FAIL CSS1Compatdoc.getElementById('-innerHTML-A-disabled-true-').clientHeight should be 54. Was 48. +FAIL CSS1Compatdoc.getElementById('-innerHTML-A-disabled-true-').offsetWidth should be 56. Was 50. +FAIL CSS1Compatdoc.getElementById('-innerHTML-A-disabled-true-').offsetHeight should be 56. Was 50. +FAIL CSS1Compatdoc.getElementById('-innerHTML-A-disabled-true-').scrollWidth should be 54. Was 48. +FAIL CSS1Compatdoc.getElementById('-innerHTML-A-disabled-true-').scrollHeight should be 54. Was 48. Properties = innerHTML: "AAAAAAAAA", disabled: "true", -PASS CSS1Compatdoc.getElementById('-innerHTML-AAAAAAAAA-disabled-true-').clientWidth is 37 -PASS CSS1Compatdoc.getElementById('-innerHTML-AAAAAAAAA-disabled-true-').clientHeight is 54 -PASS CSS1Compatdoc.getElementById('-innerHTML-AAAAAAAAA-disabled-true-').offsetWidth is 56 -PASS CSS1Compatdoc.getElementById('-innerHTML-AAAAAAAAA-disabled-true-').offsetHeight is 56 -PASS CSS1Compatdoc.getElementById('-innerHTML-AAAAAAAAA-disabled-true-').scrollWidth is 37 -FAIL CSS1Compatdoc.getElementById('-innerHTML-AAAAAAAAA-disabled-true-').scrollHeight should be 64. Was 104. +FAIL CSS1Compatdoc.getElementById('-innerHTML-AAAAAAAAA-disabled-true-').clientWidth should be 37. Was 31. +FAIL CSS1Compatdoc.getElementById('-innerHTML-AAAAAAAAA-disabled-true-').clientHeight should be 54. Was 48. +FAIL CSS1Compatdoc.getElementById('-innerHTML-AAAAAAAAA-disabled-true-').offsetWidth should be 56. Was 50. +FAIL CSS1Compatdoc.getElementById('-innerHTML-AAAAAAAAA-disabled-true-').offsetHeight should be 56. Was 50. +FAIL CSS1Compatdoc.getElementById('-innerHTML-AAAAAAAAA-disabled-true-').scrollWidth should be 37. Was 31. +FAIL CSS1Compatdoc.getElementById('-innerHTML-AAAAAAAAA-disabled-true-').scrollHeight should be 64. Was 184. Properties = innerHTML: "A", style: "padding:8px", -PASS CSS1Compatdoc.getElementById('-innerHTML-A-style-padding-8px-').clientWidth is 66 -PASS CSS1Compatdoc.getElementById('-innerHTML-A-style-padding-8px-').clientHeight is 66 -PASS CSS1Compatdoc.getElementById('-innerHTML-A-style-padding-8px-').offsetWidth is 68 -PASS CSS1Compatdoc.getElementById('-innerHTML-A-style-padding-8px-').offsetHeight is 68 -PASS CSS1Compatdoc.getElementById('-innerHTML-A-style-padding-8px-').scrollWidth is 66 -PASS CSS1Compatdoc.getElementById('-innerHTML-A-style-padding-8px-').scrollHeight is 66 +FAIL CSS1Compatdoc.getElementById('-innerHTML-A-style-padding-8px-').clientWidth should be 66. Was 48. +FAIL CSS1Compatdoc.getElementById('-innerHTML-A-style-padding-8px-').clientHeight should be 66. Was 48. +FAIL CSS1Compatdoc.getElementById('-innerHTML-A-style-padding-8px-').offsetWidth should be 68. Was 50. +FAIL CSS1Compatdoc.getElementById('-innerHTML-A-style-padding-8px-').offsetHeight should be 68. Was 50. +FAIL CSS1Compatdoc.getElementById('-innerHTML-A-style-padding-8px-').scrollWidth should be 66. Was 48. +FAIL CSS1Compatdoc.getElementById('-innerHTML-A-style-padding-8px-').scrollHeight should be 66. Was 48. Properties = innerHTML: "AAAAAAAAA", style: "padding:8px", -PASS CSS1Compatdoc.getElementById('-innerHTML-AAAAAAAAA-style-padding-8px-').clientWidth is 49 -PASS CSS1Compatdoc.getElementById('-innerHTML-AAAAAAAAA-style-padding-8px-').clientHeight is 66 -PASS CSS1Compatdoc.getElementById('-innerHTML-AAAAAAAAA-style-padding-8px-').offsetWidth is 68 -PASS CSS1Compatdoc.getElementById('-innerHTML-AAAAAAAAA-style-padding-8px-').offsetHeight is 68 -PASS CSS1Compatdoc.getElementById('-innerHTML-AAAAAAAAA-style-padding-8px-').scrollWidth is 49 -FAIL CSS1Compatdoc.getElementById('-innerHTML-AAAAAAAAA-style-padding-8px-').scrollHeight should be 76. Was 116. +FAIL CSS1Compatdoc.getElementById('-innerHTML-AAAAAAAAA-style-padding-8px-').clientWidth should be 49. Was 31. +FAIL CSS1Compatdoc.getElementById('-innerHTML-AAAAAAAAA-style-padding-8px-').clientHeight should be 66. Was 48. +FAIL CSS1Compatdoc.getElementById('-innerHTML-AAAAAAAAA-style-padding-8px-').offsetWidth should be 68. Was 50. +FAIL CSS1Compatdoc.getElementById('-innerHTML-AAAAAAAAA-style-padding-8px-').offsetHeight should be 68. Was 50. +FAIL CSS1Compatdoc.getElementById('-innerHTML-AAAAAAAAA-style-padding-8px-').scrollWidth should be 49. Was 31. +FAIL CSS1Compatdoc.getElementById('-innerHTML-AAAAAAAAA-style-padding-8px-').scrollHeight should be 76. Was 196. Properties = innerHTML: "A", rows: "10", -PASS CSS1Compatdoc.getElementById('-innerHTML-A-rows-10-').clientWidth is 54 -PASS CSS1Compatdoc.getElementById('-innerHTML-A-rows-10-').clientHeight is 54 -PASS CSS1Compatdoc.getElementById('-innerHTML-A-rows-10-').offsetWidth is 56 -PASS CSS1Compatdoc.getElementById('-innerHTML-A-rows-10-').offsetHeight is 56 -PASS CSS1Compatdoc.getElementById('-innerHTML-A-rows-10-').scrollWidth is 54 -PASS CSS1Compatdoc.getElementById('-innerHTML-A-rows-10-').scrollHeight is 54 +FAIL CSS1Compatdoc.getElementById('-innerHTML-A-rows-10-').clientWidth should be 54. Was 48. +FAIL CSS1Compatdoc.getElementById('-innerHTML-A-rows-10-').clientHeight should be 54. Was 48. +FAIL CSS1Compatdoc.getElementById('-innerHTML-A-rows-10-').offsetWidth should be 56. Was 50. +FAIL CSS1Compatdoc.getElementById('-innerHTML-A-rows-10-').offsetHeight should be 56. Was 50. +FAIL CSS1Compatdoc.getElementById('-innerHTML-A-rows-10-').scrollWidth should be 54. Was 48. +FAIL CSS1Compatdoc.getElementById('-innerHTML-A-rows-10-').scrollHeight should be 54. Was 48. Properties = innerHTML: "AAAAAAAAA", rows: "10", -PASS CSS1Compatdoc.getElementById('-innerHTML-AAAAAAAAA-rows-10-').clientWidth is 37 -PASS CSS1Compatdoc.getElementById('-innerHTML-AAAAAAAAA-rows-10-').clientHeight is 54 -PASS CSS1Compatdoc.getElementById('-innerHTML-AAAAAAAAA-rows-10-').offsetWidth is 56 -PASS CSS1Compatdoc.getElementById('-innerHTML-AAAAAAAAA-rows-10-').offsetHeight is 56 -PASS CSS1Compatdoc.getElementById('-innerHTML-AAAAAAAAA-rows-10-').scrollWidth is 37 -FAIL CSS1Compatdoc.getElementById('-innerHTML-AAAAAAAAA-rows-10-').scrollHeight should be 64. Was 104. +FAIL CSS1Compatdoc.getElementById('-innerHTML-AAAAAAAAA-rows-10-').clientWidth should be 37. Was 31. +FAIL CSS1Compatdoc.getElementById('-innerHTML-AAAAAAAAA-rows-10-').clientHeight should be 54. Was 48. +FAIL CSS1Compatdoc.getElementById('-innerHTML-AAAAAAAAA-rows-10-').offsetWidth should be 56. Was 50. +FAIL CSS1Compatdoc.getElementById('-innerHTML-AAAAAAAAA-rows-10-').offsetHeight should be 56. Was 50. +FAIL CSS1Compatdoc.getElementById('-innerHTML-AAAAAAAAA-rows-10-').scrollWidth should be 37. Was 31. +FAIL CSS1Compatdoc.getElementById('-innerHTML-AAAAAAAAA-rows-10-').scrollHeight should be 64. Was 184. PASS successfullyParsed is true
Antti Koivisto
Comment 9 2012-01-05 12:40:37 PST
Filed bug 75644: REGRESSION (r104060): fast/forms/textarea-metrics.html. Philippe, next time please file a new bug instead of pasting stuff to the bug you think is causing the regression.
Philippe Wittenbergh
Comment 10 2012-01-06 23:30:38 PST
Did this cause bug 75772 ?
Mihai Parparita
Comment 11 2012-01-18 14:49:08 PST
FWIW, this causes http://crbug.com/109888. I'll see if I can create a reduced test case, and file a separate bug.
Mihai Parparita
Comment 12 2012-01-19 07:26:37 PST
(In reply to comment #11) > FWIW, this causes http://crbug.com/109888. I'll see if I can create a reduced test case, and file a separate bug. I filed https://bugs.webkit.org/show_bug.cgi?id=76590
Note You need to log in before you can comment on or make changes to this bug.