Page MenuHomePhabricator

Optimize how we load OOUI in MediaWiki
Open, NormalPublic

Description

This is to investigate optimizing how we load OOUI in MediaWiki. I have some thoughts I have written down on another machine, that all seemed fairly easy to implement. They don't seem like large gains, but may be worth it.

  • CSS minifier:
    • Remove whitespace around CSS selectors: a + b, a > b, etc.; f.e. #p-logo + div.portal h3
    • Remove whitespace inside parentheses: ( foo ); f.e. :lang( ml )
    • Remove " from url() values and attribute selectors: url( "img.src" ), [type="radio"]
    • Remove leading 0 from fractional CSS values: 0.8em
    • Ensure hex colors are output in shorthand notation: #fff (LESS compiler sets them back to 6-digit notation in contrast to f.e. Sass)

Related T178867: Unify and optimize SVG markup across Foundation products

  • ResourceLoader:
    • Do something magical to avoid double-loading 'oojs-ui.styles' and friends due to T87871.

Event Timeline

matmarex claimed this task.
matmarex raised the priority of this task from to Normal.
matmarex updated the task description. (Show Details)
matmarex added subscribers: matmarex, ori.
Restricted Application added a subscriber: Aklapper. · View Herald TranscriptJan 30 2016, 10:03 AM

CSS minifier:

  • Remove whitespace around CSS selectors: a + b, a > b, etc.
  • Remove whitespace inside parentheses: ( foo )
  • Remove leading '0.' from CSS values

Icons and stuff:

  • Remove domain from URLs like //xx.wikipedia.org/w/load.php?...
  • Remove whitespace and ids from embedded SVG files

ResourceLoader:

  • Do something magical to avoid double-loading 'oojs-ui.styles' and friends due to T87871.

Adding to possible (micro) optimizations by CSS minifier:

  • Ensure hex colors are output in shorthand notation: #fff (Less compiler sets them back to 6-digit notation in contrast to f.e. Sass)

Another tiny gain would be to resolve T110051, which would shave off a few bytes for each icon.

Change 267794 had a related patch set uploaded (by Bartosz Dziewoński):
Work around T87871 to avoid double-loading OOjs UI PHP styles

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

Change 267794 merged by jenkins-bot:
Work around T87871 to avoid double-loading OOjs UI PHP styles

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

Jdforrester-WMF edited projects, added OOUI; removed Patch-For-Review.
Jdforrester-WMF set Security to None.
matmarex added a comment.EditedFeb 11 2016, 10:16 PM

I wrote a quick one-off Ruby script to try to see how much applying these optimizations would help. It just does some regex replacements with utter disregard for CSS syntax. I eyeballed the diff, but didn't actually test if the "optimized" styles still work the same.


For the OOjs UI style modules: https://en.wikipedia.org/w/load.php?modules=oojs-ui.styles%7Coojs-ui.styles.icons%7Coojs-ui.styles.indicators%7Coojs-ui.styles.textures&only=styles

BytesBytes when gzipped
Currently14350715338
With additional optimizations13189214756

And for comparison, for other stuff – this URL is based on the modules that were loaded on a random en.wikipedia page I looked at: https://en.wikipedia.org/w/load.php?modules=ext.cite.styles%7Cext.gadget.DRN-wizard%2CReferenceTooltips%2CWatchlistBase%2CWatchlistGreenIndicators%2Ccharinsert%2Cfeatured-articles-links%2CrefToolbar%2Cswitcher%2Cteahouse%7Cext.tmh.thumbnail.styles%7Cext.uls.nojs%7Cext.visualEditor.desktopArticleTarget.noscript%7Cext.wikimediaBadges%7Cmediawiki.legacy.commonPrint%2Cshared%7Cmediawiki.raggett%2CsectionAnchor%7Cmediawiki.skinning.interface%7Cskins.vector.styles%7Cwikibase.client.init&only=styles

BytesBytes when gzipped
Currently5954912262
With additional optimizations5758612095

So I guess we can trim off around 0.5 K from the weight of the base OOjs UI styles. (Most of this seems to be from the embedded SVG optimization.) I'm not sure if it's worth the time it would take to implement the optimizations in a way that is less likely to break things when given arbitrary input.

[edited with corrected numbers and script because I forgot that newlines are whitespace]

matmarex removed matmarex as the assignee of this task.Feb 11 2016, 10:31 PM
Volker_E updated the task description. (Show Details)Apr 1 2016, 10:59 PM

Added: Remove " from url() values and attribute selectors: url( "img.src" ), [type="radio"]

Change 281055 had a related patch set uploaded (by Krinkle):
resourceloader: Remove wfExpandUrl() from ResourceLoaderImage

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

Volker_E added a comment.EditedApr 2 2016, 12:10 AM

CSS property order would be another option. It brings, apart from better readability and code clarity, file size advantages in gzipping. Although the differences are close to zero:
themes/mediawiki/widgets.less compiled oojs-ui-widgets-mediawiki.css

BytesBytes when gzipped
Currently279823858
With unified CSS property order279823855
With unified CSS property order and 1 selector unified*279883850
  • Replaced 1 occurrence of background with background-color (as anywhere else), which was always the beginning property of the selectors.
matmarex updated the task description. (Show Details)

Change 281055 merged by jenkins-bot:
resourceloader: Remove wfExpandUrl() from ResourceLoaderImage

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

And more CSS jungle camp survival games:
I've made a few manual comparison test to see what a few of my ideas could save us, without starting long refactoring yet. As foundation for my test I've been using compiled oojs-ui-mediawiki.css out of master at this point in time (grunt quick-build SVG-&LTR- only), starting at 110.731 bytes on disk:

  • Simplifying nesting (architectural, and Less induced), caring about simplification of selectors like:

.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {} or
.oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-info > .oo-ui-selectFileWidget-label > .oo-ui-selectFileWidget-fileType {}
A very safe, foreseeably non-breaking approach resulted in

BytesBytes when gzipped
Currently11073111298
Simplified selectors107148
  • We're facing very verbose CSS class names in OOjs UI, could we do this less verbose before building the tower higher (some of those might not be possible at all any more; still out of curiosity, don't take some of those too seriously!):
BytesBytes when gzipped
Currently11073111298
Simplified selectors107148
all above & replaced oo-ui by ooui104982
all above & replaced Element by El100870
all above & replaced ooui-widget-enabled by ooui-is-on && ooui-widget-disabled by ooui-is-off99070
all above & replaced El- by BEM notation* as in __ for child elements9837911070

button is used 385 times, icon 229 times, label 205 times, I couldn't resist to replace button with btn which resulted in 97224 bytes. That's 87.82% of the original file size.

But after gzipping it doesn't gain us a lot, more like just a little – probably not worth any trouble if we're not taking into account easier readability for developers. ;)
Comparing from above
.ooui-btn--frameless.ooui-is-on.ooui-flagged--constructive.ooui-is-on.ooui-btn--pressed > .ooui-btn__btn > .ooui-label__label {}


(*) So .ooui-iconEl-icon becomes .ooui-icon__icon or .ooui-buttonEl-button becomes .ooui-button__button and
ooui-buttonEl-pressed becomes ooui-button--pressed for a modifier state of button.

Volker_E renamed this task from Optimize how we load OOjs UI in MediaWiki to Optimize how we load OOUI in MediaWiki.Jan 10 2018, 1:11 AM
Volker_E updated the task description. (Show Details)
Volker_E moved this task from Backlog to Next-up on the OOUI board.Feb 2 2018, 2:47 AM
Volker_E updated the task description. (Show Details)Feb 5 2018, 10:52 PM
Volker_E updated the task description. (Show Details)
Volker_E updated the task description. (Show Details)Feb 5 2018, 11:02 PM
Volker_E updated the task description. (Show Details)