redwoodjs / redwood

The App Framework for Startups
https://redwoodjs.com
MIT License
17.33k stars 994 forks source link

Switch out @apollo/client for smaller bundle size #1455

Open Tobbe opened 4 years ago

Tobbe commented 4 years ago

I ripped out @apollo/client from @redwoodjs/web and implemented a super basic graphql client on my own instead. I then created two RW apps with the two different graphql clients to compare sizes

With @apollo/client

$ du -s web/dist/
1980    web/dist/

With the custom RW client

$ du -s web/dist/
1084    web/dist/

So almost half the bundle size just by switching out our graphql client. I think it's worth thinking about what we really need/want to ship by default. With the (hopefully) coming possibility for our users to wire up RW to use whatever gql client they want, maybe we don't need such an advanced and fully featured client as apollo bundled up with the framework itself.

redbar0n commented 3 years ago

"As of Redwood v0.21 the GraphQL Client is swappable." said @thedavidprice in the community forums, so I guess this one can be closed as done.

A wise decision, as it seems there are a flurry of GraphQL clients still being actively developed right now, with various levels of popularity: https://twitter.com/magnemg/status/1339219144135372800?s=20

Sidenote: In general, I would advise anyone against rolling their own GraphQL client, since caching and cache invalidation is hard. But don't take my word for it: "There are only two hard things in Computer Science: cache invalidation and naming things." -- Phil Karlton, mentioned by Martin Fowler as his own favorite saying. Not to speak of offline capabilities etc. It would involve potentially developing a long list of features.

Tobbe commented 3 years ago

"As of Redwood v0.21 the GraphQL Client is swappable." said @thedavidprice in the community forums, so I guess this one can be closed as done.

IMHO, this is not done. We still haven't swapped out @apollo/client. I'm not saying we will, or even should. But I'd prefer to keep this open until we've made a decision.

In general, I would advise anyone against rolling their own GraphQL client

Totally agree!

One very interesting experiment would be to A) create a RW app using the standard apollo client. B) build the same app again, but this time using RWs ability use another client and see what happens to the bundle size. I'm curious to see how much of apollo would be removed thanks to tree shaking. If none of it is removed then your RW app would basically be shipping with two graphql clients. C) Remove apollo client from the RW code base and replace it internally in RW with whatever client you chose for B) and again compare bundle sizes.

Also, of course bundle size isn't everything. We also want a great developer experience. So whatever we ship with by default should at least feel really nice to work with for what we're building in the tutorial.

redbar0n commented 3 years ago

IMHO, this is not done. We still haven't swapped out @apollo/client.

Oh yeah, that's true! I mistakenly thought the issue was only to have to option to do it. Good catch.

I completely agree, that would be a super interesting experiment! Though I think tree shaking would be dependent on what features/functions a given app would have/use...

I think with all the GraphQL clients out there (with varying features), and the presumption that bundle size is to some extent dependent on features, a discussion needs to be had on: what feature set should RW optimise for? Maybe only a subset of features would satisfy 80% of users needs / use cases? Hence the GraphQL client with the minimum viable bundle size could be chosen.

Update: Here is a link to the relevant discussion: https://community.redwoodjs.com/t/were-evaluating-a-new-default-graphql-client-discussion-wanted/1344

Tobbe commented 3 years ago

I'm using this repo for my tests: https://github.com/thedavidprice/redwood-tutorial-test

With the latest canary version of RW I get this when running $ yarn rw build --stats

image

Wiring up graphql-hooks I get this

image

Next step is to replace @apollo/client internally with graphql-hooks and see what that does with bundle size

Probably difficult to see unless you open up the screenshots, but @apollo/client is still present even when another client is used. So total bundle size is even bigger when you try to use some other GraphQL client

redbar0n commented 3 years ago

Cool! Corresponds roughly with what Bundlephobia reports for @apollo/client (33.9 kB), and graphql-hooks (3.6 kB).

redbar0n commented 3 years ago

It looks like RW is looking more into URQL than graphql-hooks, though. Maybe because the latter is too light. Feel free to jump into the discussion there.

Tobbe commented 3 years ago

~Modifying RW to use graphql-hooks internally instead of @apollo/client somehow caused graphql to balloon in size, and I don't understand why~ Never mind, figured it out, see below

Tobbe commented 3 years ago

Here we go!

This is with a modified version of RW that uses graphql-hooks internally instead of @apollo/client

image

So going from 905 KB when using @apollo/client down to 757 KB using graphql-hooks! Nice!

redbar0n commented 3 years ago

Nice! You shaved off a good 148 kB of RedwoodJS total size by dropping Apollo Client in favor of graphql-hooks throughout it! But how would that translate to reduced content (minified and gzipped) sent to the browser over the wire?

Tobbe commented 3 years ago

netlify-identity is so big it dwarfs everything else right now. I'd like to create a new project that doesn't have netlify-identity included, and run the bundle analyzer on that. Realistically I think we'd also want caching, which @apollo/client includes by default, but that graphql-hooks doesn't. So I'll add their memcache plugin as well before doing any further analyzing.

EDIT: I noticed that installing graphql-hooks-memcache also installs tiny-lru

image image

So caching seems to add about 2 kb to the total zipped size.

jpvajda commented 2 years ago

@Tobbe 👋 I was reviewing this issue and though it's older, it's still very relevant of a topic for us at Apollo GraphQL, as we've had others asking us about the total bundle size of Apollo Client and have raised concerns about it's size. I'm actually the Staff Product Manager of Apollo Client, and I'd be deeply interested in learning where this particular change is at for RedwoodJS and if there is any specific feedback we could gather from you as it relates to Apollo Client. We'd love to keep Apollo Client as part of the core offering of RedwoodJS, so any feedback you can share would be awesome for us to hear.

I'd be happy to setup some time to discuss further or we can have any async conversation. I'm also including the Client engineering team on this issue as they are always open to feedback and happy to answer any questions.

cc @benjamn @hwillson @brainkim

Tobbe commented 2 years ago

@jpvajda Thanks for reaching out. I don't have time to take lead on this right now, but someone else from the RW team will be in touch. But since this issue was about the library size I'm curious to hear 1) Has the size changed significantly in the year and a half since I raised the issue? 2) Is there anything we can do to reduce it?

As a team we have more input than this, but as I said, someone else will contact you about that 🙂 Thanks again for writing to us.

jpvajda commented 2 years ago

@Tobbe Sounds great! I just checked our current bundle size on a test app I made for the current release 3.6.4 of the Web Client, and it's current showing:

Screen Shot 2022-05-17 at 1 47 11 PM

As for reducing the overall bundle size, it's definitely something we've been discussing as a team lately, and we'd be interesting in learning more about what issues you are facing with the current bundle size.

Happy to discuss further with a member of the RS team.

cc @benjamn

Tobbe commented 2 years ago

Thanks for the bundle size analyzer screenshot. Seems it has gained some size since I posted a screenshot back in 2020 (to be fair though, who hasn't 🍩 🍕 😁 )

image

jtoar commented 2 years ago

Hey @jpvajda! I'm only a few months late with my response. So sorry. I went on vacation as soon as you commented here and when I got back of course I had a ton of things to do and never really caught up. Till now!

I couldn't figure out how to contact you, so I'm posting here. (First I tried Twitter, then I tried looking for your email in your git commits.)

I went back and forth on the format. Should I write it all up? Do a demo? I settled on a demo. So here's a 10 minute video that walks through most of the things I wanted to say: https://s.tape.sh/WuCpdKuf. Give that a watch and tell me what you think and where we could discuss further.

jpvajda commented 2 years ago

@jtoar This is amazing feedback! Thanks for taking the time to put all of this together for us. I'm going to share all of this with the team.

Would you be interested in setting up some time in the near future to talk more in detail? If so feel free to hit me up at my Apollo email address and we can set something up. jvajda-at-apollographql-dot-com

NetLancer commented 2 years ago

I personally thought about bundle size decrease by swapping for preact, and it appeared that urql claims to have good charasteristics + supports preact,so preact & urql options would be great to have, the solution i've been googling for ))