Krinkle has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/52544


Change subject: mw.loader: Prevent excessive re-paints (new style tags)
......................................................................

mw.loader: Prevent excessive re-paints (new style tags)

As brought to our attention by Chromium/WebKit developers at Google,
when we fixed bug 31676 (IE stylesheet limit) by appending to
<style> whenever we can (i.e. whenever the received stylesheet
does not involve @import which only works on top of the a
stylesheet) – this is causing several slowdowns.

Which build up on mobile to several dozen seconds in pages
with a lot of content and many modules being loaded.

Appending a text node to a <style> tag, while it doesn't require
the DOM to do anything fancy (no need to reparse the contents).
The stylesheet handler of the browser has to re-parse the css text
after each modification as the css syntax is too tolerant to be
able to just pick up parsing again (at least, as of writing
neither Gecko or WebKit are able to do so).

As a result, the stylesheet is invalidated, re-parsed and
re-applied to the page.

So instead default the other way around and only re-use a <style>
tag if we have to do so for IE.

Bug: 45810
Change-Id: I52252e699a518dc1c1327ee598a9e023cc2555e2
---
M resources/mediawiki/mediawiki.js
1 file changed, 24 insertions(+), 15 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/core 
refs/changes/44/52544/1

diff --git a/resources/mediawiki/mediawiki.js b/resources/mediawiki/mediawiki.js
index 4dbf04c..1503ba9 100644
--- a/resources/mediawiki/mediawiki.js
+++ b/resources/mediawiki/mediawiki.js
@@ -391,7 +391,9 @@
                                // List of callback functions waiting for 
modules to be ready to be called
                                jobs = [],
                                // Selector cache for the marker element. Use 
getMarker() to get/use the marker!
-                               $marker = null;
+                               $marker = null,
+                               // Buffer for addEmbeddedCSS.
+                               cssBuffer = '';
 
                        /* Private methods */
 
@@ -452,35 +454,42 @@
                        }
 
                        /**
-                        * Checks if certain cssText is safe to append to
-                        * a stylesheet.
+                        * Checks whether we should create a new styleheet or 
append to the
+                        * given style tag in `$style`.
                         *
-                        * Right now it only makes sure that cssText containing 
`@import`
-                        * rules will end up in a new stylesheet (as those only 
work when
-                        * placed at the start of a stylesheet; bug 35562).
-                        * This could later be extended to take care of other 
bugs, such as
-                        * the IE cssRules limit - not the same as the IE 
styleSheets limit).
+                        * TODO: Handle IE cssRules limit (not the same as the 
IE styleSheets limit).
+                        *
                         * @private
                         * @param {jQuery} $style
                         * @param {string} cssText
-                        * @return {boolean}
+                        * @return {boolean} False if a new one should be 
created.
                         */
-                       function canExpandStylesheetWith( $style, cssText ) {
-                               return cssText.indexOf( '@import' ) === -1;
+                       function shouldExpandStylesheetWith( $style, cssText ) {
+                               return (
+                                       // By default, always create a new 
<style>. Appending text
+                                       // to a <style> tag means the contents 
have to be re-parsed (bug 45810).
+                                       // Except, of course, in IE below 9, in 
there we default to
+                                       // re-using and appending to a <style> 
tag due to the
+                                       // IE stylesheet limit (bug 31676).
+                                       ( 'documentMode' in document && 
document.documentMode <= 9 ) &&
+                                       // Makes sure that cssText containing 
`@import`
+                                       // rules will end up in a new 
stylesheet (as those only work when
+                                       // placed at the start of a stylesheet; 
bug 35562).
+                                       cssText.indexOf( '@import' ) === -1
+                               );
                        }
 
                        function addEmbeddedCSS( cssText ) {
                                var $style, styleEl;
+
                                $style = getMarker().prev();
-                               // Re-use `<style>` tags if possible, this to 
try to stay
-                               // under the IE stylesheet limit (bug 31676).
-                               // Also verify that the the element before 
Marker actually is one
+                               // Verify that the the element before Marker 
actually is one
                                // that came from ResourceLoader, and not a 
style tag that some
                                // other script inserted before our marker, or, 
more importantly,
                                // it may not be a style tag at all (could be 
`<meta>` or `<script>`).
                                if (
                                        $style.data( 
'ResourceLoaderDynamicStyleTag' ) === true &&
-                                       canExpandStylesheetWith( $style, 
cssText )
+                                       shouldExpandStylesheetWith( $style, 
cssText )
                                ) {
                                        // There's already a dynamic <style> 
tag present and
                                        // canExpandStylesheetWith() gave a 
green light to append more to it.

-- 
To view, visit https://gerrit.wikimedia.org/r/52544
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I52252e699a518dc1c1327ee598a9e023cc2555e2
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/core
Gerrit-Branch: master
Gerrit-Owner: Krinkle <ttij...@wikimedia.org>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to