yari icon indicating copy to clipboard operation
yari copied to clipboard

CSSRef is slow

Open peterbe opened this issue 3 years ago • 5 comments

Now that the new CSS sidebar has been updated, we still find it to be very slow. There's probably not a single explanation, but rather "death by a thousand papercuts".

As an experiment, I ran...

yarn build:prepare && BUILD_FLAW_LEVELS="*:ignore" BUILD_FOLDERSEARCH=web/css yarn build

a bunch of times and recorded the rate of docs per second. After a couple of runs I concluded it to be about 6 docs/sec. (note: there are 943 docs in web/css)

Then I hackishly and temporarily just commented it out entirely to just return <section id="Quick_links"></section> and nothing else. Now, after a bunch of runs of the same command as above, the rate instead becomes 25 docs/sec.

Because the CSSRef.ejs sidebar does not depend on the slug, we could technically cache its computation once per locale and re-use the HTML it produces.

peterbe avatar Mar 25 '21 19:03 peterbe

Before we jump in to optimize how kumascript is run and executed, I think we should seriously consider taking this opportunity to pivot to the new "related_links" based sidebar solution as described here: https://github.com/mdn/yari/discussions/2895 The code mentioned there was the work of half an afternoon so it needs some love but not a whole lot.

If we can move the CSSRef sidebar into a Node function, we can easily do a couple of things:

  1. Have it so that the HTML is different for every different slug that renders it
  2. Cache the basic structure and then "clone" it so the current page is highlighted

@wbamberg and I discussed that it would be nice to highlight the page you're on. (Both Stripe and GitHub does this) But to do that with the CSSRef.ejs and make it fast would be hard, so we discussed a solution where we add some client-side code that finds the DOM node, at render-time, and adds a class="current" or something.

But I think it would be better to solve this properly once and for all. Both birds with one stone.

peterbe avatar Mar 29 '21 15:03 peterbe

The other thing we could do is to not necessarily jump on the related_links bandwagon and still just make the sidebar produce a blob of HTML. But by moving it out of .ejs and into its own .js file, we could maybe have a working solution sooner.

peterbe avatar Mar 29 '21 15:03 peterbe

@fiji-flo pointed out that perhaps the reason it's so slow is that it's so HUGE. Sure enough, the HTML blob in https://developer.mozilla.org/en-US/docs/Web/CSS/padding/index.json for example is 104KB. Yikes. Considering that 90% of that weight is visually hidden, it feels like a huge burden just to build that much just to not display it.

Also, we discovered that there's a LOT of <svg> in that HTML blob. If you replace every <svg> block with a <img> the total weight goes down to 56KB. That might be quick boost on its own. It probably won't help our build times but it'll probably help users.

peterbe avatar Mar 29 '21 20:03 peterbe

So, maybe caching deep in kumascript doesn't help. The problem might lie elsewhere. Perhaps its sheer size. I copied the rendered out HTML from one of the docs and took its whole HTML blurb and entirely replaced the contents of CSSRef.ejs with that. So no JS function calls now to render the sidebar. It now gave me a rate of 6.3 docs/second.

peterbe avatar Mar 29 '21 21:03 peterbe

After some more measuring and experimentation, I can conclude that the reason isn't because of the KS rendering (only a small amount) but the fact that the CSS sidebars are so huge. The best solution is probably to migrate it to a related_links solution. The best intermediate solution is to try to tackle https://github.com/mdn/yari/issues/3385 so that we don't need to include 100KB of SVG data on every CSS page. (...that isn't even visible until you expand the menu)

peterbe avatar Apr 20 '21 14:04 peterbe