Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Split CSS to @media-related files to improve performance significantly #37830

Closed
2 tasks done
WEBPerformace opened this issue Jan 7, 2023 · 3 comments
Closed
2 tasks done
Labels

Comments

@WEBPerformace
Copy link

WEBPerformace commented Jan 7, 2023

Prerequisites

Proposal

When CSS is bundled into one file, even after tree-shaking, it still contains a lot of unused CSS because of different @media contexts (mobile, tablet, desktop, dark/light/other themes, etc.).

It’s bad for Core Web Vitals: First Input Delay (FID), Largest Contentful Paint (LCP), Cumulative Layout Shift (CLS), as well as other vital performance and usability metrics: First Contentful Paint (FCP), Total Blocking Time (TBT), Time to Interactive (TTI), and DOMContentLoaded event.

There is a way to improve CSS loading and rendering significantly by separating CSS into different files, where every file contains only code needed in that context.

This can be achieved by separating the CSS into different files:

📄main.css        - contains CSS needed for all @media conditions
📄screen.css      - contains CSS needed only for screen @media condition
📄print.css       - contains CSS needed only for print @media condition
📂breakpoints
    📄x-small.css - contains CSS needed only for X-Small breakpoint
    📄sm.css      - contains CSS needed only for Small breakpoint
    📄md.css      - contains CSS needed only for Medium breakpoint
    📄lg.css      - contains CSS needed only for Large breakpoint
    📄xl.css      - contains CSS needed only for Extra large breakpoint
    📄xxl.css     - contains CSS needed only for Extra extra large breakpoint
📂themes
    📄light.css   - contains CSS needed only for light theme
    📄dark.css    - contains CSS needed only for dark theme

Then, include CSS files like this:

<link rel="stylesheet" href="main.css" media="all">
<link rel="stylesheet" href="screen.css" media="screen">
<link rel="stylesheet" href="print.css" media="print">
<link rel="stylesheet" href="x-small.css" media="(max-width: 575px)">
<link rel="stylesheet" href="sm.css" media="(min-width: 576px)">
<link rel="stylesheet" href="md.css" media="(min-width: 768px)">
<link rel="stylesheet" href="lg.css" media="(min-width: 992px)">
<link rel="stylesheet" href="xl.css" media="(min-width: 1200px)">
<link rel="stylesheet" href="xxl.css" media="(min-width: 1400px)">
<link rel="stylesheet" href="light.css" media="(prefers-color-scheme: light)">
<link rel="stylesheet" href="dark.css" media="(prefers-color-scheme: dark)">

With this approach, modern browsers prioritize CSS loading for the current @media conditions, so page rendering starts much faster because users don’t need to wait for the loading of the unused part of the CSS.
In cases where you have all the CSS bundled in one file and don’t specify conditions in media attributes of link tags, the browser waits for the entire set of CSS to load before starting page rendering. Which slows down page rendering drastically.

Breakpoints in this example are based on Bootstrap 5. This approach will become even more important for Bootstrap soon given that Bootstrap will add support of light/dark/other themes.

Source: https://nednex.com/en/split-your-css-to-media-related-files-to-improve-performance-significantly/

Further reading about this improvement:

  1. https://pepelsbey.dev/articles/conditionally-adaptive/
  2. https://developer.mozilla.org/en-US/docs/Learn/Performance/CSS

Motivation and context

Significant performance improvements, especially noticeable on slow connections and mobile devices.

@mc2002tii
Copy link

The perfers-color-scheme query isn't going to work if you want to allow people to override the OS setting (like the 5.3.0 documentation shows). Would you really be saving much by the time you download main, screen, one of the sizes, and one of the themes? There shouldn't be a lot of overhead with http/2 for multiple files vs. one, but there will be some.

@mdo
Copy link
Member

mdo commented Jan 7, 2023

Little weird to post the entirety of a blog post as an issue, but I appreciate the thinking around this stuff. Fun to second guess what we normally do. No plans to go this route though, at least with our own code. Sounds like a fun post processing step or something for bundlers to address.

@mdo mdo closed this as not planned Won't fix, can't repro, duplicate, stale Jan 7, 2023
@WEBPerformace
Copy link
Author

WEBPerformace commented Jan 11, 2023

The perfers-color-scheme query isn't going to work if you want to allow people to override the OS setting (like the 5.3.0 documentation shows).

On the contrary, it will work perfectly, because by the time the user overrides the theme, he already has a cached copy of both themes.

Would you really be saving much by the time you download main, screen, one of the sizes, and one of the themes?

Yes, it saves a lot, especially on mobile and bad internet connections.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants