Page MenuHomePhabricator

performance optimize timeless
Open, Needs TriagePublic

Description

Timeless has started to become stable, I think its time to do some performance optimization. I guess this could be a tracking bug once different performance metrics/issues are identified.

At T217883 its claimed

As it stands, the CSS included in Timeless exceeds that of Vector by 5kb.

In my test, I got closer to 4, but its clear that the css foot print is slightly larger in Timeless then in vector. This may be related to having more images embedded in the CSS which probably don't gzip well.

More to the point, in initial tests, (uncached) Timeless seems to be behind Vector by about 0.1 seconds both on cable internet and 3g ( cable: vector, timeless. 3g: vector timeless. 2g vector, timeless).).

On the backend side, In very initial profiling (very low sample size of 1), Timeless seems to be about 0.1 seconds slower than Vector, and 0.3 seconds faster than monobook. (Link to profile: timeless, vector, monobook)

Anyways, that's very initial. We should do more profiling and stuff.

Event Timeline

Bawolff created this task.Mar 28 2019, 5:53 PM
ashley assigned this task to Isarra.Mar 28 2019, 6:13 PM
ashley added subscribers: Isarra, ashley.

Per our IRC discussion, assigning to @Isarra so she can work on this during the next week.

Bawolff updated the task description. (Show Details)Mar 28 2019, 11:23 PM
Bawolff updated the task description. (Show Details)Mar 28 2019, 11:38 PM
Bawolff updated the task description. (Show Details)Mar 30 2019, 9:15 PM
Bawolff added a comment.EditedMar 31 2019, 6:12 AM

So I think we should do some research into how much different CSS footprints affect performance before actually doing anything, but some initial thoughts on CSS in timeless:

  • We may be able to get a small amount of savings by running all the svgs through svgo (I expect ~7% or 3kb pre-compression space savings for that. So probably not very much post compression). The cost here is it makes svgs a little less readable for manual editing. [edit in my test that saved only 80 bytes post compression]
  • We could change some of the larger embedded SVGs to use http links instead of data:. This of course means that they have to be fetched in a separate request, which presumably also has overhead and some performance consequences. However, I'm not clear on what these costs are. In our brave new HTTP/2 world I would expect the costs to be quite a bit less as this is basically the problem that HTTP/2 is designed to solve. This also means (I think) that loading that image is off the critical render path (so its not blocking page rendering anymore), so the image may show up to user after the main load of the page, so the user might not immediately see it. Note, that cat-grey.svg is already loaded in this fashion as its > 32kb. If this is indeed worth it (which I'm not sure), the top candidates are languages-grey.svg, gear-large-grey.svg, gear-grey.svg [edit I did some testing. This would indeed reduce first paint time a little bit on slow connections. However the extra RTT to fetch the svgs means they take a lot longer to show up. Which makes the page seem much slower as they are mostly above the fold. I don't think this would improve perception of performance, and should be avoided except maybe for icons that are below the fold]
  • I was looking at differences between timeless and vector. One of the major sources of increased css size in Timeless relative to the importance of the feature it implements is mediawiki.skinning.content.externallinks. Probably that could be improved by grouping repeated styles in the same block. If size of CSS on critical render path is truly a concern, that entire file could probably be reduces to about 100 bytes that just sets padding-right to 13px on external-links, and a second part that does everything else (which shouldn't affect any layout as it just adds an image) as an asynchronously loaded CSS file. However, given that support for loading (non-js) async CSS was removed in MW on the basis of it not being worth it (9435cd81b07f), not sure where it leaves doing that in terms of being a good idea.
  • I suppose some of the stuff in forms.less could be a skinStyle appended to mediawiki.special or some other more specific module that's not loaded on every page. Not sure if that's worth it.
  • Currently we combine all media queries and output them as @ blocks. If we were truly concerned about the size of CSS on the critical render path, I would assume we would use separate <link> tags for the different media queries with a media attribute. According to https://developers.google.com/web/fundamentals/performance/critical-rendering-path/render-blocking-css media queries that don't match the current device are still downloaded, but are considered non-blocking. I would (perhaps naively) assume that the benefits of combining the CSS into one file is much reduced in the world of HTTP/2. [This is of course not a skin thing but a RL thing]

So reading a bit about client side performance [This is not my area of expertise] - the best thing (all other things being equal) to do is transfer less bytes. But that's easier said then done.

Beyond that it seems like there are two philosophies

  • progressive enhancement - where people think its better to show the most important content first and fill in the other details as they are available. The idea being people can use the site for its primary purpose well the less important details are being filled in.
  • Top-down approach (not sure if that's its real name) - The idea that users find it confusing and disconcerting when the page changes on them (The extreme case of a re-layout fits here, but more generally its confusing and distracting when ui-elements load late even if they don't cause a re-layout). Best to start at the top of the page and render from the top going down so that basically once something is rendered on screen its stable, at least for the content above the fold. (this & this are interesting reads)

I think Isarra likes the later school of thought.

So currently Timeless embeds the data: uri's for interface elements into the CSS. This minimizes extra RTT to go fetch them after the css is loaded, and also ensures they load fairly early, at the cost of the initial CSS (which blocks the first render of the page) taking a little bit longer. However, currently timeless puts much of the DOM for its interface elements at the bottom of the page. For a long [uncached] page on slow internet, (e.g. [[w:Sweeden]]) this means the CSS finishes loading way before the bottom of the DOM loads. So these icons still take a long time to load eventhough they are directly embedded in the blocking css file. So the benefit of embedding them is kind of negated on long pages. I think we should experiment with including various portlets (perhaps not interlanguage though as that's large) earlier in the DOM, so that all the above the fold content renders faster on long pages. (With the trade-off being that the primary content could potentially render a little slower).


Metrics: Reading about various metrics there's a bunch of them, and there's trade-offs between optimizing for different metrics. If we're going more for the the top-down philosophy, I think the best metric to initially concentrate on is Web Page Test's "speed index" (possibly followed by DomInteractive). This very roughly measures how long the initial view of the page (before scrolling or other interaction) take to fully render. I think it makes sense to first concentrate on slow internet (say 2g) as fast people have fast internet and care less. We should probably also measure for different widths as the different responsive layouts could affect things. Page length also changes things a lot. Last of all, I think its important to also measure both for (client-side) cached and uncached hits. At least right now, most hits to Timeless will probably be cached since its people who selected in preference, so repeat viewers is very common.

So I guess I'm suggesting we start keeping track of the following metrics, and try to improve them:

  • speed-index, 2g (280kbps down, 256 kbps up, 800ms RTT), uncached, Long (sweeden length) page
  • speed-index, 2g, cached, sweeden
  • speed-index, 2g, uncached, Special:BlankPage (or maybe some short real page)
  • speed-index, 2g, cached, Special:BlankPage

(And then all of these repeated for the 3 different widths).

That's a lot of metrics already (And Ideally we should probably add some sort of moderately speed internet to the mix), so we definitely would need to have some sort of automated collection system.

Isarra added a comment.EditedApr 2 2019, 3:45 PM

I don't think worrying about this here at this point is going to be worth the effort. Skins such as timeless/monobook/vector may vary slightly, but I suspect their impact is going to be negligible compared to others like Minerva and many third-party skins, or especially a lot of the features common to all of them including the new recent changes stuff or ooui in general.

Could we get some comparisons of these kinds of things, just so we have some actual context?

So it looks like the main problems for performance are going to be:

  • Frontend: we don't actually know because we don't currently have anything set up to track this (?)
  • Backend: the message handling and especially parsing for stuff like the sidebar. While this is going to apply for all skins that support a customisable interface, it may be something worth looking at more closely when overhauling skinning in general? (T217158)

Action items here:

  • Make dom more consistent with order of appearance of items on page (check html structure; reconsider embedding of interface icons and such)
  • The cat?