lightningcss icon indicating copy to clipboard operation
lightningcss copied to clipboard

Optimization idea: Split file by media query(s).

Open nicksrandall opened this issue 3 years ago • 4 comments

Not sure if it makes sense to live in this package but since we have the AST, would be easy to implement here.

The basic idea is that we could take a css file like this as input:

/* Set the background color of body to tan */
body {
    background-color: tan;
}

/* On screens that are 992px or less, set the background color to blue */
@media screen and (max-width: 992px) {
    body {
        background-color: blue;
    }
}

/* On screens that are 600px or less, set the background color to olive */
@media screen and (max-width: 600px) {
    body {
        background-color: olive;
    }
}

/* Show dark mode when user prefers it */
@media (prefers-color-scheme: dark) {
  body  { 
    background:  #333; 
    color: white;
  }
}

And then split it into 4 files, one for each unique media query included in the file: Media: N/A

body {
    background-color: tan;
}

Media: screen and (max-width: 992px)

body {
    background-color: blue;
}

Media: screen and (max-width: 600px)

body {
    background-color: olive;
}

Media: (prefers-color-scheme: dark)

body  { 
  background:  #333; 
  color: white;
}

This list of split files could then be used by bundlers (like parcel) to generate multiple <link rel="stylesheet" media="..." href="..." /> in the HTML.

This would be a performance optimization as link tags with media queries are non-render blocking for the browser.

nicksrandall avatar Dec 31 '21 18:12 nicksrandall

Interesting idea. It's a tradeoff I guess. It means more network requests, and potentially delayed UI updates when the media query first matches (e.g. on window resize) because the browser has to download that CSS on demand.

devongovett avatar Dec 31 '21 19:12 devongovett

This would involve more network requests. However, I have a hard time seeing this growing to something unmanageable in real-world scenarios (especially with the prevalence of HTTP/2).

Also (interestingly), <Link /> tags with the media attribute are not lazy loaded. If the media attribute evaluates to true, the link tag is downloaded with high priority and marked as render-blocking (like a regular link tag). If the media query evaluates to false, the link tag is still downloaded immediately (albeit with a low priority) and marked as non-render blocking so that rendering can begin before the download has finished.

nicksrandall avatar Dec 31 '21 20:12 nicksrandall

Wouldn't this cause problems though in the general case because the order changes and therefore the specificity?

mischnic avatar Dec 31 '21 21:12 mischnic

Wouldn't this cause problems though in the general case because the order changes and therefore the specificity?

Yes, it could. The bundler would have to enforce that the stylesheets with media attrs all came after the root stylesheet and then then sort the media attributes in some intelligent way (perhaps configurable by end user).

nicksrandall avatar Dec 31 '21 21:12 nicksrandall