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

"First Load JS" Seems to include Apollo on the client regardless of using RSC implementation #95

Closed
blakewilson opened this issue Sep 13, 2023 · 10 comments

Comments

@blakewilson
Copy link

blakewilson commented Sep 13, 2023

Hi all, thanks for this great library.

I am trying to incorporate the RSC Apollo implementation as described here:

https://www.apollographql.com/blog/announcement/frontend/using-apollo-client-with-next-js-13-releasing-an-official-library-to-support-the-app-router/#server-components

I'm able to fetch data fine (see the posts page), but I noticed Apollo is being shipped to the client, regardless if it's an RSC or not.

I'm only using the client on the posts page, and from the build logs, you can see that the posts page is ~90kb larger than the home page:

Screenshot 2023-09-13 at 1 02 48 PM

Am I doing something wrong here?

Here is a reproduction repo.

@phryneas
Copy link
Member

That is weird - but looks like a bug in NextJs's bundling.

You don't have a single client component in that project, so I don't see a reason why any third-party library should ever be sent to the browser.

@theodesp
Copy link

theodesp commented Sep 14, 2023

@blakewilson there is a distinct difference here when using the registerApolloClient as per example:

https://github.com/apollographql/apollo-client-nextjs/blob/main/examples/app-dir-experiments/app/ApolloClient.ts

So If you use it like this:

export const { getClient } = registerApolloClient(() => {
  return new ApolloClient({
    cache: new InMemoryCache(),
    link: new HttpLink({
      uri: "https://faustexample.wpengine.com/graphql",
    }),
  });
});

The bundle size is properly slimmed:

Route (app)                                Size     First Load JS
┌ ○ /                                      5.34 kB        83.8 kB
├ ○ /api/hello                             0 B                0 B
├ ○ /favicon.ico                           0 B                0 B
└ ○ /posts                                 137 B          78.6 kB
+ First Load JS shared by all              78.5 kB
  ├ chunks/596-c294a7d39d9fe754.js         26.1 kB
  ├ chunks/fd9d1056-a99b58d3cc150217.js    50.5 kB
  ├ chunks/main-app-5064061fd36ee5d1.js    221 B
  └ chunks/webpack-dae38a8f51101118.js     1.68 kB

Route (pages)                              Size     First Load JS
─ ○ /404                                   182 B          76.5 kB
+ First Load JS shared by all              76.3 kB
  ├ chunks/framework-8883d1e9be70c3da.js   45.1 kB
  ├ chunks/main-183d48c5a18cff9a.js        29.4 kB
  ├ chunks/pages/_app-52924524f99094ab.js  195 B
  └ chunks/webpack-dae38a8f51101118.js     1.68 kB

○  (Static)  automatically rendered as static HTML (uses no initial props)

@phryneas
Copy link
Member

@theodesp I might be blind, but isn't that what they are doing?
https://github.com/blakewilson/app-router-apollo-bundle-size/blob/main/src/lib/client.ts

@mvandergrift
Copy link

mvandergrift commented Sep 15, 2023

@phryneas The OP's code is building a RSC client that returns a NextSSRApolloClient/NextSSRInMemoryCache instead of an ApolloClient/InMemoryCache.

export const { getClient } = registerApolloClient(() => {
  return new NextSSRApolloClient({
    cache: new NextSSRInMemoryCache(),
    link: new HttpLink({
      // https://studio.apollographql.com/public/spacex-l4uc6p/
      uri: "https://faustexample.wpengine.com/graphql",
      // you can disable result caching here if you want to
      // (this does not work if you are rendering your page with `export const dynamic = "force-static"`)
      // fetchOptions: { cache: "no-store" },
    }),
  });

My assumption is that the packager is shipping the additional code used for the SSR implementation.

The post he references shows an example where the RSC client is built using the NextSSR client. Is this incorrect or at least not ideal?

https://www.apollographql.com/blog/announcement/frontend/using-apollo-client-with-next-js-13-releasing-an-official-library-to-support-the-app-router/#client-components-with-server-side-rendering

Thanks!

@phryneas
Copy link
Member

@mvandergrift huh, good point, that's not ideal, I'll make sure that gets cleaned up.
But at the same time: it's only suboptimal, it should not have any consequences for the bundling.

@mvandergrift
Copy link

mvandergrift commented Sep 15, 2023

@phryneas

Yeah, there's something weird going on with nextjs bundling. Any reference to the @apollo/experimental-nextjs-app-support/ssr and the entire barrel gets imported and shipped to the client (~90kB).

Looking at the code in apollo-client-next, I removed all of the exports from ssr/index.ts except NextSSRApolloClient and NextSSRInMemoryCache. This fixed things; the RSC package size didn't increase. However, the bundler gets confused if you export ApolloNextAppProvider, hooks, or resetNextSSRApolloSIngletons. All of these have the "use client" pragma in common.

I guess that next is correctly ignoring the "use client" modules during the build, but Webpack is including them in the bundle anyway.

@blakewilson
Copy link
Author

@theodesp @phryneas @mvandergrift Thanks yall. It does seem that using ApolloClient/InMemoryCache properly reduces the bundle size. I guess the guide that I followed was using the wrong implementation. I think it would be helpful to get that guide updated for others that may fall into the same trap 🤞

My particular issue is resolved, however, it does seem like there is a greater issue here regarding Next bundling and the ssr barrel export that @mvandergrift mentions.

@phryneas I'll leave this issue open for now in case any follow up is needed re:next bundling, but feel free to close it if you feel it doesn't apply. Thanks!

@louisthomaspro
Copy link

I faced the same issue. @blakewilson, your solution works, thanks!

@phryneas
Copy link
Member

I'm doing some housekeeping so I'm closing some older issues that haven't seen activity in a while.
If this is still relevant, please feel free to reopen the issue.

Copy link
Contributor

Do you have any feedback for the maintainers? Please tell us by taking a one-minute survey. Your responses will help us understand Apollo Client usage and allow us to serve you better.

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

No branches or pull requests

5 participants