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

How does SC compare to Linaria? #2377

Closed
Tracked by #12
jferrettiboke opened this issue Feb 11, 2019 · 9 comments
Closed
Tracked by #12

How does SC compare to Linaria? #2377

jferrettiboke opened this issue Feb 11, 2019 · 9 comments

Comments

@jferrettiboke
Copy link

Linaria seems to be faster than SC since it has zero-runtime CSS in JS. More info https://linaria.now.sh/.

Can SC be faster taking into consideration another approach similar to Linaria's approach?

I started seeing some developers with a strong interest in Linaria. The syntax for React is very similar to SC.

Let's open up a discussion to see the advantages and disadvantages and let's keep innovating. SC is a great library and it is so popular within the community. Can we make it even faster?

@mxstbr
Copy link
Member

mxstbr commented Feb 11, 2019

For context: we are good friends with @satya164, the creator of linaria, and talk to him a lot. Linaria is a great library with a brilliant implementation, and we are big fans of any experimentation around CSS-in-JS.

Linaria (as well as other libraries like astroturf) statically extract the CSS into a separate file. On the other hand, styled-components (and most other CSS-in-JS libraries) inject the CSS from JavaScript.

Neither approach is universally better, they both come with their own set of tradeoffs. Saying one is faster than the other is incorrect, as it depends on the app you are building and your requirements.

With static CSS extraction, the CSS is independently cachable1, your JavaScript bundle is slimmer and the CSS is parsed independently from the JavaScript.

The downsides are that it heavily limits dynamic styling, there is no IE support for dynamic styling, users have to do an extra network request to load the CSS, and it cannot do critical CSS extraction during server-side rendering, leading to (potentially lots of) unnecessary code being downloaded.

We initially wanted to build static extraction, but decided against it as the downsides outweigh the tradeoffs for us. See #1018 and related issues for more discussions around this topic.

I hope that helps, maybe @satya164 also wants to chime in here with the linaria teams perspective on this debate!

1: How often do you change the JS without the CSS in a React app though?

@satya164
Copy link

satya164 commented Feb 17, 2019

I love how elegant and nice the syntax of styled-components is. It's also probably be one of the easiest syntax to work with when doing static CSS extraction. That's why we decided to use this API in Linaria.

Apart from the API, where styled-components shines is dynamic styling. You can generate entire a ruleset dynamically based on some props, use prop based values in places like media queries which won't work with CSS variables (in Linaria's approach). It's totally possible to workaround these limitations in many cases, but it won't be as elegant as in styled-components.

Linaria's approach can provide many advantages, such as reducing style duplication (only matters if you do SSR), parallel loading of CSS etc., and can be faster in performance critical components, for example a dynamic list with lots of components doing prop based styling (it totally depends on what you're building). You can also use the existing CSS pre-processor ecosystem (e.g. the awesome CSS grid autoprefixing with autoprefixer), other postcss plugins, Sass, stylelint processor (more accurate due to build-time evaluation) etc.

But there are clear trade-offs such as no IE support and constraints in how much dynamic you can get (basically only what's supported with CSS variables). Especially IE support can be a big issue.

Regarding critical CSS extraction, but it's mostly handled if you're doing code splitting (unless a lot of conditional rendering is going on) already and isn't probably an issue with Linaria's approach due to less style duplication (as we won't generate separate rulesets if props vary for dynamic styles). But it's hard to say, because as you can see these things are very much context dependent and will vary for every app.

However, we do provide a utility to do critical CSS extraction during SSR for the cases you need, so it can do critical CSS extraction.

An extra request for CSS can be a good thing, because the request for the CSS and parsing happens in parallel to your JavaScript, which can improve performance on lower end devices with slower parsing time. It also depends on a lot of factors like the network latency, whether you're using HTTP2 etc.

Trying to do static extraction in styled-components will be pretty difficult because it wasn't built with the constraints Linaria imposes from the beginning. And even if it was possible, it'll be limited in what it can extract. Now part of your CSS will be in JS files, another part will be in a CSS file, which will probably make it worse.

For example, Emotion had a static extraction mode and they removed it because it doesn't play well with the dynamic nature.

Also keep in mind that Linaria's setup is not as straightforward as npm i styled-components, which is possible because of no build-time processing (e.g. static extraction).

I agree that caching isn't something you can really rely on because CSS will change often when you change JS. We don't mention it as an advantage in our docs at all for this reason.

Also, mixing Linaria and SC in a codebase is supported. You can use both Linaria and SC in the same codebase if you reaaally want to, as well as alias to SC for IE support or something. Wherever we have the same API in Linaria as styled-components, we try to keep the behavior same, so a lot of code will be inter-operable.

@ImanMh
Copy link

ImanMh commented May 18, 2021

It's 2021 now and it seems like Linaria is the way to go. They seems to love styled component as well and included a feature that you can write your component in the same syntax as SC.

@mikejune
Copy link

@ImanMh Could you elaborate on why it is the way to go?

@jashwant
Copy link

@mikejune For one thing, you may not need to support IE in 2021.

@hyoretsu
Copy link

@ImanMh Could you elaborate on why it is the way to go?

Probably for the same reason as to why the flow's shfiting towards Next.js, SSR, optimization and such.

@jodaka
Copy link

jodaka commented Aug 17, 2021

We haven't tried Linaria yet, but plan to, cause we are having nasty performance issues with styled components.

@aqarain
Copy link

aqarain commented Nov 11, 2021

Please correct me if I didn't gather it correctly about Linaria:
Linaria take ALL the CSS out from ALL the JS files and make it ONE GIANT CSS file at BUILD TIME. Later on at RUNTIME, EACH component ONLY imports the CSS FROM THAT ONE GIANT file, that that PARTICULAR component is using

Is this correct?

@kitten
Copy link
Member

kitten commented Nov 12, 2021

@aqarain No, it does not create "one big file" unless your bundler combines them from all pages into one. Even if it did, I'm not sure why you're using all caps and bold highlighting 😅 If you're trying to imply that this is bad, it doesn't have to be; especially since that file is easy to parse for browsers and compressible. Generally, you'll also have overlap between pages, so an optimal bundling setup would likely want to generate a common CSS file and a split CSS chunk per page. https://github.com/callstack/linaria/blob/master/docs/BENEFITS.md#1-css-is-downloaded-and-parsed-separately-from-js

I'll lock this issue for now, since it doesn't add much value over docs that Linaria already has. I'd also point out to readers that there are several solutions now to the same problem, and vanilla-extract is another excellent one.

@styled-components styled-components locked as resolved and limited conversation to collaborators Nov 12, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

10 participants