Skip to content
This repository has been archived by the owner on Jun 17, 2024. It is now read-only.

Aphrodite vs. JSS - Thoughts? #172

Closed
kentcdodds opened this issue Aug 5, 2016 · 12 comments
Closed

Aphrodite vs. JSS - Thoughts? #172

kentcdodds opened this issue Aug 5, 2016 · 12 comments

Comments

@kentcdodds
Copy link
Owner

@kof asked me:

Hey Kent, I have seen you are using aphrodite
I am curious what you think about jss compared to aphrodite if you had a chance to compare them. I wrote an article recently: https://twitter.com/oleg008/status/761476939601289216

@kentcdodds
Copy link
Owner Author

Hi @kof!

Here are my thoughts:

  1. Performance: I have yet to experience bad perf with aphrodite. JSS may be faster, maybe it's not, but it doesn't matter to me as long as aphrodite is "good enough" (which it is). Also, perf is being worked on: Try insertRule Khan/aphrodite#83
  2. Transparency: I haven't needed this
  3. no-important.js: I voted for this approach. So I think it actually is a fine way to make this optional.
  4. Plugins: I actually like the fact that aphrodite is not pluggable. For many libraries, having something that's pluggable is important, but for something as defined as CSS, I don't think so. I'd rather have one thing that solves all my CSS in JS problems and I think aphrodite does that (with the exception of a few edge cases that are under development). The problem with plugins is it can fragment the community. You have to be sure that you're getting more benefit than cost with regards to that. For example, Redux needs to cover a TON of use cases, so making it pluggable was a big part of its success. CSS in JS does not need to cover nearly as many use cases and I'd prefer to have a single abstraction to handle all those use cases and avoid fragmenting the community.
  5. Targeting child nodes is currently under development: Allow additional handlers for special selectors to be added. Khan/aphrodite#95 In cases where I need to do some global styles or work around this current limitation, I just use regular CSS, which is not a terrible workaround for me.
  6. Unpredictable rendering: I've not experienced this myself yet, so I can't speak to this. I do know that other people have had this trouble though. I believe this is also being worked on. I do not believe that the solution is to insert CSS into the dom synchronously. I would imagine that would be a perf issue. Batching CSS application is one of the things that makes aphrodite fast.

I hope that's helpful! Thanks for your work on JSS!

@kof
Copy link

kof commented Aug 5, 2016

Thank you for answers!

A few thoughts from my side:

no-important.js: I voted for this approach. So I think it actually is a fine way to make this optional.

The approach itself is not bad as long as you need just one or two additional entry points, however this doesn't scale well.

Regarding plugins: I think you are underestimating the amount of use cases, think for e.g. of postcss. Of course jss will not be able to handle this amount of plugins when used at runtime, but still, many interesting and experimental things happen because we have plugins, for e.g. jss-expand or jss-isolate

Unpredictable rendering.

The reason why Aphrodite needs to batching, is because it knows what CSS to render only at render time, when css() function is called. Batching is basically a workaround because adding rule by rule during render call would cause performance overhead, so they had no other way but batching. JSS doesn't need batching because it renders sheet upfront, once a component is going to mount.

@kentcdodds
Copy link
Owner Author

I think that the no-important.js thing and the plugins are related. If I were in favor of plugins then I would agree with you that no-important.js is not a good idea, but it should instead be a plugin. However I still disagree that plugins are the right approach for something like this. With regards to the cost of plugins, one of them is this added complexity:

screen shot 2016-08-05 at 7 24 37 am

Also, something I think is a very important part of libraries is to be able to look at code that's using a library and know what the result will be. If I were to put this:

import jss from 'jss'
import jssExpand from 'jss-expand'

jss.use(jssExpand())

In a file like bootstrap.js then I put my styles in a different file, I can't know what plugins are installed and hence I wont know what plugins are available or what the result of my style configuration would be. You could get around this by doing something like this:

import jss from 'jss'
import jssExpand from 'jss-expand'

const instance = jss.getCustomInstance({plugins: [jssExpand()]})
export default instance

And then using that module everywhere. I would definitely feel more comfortable about that. But still, you're suffering the cost of added complexity and a fragmented community.

@kof
Copy link

kof commented Aug 5, 2016

I totally agree, the order of plugins should not matter in the ideal world, but I couldn't find a way around. This issue is similar in express middleware.

One way would be to provide presets, which will have all plugins installed by default. I am not sure if this should be the default or an optional thing.

Creating separate jss instances is already in place. It is done by import {create} from 'jss'. This is how I recommend to use it most of the time. maybe a documentation issue? https://github.com/cssinjs/jss/blob/master/docs/js-api.md#create-an-own-jss-instance

So when using a local Jss instance, you always know your setup for your application. Also it is possible to have different setups, for different parts of the application.

@kof
Copy link

kof commented Aug 5, 2016

I am slowly getting convinced, that the default, global instance should be with most official plugins installed. If one want a jss without plugins, create() will deliver a clean instance and one can setup all plugins.

@kentcdodds
Copy link
Owner Author

That'd be cool 👍

@kof
Copy link

kof commented Aug 5, 2016

Another option would be to have a second entry file, which has plugins built in. To give a chance people who has a custom setup to not bundle default plugins at all.

@kentcdodds
Copy link
Owner Author

Yeah, give people the option and see what they do more frequently.

@just-boris
Copy link

just-boris commented Aug 5, 2016

Another option would be to have a second entry file, which has plugins built in.

Sorry for coming into your discussion, but why not to follow the Babel way?
It is nice to have a very clean default instance and then add preset of popular plugins with a single-line import.

@kof
Copy link

kof commented Aug 5, 2016

Thought about this option too, technically it is a nicer way, but would potentially also result in fragmenting community, those who installed the preset and those who installed plugins manually.

Also this is +1 dependency and +1 function call.

@kof
Copy link

kof commented Aug 6, 2016

On the other hand, when creating a new instance, there should be also a way to define all plugins quickly ... probably we can't do it right without presets.

@kof
Copy link

kof commented Aug 6, 2016

presets released.

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

3 participants