= Background
Back in Sept 2015, render blocking CSS for mobile was only 6.4kb for an anonymous user (T97289) with JS disabled.
Since then it's been steadily increasing and it's now 9.3kb.
Render blocking CSS is problematic as it **blocks rendering** meaning that it slows down the time a user **sees content**.
According to real world data [[ https://grafana.wikimedia.org/dashboard/db/mobile-2g?panelId=72&fullscreen&orgId=1 | it currently our 95th percentile of users still wait up to 5-7s ]] to read Wikipedia on mobile devices. The median is just over 1s, so good but not awesome. On a 3G connection the [[ https://grafana-admin.wikimedia.org/dashboard/db/mobile-2g?orgId=1 | Barack Obama article takes around 2s to render ]].
Using uncss and spending time investigating our CSS I found that much of this CSS is unnecessary.
= Problem statement
* Our CSS is messy. This is natural for a 6 year old repository. It could do with some cleanup. There are many outdated and unused CSS rules. This makes maintenance more difficult.
* Removing render blocking CSS seems to have an impact on real world performance (but not webpagetest see T193570)
* At least 2.6kb of our render blocking CSS is redudant
= Phase 1 - cleanup
I recommend the following changes:
[] **Remove usage of data URIs in render blocking styles**
Estimated savings: 1.6kb
https://gerrit.wikimedia.org/r/444143
[] **Do not load mediawiki.ui.button on startup**
Estimated savings: 0.6kb
https://gerrit.wikimedia.org/r/#/c/mediawiki/skins/MinervaNeue/+/444276
[] **Do not ship 2 versions of the same icon**
Estimated savings: 0.2kb
https://gerrit.wikimedia.org/r/444141
[] **Do not send JavaScript-only styles as render blocking**
Estimated savings: 0.2kb
Various classes are not used if JS is never loaded - .truncated-text,.cloaked-element,.position-fixed, lazy loading related css, last modified active color, overlay header styles
https://gerrit.wikimedia.org/r/444141
https://gerrit.wikimedia.org/r/444134
https://gerrit.wikimedia.org/r/444137
https://gerrit.wikimedia.org/r/444135
https://gerrit.wikimedia.org/r/444138
= Phase 2 - prevention
[] Establish a baseline and block merges that impact it - We'll want to prevent the CSS bloating again by measuring the amount of render blocking CSS we serve to anonymous users on each commit. We have something similar in the Page previews codebase for JavaScript.
[] In code review sessions we'll want to talk about the way we write CSS going forward and how we can keep bloat down. webpack may help with this (T160128)
[] Comments would be added to the CSS files and style entry points giving guidelines to developers to prevent good word being undone. It would make clear when something is going to be added to critical CSS and when it is not.
= Phase 3 - Inlining css
Although such optimisations in 1&2 are unlikely to make much of a change to the start render time (a casual glance at webpagetest showed no improvement to first paint for a slow 3G connection), it does go a long way to improving how our CSS is architected and sets us up for loading CSS as an inline style in future.
The leaner the CSS is, the more compelling it would be to inline the CSS in the head of the document per [[ https://developers.google.com/speed/docs/insights/PrioritizeVisibleContent#RemoveUnusedCSS | this recommendation ]]. This would remove the need for an additional HTTP request for CSS and would [[ https://www.smashingmagazine.com/2015/08/understanding-critical-css/ | give us the fastest first paint possible ]].