15 ms·
Real-world CSS vs. CSS-in-JS performance comparison
- jonorsi 5y agoThis is an apples to oranges comparison -- a run-time compiled stylesheet vs. a statically-generated stylesheet. Styled Components has options for statically-generating their stylesheets (https://styled-components.com/docs/advanced#server-side-rendering https://styled-components.com/docs/advanced#server-side-rend...), so why wouldn't you compare those?
- NegativeLatency 5y agoMight not be a fair comparison, but there are people who are looking at changing up how their css is written so it makes sense to be aware of the differences in performance.
- jonorsi 5y agoDefinitely should be aware, and I would highly recommend static files over large JS apps. The options are there to have both now with frameworks like Gatsby and Next.
- fullstackchris 5y agoCan confirm from multiple sites, Gatsby with CSS modules runs like lightning
- andrewingram 5y agoYou linked to server side rendering, not static extraction of styles, did you mean something else? The point of static extraction (something the current wave of new CSS-in-JS libraries seem to be focusing on), is to generate all the style sheets at build time and serve them as regular CSS files — so that your styles don’t inflate your JS bundles (a problem most older CSS-in-JS libraries have).
- jonorsi 5y agoSSR would extract all the styles out for the styled components, but I guess now it would have an advantage as all the html/js would be as well. My point is, the comparison seems more “js runtime stylesheets” vs “regular static stylesheets.” Styled Components, or CSS-in-JS, isn’t really the main focus here. There are options to get the static stylesheets generated, and I predict most CSS-in-JS frameworks will eventually provide the tools to do so.
- andrewingram 5y agoWith conventional CSS-in-JS solutions like emotion and styled-components, SSR with these libraries still extracts the stylesheets at run-time, so it's not static extraction -- where the extraction is done at build-time. And your style definitions still live in your code bundles -- inflating the size. Both emotion and styled-components have dabbled in supporting static (build-time) extraction, but it's actually a hard problem to solve when you have such flexible APIs. The libraries that have cropped up to support this notion of near-zero runtime CSS-in-JS (Linaria, Astroturf, vanilla-extract, and more) do so by providing tighter constraints surrounding what you can and can't do.
- jonorsi 5y agoSSR (at least with Gatsby) extracts the styles at build-time.
- andrewingram 5y agostyled-components can do automatic injection of critical CSS into the page HTML, but doesn't do static extraction of stylesheets.
- epigen 5y ago> Don’t use runtime CSS-in-JS if you care about the load performance of your site. Simply less JS = Faster Site. There isn’t much we can do about it. But if you want to see some numbers, continue reading.
- toadkicker 5y agoStudies show computers running less code perform faster
- dorianmariefr 5y agoloop {}
- nwienert 5y agoI wrote SnackUI[0] to solve this exact problem. It gives you in my opinion a nicer style syntax (flat style props on the component) while avoiding the downsides of CSS-in-JS by extracting everything but the most dynamic parts to pure CSS. The optimizing compiler part was a large investment to get right, especially with theme and media query support. But the main claim to fame is that it also works on React Native, and optimizes there as well, so you get for the first time a really performant way to style native and web apps at once. [0] https://github.com/snackui/snackui https://github.com/snackui/snackui
- paulintrognon 5y agoWhy the downvotes?
- mrwnmonm 5y agoI noticed this a while ago. Some people with the ability to downvote, downvote some comments for no reason, other than hating the comment somehow. They try to release their hate through the downvote, which is funny actually.
- lucas_codes 5y agoIf largest contentful paint is over 6 seconds, is Css-in-JS really the problem?
- tonerow 5y agoI had the same thought at first, but after re-reading it I think it's because of the Slow 3G network throttling.
- MatekCopatek 5y agoCan someone explain the appeal of CSS-in-JS? I've used scoped styling in .vue components extensively, at a quick glance it seems to offer similar benefits (lives right in your component and is scoped to it), but most importantly it can be extracted to a plain CSS file when building frontend assets. Is there something extra these React libraries do that prevents them from doing this?
- jahewson 5y agoFor highly dynamic styles it allows me to avoid all the logic around coming up with class names and applying them. Think of it less like traditional CSS and more like a super version of inline styles.
- troll_v_bridge 5y agoCss-in-js helps minimize context switching for logic related styling, believe this is one of the main advantages from a developers perspective. It also allows javascript developers to colocate their CSS where they want, separate file, inline, same file, etc. This is more flexible than a .vue file in that sense.
- lwhi 5y agoI've never really been comfortable with the idea, as I was raised on the idea that separation of concerns is good thing. I think one of the main appealing aspects is the idea of never having a styling conflict with other components ever. Less macro-level management and organisation required. -- Edit: sorry, just realised you're talking about a specific implementation.
- stevebmark 5y agoCSS and Javascript aren't concerns, they're technologies, and separation of technologies isn't a software engineering principle. "Concern" is pretty undefined in general. If anything, they're all part of the "view" concern. It's the same reason why JSX doesn't violate separation of "concerns."
- 5y ago
- hudixt 5y agoA 4 year experienced react dev here. I have had decent time working with different styling I'll try to answer few common things for everyone's context Why even use CSS in JS? - SPA bundling usually loads all CSS at once and all styles collide. You need to be super good at naming stuff/or load CSS based on module. So your CSS will be conflicting, so scoping is helpful here. - Not having to jump from your component file to CSS file. Save some context switching or few strokes. - Dynamic control over style. Basically your stylesheet is JS function returning style. You can do anything here. See this https://github.com/styled-components/styled-components/issues/1018#issuecomment-316827497 https://github.com/styled-components/styled-components/issue... - Support for JS reference in color, font sizes, etc with editor support. It'll lead to more consistent design system. - More cleaner API when using media queries, pseudo states. eg-https://emotion.sh/docs/media-queries https://emotion.sh/docs/media-queries Another alternative is Emotion, also I find it to be much more cleaner in code perspective. (Good performant library in terms of layout and painting). Why is export option not available for most CSS in JS (some suggested this as solution)? Read this https://github.com/emotion-js/emotion/blob/bcf40cf2c201534813f7e3070aacd59e9f674f6f/docs/extract-static.mdx https://github.com/emotion-js/emotion/blob/bcf40cf2c20153481... Is it worth it? - Depends a lot on context and your perfonal objective. Generally I personally feel it's worth it as it's good tooling. - CSS in JS is lot better than what it used to be. Styled component had good perf bump in last few years.
- stevebmark 5y agoCSS modules solves all of these problems (except the separate file), and also lets you write vanilla CSS, and not have to hack around the limitations of css-in-js. Dynamic styles are easy with React's `css` prop, or simply passing in an additional class name.
- mikewhy 5y agoReact doesn't have a CSS prop.
- frank_nitti 5y agoMust be referring to the style prop for jsx elements whose argument conforms to the React.CSSProperties interface
- z3t4 5y agoI'm not a fan of web frameworks such as React and CSS in JS, but to be fair, you should not stare blindly on first-time-load times! Imagine if you would include download and install time when you measured native app performance... You should also take into account repeat use performance! While most "users" will just load the app once and leave, those who actually use the app will spend hours clicking around and doing stuff, and that's where aka "single page app" have an advantage over full reloads. Measure things like click latency and re-render times!
- pineconewarrior 5y agoThis is almost certainly a result of the recent Google "core web vitals" update.
- topspin 5y agoGreat effort and I have no dispute with the methodology. The conclusion, however, is naïve. Specifically this part: "Great developer experience shouldn’t come at the expense of the user experience." Great developer experience can conceivably deliver better user experience. A more capable, responsive and lower defect application that load 10% slower may be a net improvement. I'm not arguing that CSS-in-JS actually delivers that. Only that load times aren't the only variable in the "user experience" equation.
- forgotmypw17 5y ago>A more capable, responsive and lower defect application that load 10% slower may be a net improvement. The problem with this approach is that this 10% is not a one-time fee, but is collected on a regular basis, with compounding.
- cosmotic 5y agoI very much agree that load time is not the only metric that should be measured. Unfortunately, it's one of the easiest to measure. It's also one which does not sacrifice any other UX metric like low completion time leading to less satisfaction sort of corruptible metrics. Although, in my experience, usage of react is not indicative of a more capable, responsive, or lower defect application. Quite the opposite (for me) actually. React is a good (but not absolutely reliable) indicator of slow, unresponsive (in terms of response time, not resolution scaling, buggy, and frustrating UX. From the code examples of the suggested library, it looks like a pretty simple drop in replacement for many (if not all) cases. 10% for free would be a slam dunk.
- tomgp 5y agoAs someone working predominantly on React sites for the last 4 years or so I absolutely agree. Of course you can write quick, responsive and solid sites with React but it’s not the automatic process some would like you to believe, you still have to try and often the effort required is not trivial. The problem I often find is that optimising React sites needs a bunch of knowledge and skills which are only tangentially and most related to those which you’d use to optimise a more traditional site. This is related to the topic of the OP i think; knowing how to write good css is a skill which css-in-js tries to pretend doesn’t matter but which absolutely does - things like Styled Components effectively enforce certain good practices but don’t remove the need to understand whats going on under the hood in all but the most basic of situations.
- vpfaulkner 5y agoMy gripes with traditional CSS styling are: - Styles are global - Styles are targeted via brittle, untyped, and opaque "magic strings” basically. This means mistakes are more likely to be caught at run time than compile time. Eg, I wouldn't get a compile time error if I did `position: oops` or `class="oops"`. - Styles are often "far away" from their target which makes mistakes more likely; ie this deeply nested HTML element in one file is coupled to a deeply nested style sheet in another file - It is easier to perform complex manipulation of styling if it is made up of JS objects. Eg, if I wanted to do math or I wanted one style to be a function of another (eg `marginLeft: PAGE_MARGIN`) That being said, I’m sure there are some better ways of doing traditional CSS since I last tried it that I’m unaware of... As far as the performance trade off, I'd love it with styled components did not come with this but, at least for my use case, it is usually worth it
- diob 5y agoI've really enjoyed tailwind after using styled for a while. At least for my applications, the computers my users run on can't handle the performance implications of styled. But beyond the performance, I legitimately build faster using tailwind. I also find it easier to understand the components others build as well.
- aidos 5y agoWe’re making the switch at the moment and, after a bit of a learning bump, everyone is flying along with it now. It’s basically inline-styles++ with having all the context right there but not having the edge cases that require breaking out into classes to use media queries etc. It was a little struggle at first with our previous setup, but I spent a week or so moving everything over to Vite with hot module replacement which has been life changing.
- gherkinnn 5y agoCompletely agree. This whole discussion feels silly after a day building things with Tailwind. The system, defaults, docs and tooling are excellent. And dev speed is ludicrous.
- uyt 5y agoIn theory there's nothing CSS can do that JS can't, as long as the browsers provide the equivalent API for it. Any other performance difference will go away once they devote some resources to optimizing it. The real question is whether we want styling/theming to be in it's own domain specific language. From an ergonomics standpoint, CSS is such a bad language we would rather write JS instead. But the downside of not having it in a more restricted language is that it's much harder to build tooling for it. For example, you won't be able to open up any webpage and know you can inspect and change the style of things. Instead you need to know the specific JS class for that component or ThemeProvider and modify that instead. Every ui framework is going to do things slightly differently which will be a huge blow to user customizability.
- pcthrowaway 5y agoFor others seeing a rate-limit message: https://web.archive.org/web/20210608190243/https://pustelto.com/blog/css-vs-css-in-js-perf/ https://web.archive.org/web/20210608190243/https://pustelto....
- mrwnmonm 5y ago<3
- alesso_x 5y agoThe website is being rate limited, here’s a google cached version https://webcache.googleusercontent.com/search?q=cache%3Ahttps%3A%2F%2Fpustelto.com%2Fblog%2Fcss-vs-css-in-js-perf%2F https://webcache.googleusercontent.com/search?q=cache%3Ahttp...
- leetrout 5y agoWhat is the author doing that a static site is rate limited in cloudflare?
- zoover2020 5y agoTailwind haters ;-)
- e12e 5y agoGoogle cache gives me a 404 (maybe because mobile?). This works for me: https://web.archive.org/web/20210608190243/https://pustelto.com/blog/css-vs-css-in-js-perf/ https://web.archive.org/web/20210608190243/https://pustelto....
- theschmed 5y agoor you can read the source markdown here: https://github.com/Pustelto/personal_web/blob/master/src/blog/css-vs-css-in-js-perf/index.md https://github.com/Pustelto/personal_web/blob/master/src/blo...
- deleted 5y ago[deleted]
- trinovantes 5y ago> You cannot access this site because the owner has reached their plan limits. Check back later once traffic has gone down. First time I've seen this Cloudflare error. Doesn't their free plan have almost ~1TB buffer before they take notice and ask you to upgrade?
- j03b 5y agoCloudflare Workers are billed separately, 100k requests/day on their free plan. https://developers.cloudflare.com/workers/platform/limits#worker-limits https://developers.cloudflare.com/workers/platform/limits#wo...
- oblak 5y agoI mean, I can appreciate some basic stuff like this but how about measuring rendering performance on low end devices? Like having large, medium, and small css files vs having the same thing BUT moving state changing things to js so that some specific styles are applied inline. Somewhat superficial content but might spawn a few interesting discussions.
- stephen 5y agoWe have a "write tachyons/tailwinds CSS-in-TypeScript" project [1] that can sit on top of any CSS-in-JS runtime (emotion and fela are both supported). I'm hoping to eventually find one of these build-time CSS-in-JS frameworks that is smart enough to partially eval ~80% of our `<div css={Css.m4.black.$}>` expressions to be zero runtime. And, if/when this happens, do this as a seamless upgrade to our existing codebases, i.e. without any lines of `css={Css.m4.black.$}` in our app need to change. Basically we're using our Truss DSL both for atomic/utility class names today + a decoupling layer to switch CSS-in-JS libs in the future if/when needed. I think Linaria and https://github.com/twstyled/twstyled https://github.com/twstyled/twstyled (based on/forked from Linaria) are the closest to doing this eval during compilation, but haven't had to dig in so far (runtime emotion has been fast enough for us so far). [1]: https://github.com/homebound-team/truss/ https://github.com/homebound-team/truss/
- o_m 5y agoWhy not use only Tailwind at that point? Then you always have no runtime.
- throw_m239339 5y agoIt's funny how we are going from one orthodoxy to another, from "separate logic from presentation at all cost" to "inline all css directly in your HTML tags". It reminds me the era when devs were chastised for using tables for layout, and using floats was deemed the right way to do things, when both techniques were essentially just hacks with both their strengths and weaknesses (overflow:hidden anyone?), but somehow the entire dev community was gazlit into believing that "tables" for layout were bad. Tables weren't bad, CSS wasn't just good enough, otherwise Flexbox or Grid would not be needed. Flexbox considerably simplified CSS layout. The people who never had to use a single float attribute in their style declaration cannot fathom that. CSS, the way it was designed, has been terrible for a long time and a thorn in the side of generations of web developers, but nobody want to acknowledge that. IF there is one thing the web failed at, it's absolutely CSS, from its syntax to the way it works in conjunction with HTML And Javascript.
- developer2 5y agoThe reason tables for layout were so bad was that the table as a whole couldn't be rendered (laid out) properly until every cell was fully rendered first, including images with unspecified width/height attributes as well as dynamic cell dimensions based on free-flowing text, etc. Floating div tags still cause redraws for containers with content requiring dimensions to be determined at runtime, but at least something would display. It was also easier to see which divs were causing redraws because their dimensions were not fixed, and thus developers could focus on those specific regions to try and add fixed dimensions.
- throw_m239339 5y agoedit: My comment sounds a bit angry, but it's not directed at you personally, so keep it in mind ;) > The reason tables for layout were so bad was that the table as a whole couldn't be rendered (laid out) properly until every cell was fully rendered first, including images with unspecified width/height attributes as well as dynamic cell dimensions based on free-flowing text, etc [...] That was purely a limitation of the CSS rendering engines, it had absolutely nothing do to with table layout themselves, from a developer perspective. There is no reason this problem cannot/couldn't be worked out by CSS rendering engine developers. I get what you are saying, but it wasn't a good enough reason to dismiss tables entirely (and that wasn't the biggest reason used back then when "a list apart" writers decided that tables were cancer). Floats were so good yet developers had to resort to CSS frameworks and grid frameworks for years in order to make working with CSS bearable? No, float positioning was horrible, un-intuitive and just a hack. Again, the culprit was CSS itself (and by extension the rendering engines), not the developer using tables. The irony is that all these CSS frameworks were essentially tables re-implemented on top of "floating divs". A good measure of whether a web spec is good or not, or pragmatic enough or not is how much effort developers go through in order not to use that spec directly. Generally, if using a framework on top of the spec to make that spec somehow useful is what most developers do, it means that the spec needs to be revised and improved in order to fulfil the needs of the developer, not the other way around. Obviously that doesn't apply to low level protocols like WebRTC and co, but CSS isn't a low level protocol, it was supposed to make web presentation easy, and it failed at it for decades. That's all I'm saying. Just thank god we now have at the very least Flexbox and Grid. Which makes bootstrap and co completely redundant even for devs allergic to design.
- joshwcomeau 5y agoI think an important caveat here is that in a serverside-rendered context, linaria’s 70kb of CSS would be a bigger issue than styled-component’s additional JS. The page can’t render until it has downloaded the CSS. Granted, many react apps aren’t serverside-rendered, so these numbers are still useful and interesting. But I would say that if performance is a priority, moving to an SSR solution (or away from React altogether) would have a way bigger impact on performance.
- deleted 5y ago[deleted]
- fullstackchris 5y agoBig surprise that using CSS the original way it was supposed to be used... is the most performant. CSS-in-JS has always been a sort of "hack" for me. Sure it's a great DX, but it's really just an abuse of JavaScript to have CSS capabilities "just because we can".