1

I want to implement critical-css for React SSR. There are many ways to achieve this but I'm interested particularly in this approach - I plan collect it on the fly after react renders the html. I have css on server and I want to inline only required css from it and load the rest asynchronously (I am not sure about performance but I saw production solution doing this with tools like purifyCSS, so I plan to give it a try and measure its performance)

Problem #1 - Critical CSS extraction

My SSR setup is based on renderToNodeStream not renderToString so I cant compare html with css so easily - chunk might be just a piece of invalid html without closing tags. How do I parse classnames properly in this case efficiently? RegExp might be quite slow here I guess?

Problem #2 - Inlining styles into html chunk

My plan is to get the chunk of html that comes from renderToNodeStream and inline corresponding css into response - so it will be working similarly to interleaveWithStyles method of styled-components

Here's how chunk looks after styled-components processes it - <style> node might be inserted in the middle of <svg> - I suppose its not a problem as long as I will load full css eventually, but this doesn't feel safe as this node might be easily removed e.g. by react hydrate. So what would be correct way to enrich html stream with inlined css?

enter image description here

godblessstrawberry
  • 4,556
  • 2
  • 40
  • 58

2 Answers2

1

create a clone of readable stream that is returned by renderToNodeStream. convert it into string and purify with css to get the critical css.

  • converting a stream into a string will make the render synchronous. it is a pretty serious side-effect. if one was working with synchronous rendering, one might as well use `renderToString()`. further, how do you extract critical CSS? it won't happen by itself. – Igor Shmukler May 15 '22 at 16:03
0

https://github.com/theKashey/used-styles is working exactly as your desired solution:

  • scans your build folder to find all styles you can use
  • scans your HTML output collecting used styles (thus the name)
  • inlines references to used style files as well as rules in a bulk (renderToString) as well as stream(renderToNodeStream) modes
  • moves all injected code outside renderer markup just before applicating start allowing correct hydration.
Anton Korzunov
  • 140
  • 1
  • 8
  • Unfortunately, the documentation is pretty bad and there are no examples. Since you managed to make the package, perhaps document it a little. – Igor Shmukler Aug 29 '21 at 23:15