From: Timo Tijhof Date: Tue, 29 Nov 2016 21:48:15 +0000 (-0800) Subject: mediawiki.notification: Improve scroll performance X-Git-Tag: 1.31.0-rc.0~4686^2 X-Git-Url: http://git.cyclocoop.org/%22%20.%20generer_url_ecrire%28%22config_fonctions%22%2C%20%22image_process=%24process%22%29%20.%20%22?a=commitdiff_plain;h=f1ac8022d503a904dc66685e9b979814730ef3bc;p=lhc%2Fweb%2Fwiklou.git mediawiki.notification: Improve scroll performance This fixes the problem with random scroll lag when on a page that had 1 or more notifications at some point. The scroll handler was fairly expensive and kept being called on every scroll event. The actual frame where a frame is detected does take more than 16ms to paint but that's unavoidable. It only happens for 1 or 2 frames, which is perfectly within the response guidelines for RAIL. https://developers.google.com/web/fundamentals/performance/rail (MacBook Pro, Latest Chrome, CPU throttle 5x) 1. Before * Duration of no-change scroll event (not crossing offset.top in ither direction) ~5ms * Duration of changed scroll event (crossing the offset.top and swapping classes) ~10ms * Paint: - 16ms for no-change frames (50-60fps) - 40ms for frames that paint a change. (25-30fps) 2. After storing isFloating as boolean and not checking className if nothing changed. * no-change scroll event: ~0.13ms * changed scroll event: ~2ms * Paint: - 15ms for no-change frame (60fps) - 33ms for no-change frame (30fps) 3. After changing $window.scrollTop() to window.pageYOffset. * no-change scroll event: 15μs (0.015ms) * changed scroll event: ~1ms * Paint: - 11ms for no-change frame (60fps) - 20ms for no-change frame (48fps) Change-Id: Ia48b00cd0834700ce79e72d4599c51ff8c6179b5 --- diff --git a/resources/src/mediawiki/mediawiki.notification.js b/resources/src/mediawiki/mediawiki.notification.js index 926f8c5048..e1287dbc56 100644 --- a/resources/src/mediawiki/mediawiki.notification.js +++ b/resources/src/mediawiki/mediawiki.notification.js @@ -262,7 +262,8 @@ * @ignore */ function init() { - var offset, $window = $( window ); + var offset, + isFloating = false; $area = $( '
' ) // Pause auto-hide timers when the mouse is in the notification area. @@ -289,13 +290,17 @@ $area.hide(); function updateAreaMode() { - var isFloating = $window.scrollTop() > offset.top; + var shouldFloat = window.pageYOffset > offset.top; + if ( isFloating === shouldFloat ) { + return; + } + isFloating = shouldFloat; $area .toggleClass( 'mw-notification-area-floating', isFloating ) .toggleClass( 'mw-notification-area-layout', !isFloating ); } - $window.on( 'scroll', updateAreaMode ); + $( window ).on( 'scroll', updateAreaMode ); // Initial mode updateAreaMode();