From: Timo Tijhof Date: Wed, 4 Oct 2017 20:30:24 +0000 (+0100) Subject: mediawiki.notification: Move offset() computation to next frame X-Git-Tag: 1.31.0-rc.0~1872^2 X-Git-Url: http://git.cyclocoop.org/%7B%24admin_url%7Dmembres/modifier.php?a=commitdiff_plain;h=f2e8cd6dbdfc4c2004c5ff5f2d20b6d484589c30;p=lhc%2Fweb%2Fwiklou.git mediawiki.notification: Move offset() computation to next frame Crrently on all page views in WMF production, the $.ready handler is inserting the notif $area and subsequently doing a forced style calculation due to getBoundingClientRect() from offset(). Move this to an animation frame instead and re-order the statements so that DOM reads go before DOM writes. Change-Id: I7c6201dc8d4e3227e01b75e853b6e4dc9a734031 --- diff --git a/resources/src/mediawiki/mediawiki.notification.js b/resources/src/mediawiki/mediawiki.notification.js index d5289bd9d7..20f8b8d31c 100644 --- a/resources/src/mediawiki/mediawiki.notification.js +++ b/resources/src/mediawiki/mediawiki.notification.js @@ -280,6 +280,7 @@ .toggleClass( 'mw-notification-area-layout', !isFloating ); } + // Write to the DOM: // Prepend the notification area to the content area and save its object. $area = $( '
' ) // Pause auto-hide timers when the mouse is in the notification area. @@ -301,20 +302,29 @@ } ); mw.util.$content.prepend( $area ); - offset = $area.offset(); - $area.css( 'display', 'none' ); - $( window ).on( 'scroll', updateAreaMode ); + // Read from the DOM: + // Must be in the next frame to avoid synchronous layout + // computation from offset()/getBoundingClientRect(). + rAF( function () { + offset = $area.offset(); - // Initial mode - updateAreaMode(); + // Initial mode (reads, and then maybe writes) + updateAreaMode(); - // Handle pre-ready queue. - isPageReady = true; - while ( preReadyNotifQueue.length ) { - notif = preReadyNotifQueue.shift(); - notif.start(); - } + // Once we have the offset for where it would normally render, set the + // initial state of the (currently empty) notification area to be hidden. + $area.css( 'display', 'none' ); + + $( window ).on( 'scroll', updateAreaMode ); + + // Handle pre-ready queue. + isPageReady = true; + while ( preReadyNotifQueue.length ) { + notif = preReadyNotifQueue.shift(); + notif.start(); + } + } ); } /**