question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Solution for large bundle size

See original GitHub issue

Hi There

First, a huge thank you to @manueliglesias - absolutely love appsync.

The problem (as others have pointed out) is the bundle size. It is huge, and the reason it is big is mainly because the entire AWS-SDK is imported. Even if one is not using any feature on the client that needs it. I have two suggestions:

  1. Allow consumers to consume the raw “unprocessed” version, and then in our build process, we can use something like Webpack that would minify and treeshake.
  2. Setup the project in such a way that allows a consumer to configure their options and therefore they can opt out of the expensive (in terms of size) options.

Unfortunately, I could not wait: Using aws-appsync-client in it’s current state adds almost 500kb (uncompressed) to our build, which was a blocker. Therefore I stripped things down (and things seem to work). I will provide my solution here for anyone interested, and also @manueliglesias I would appreciate it if you could comment on it.

The following code will create an Apollo client that users openId tokens for auth and subscriptions:

import ApolloClient from 'apollo-client';
import fetch from 'isomorphic-fetch';
import { InMemoryCache } from 'apollo-cache-inmemory';
import { HttpLink } from 'apollo-link-http';
import { setContext } from 'apollo-link-context';
import { ApolloLink } from 'apollo-link';
import { getMainDefinition } from 'apollo-utilities';
import { SubscriptionHandshakeLink } from 'aws-appsync/lib/link/subscription-handshake-link'; // importing directly so AWS-SDK does not get introduced
import { NonTerminatingHttpLink } from 'aws-appsync/lib/link/non-terminating-http-link';
import { onError } from 'apollo-link-error';
import { logError } from 'client/common/log';

// The singleton client instance
let apolloClient = null;

// Polyfill fetch() on the server (used by apollo-client)
if (!process.browser) {
  global.fetch = fetch;
}

const createApolloClient = (jwtTokenFunc, initialState) => {

  // Allows for custom logic when a GraphQL or network error occurs
  const onErrorLink = onError(({ graphQLErrors, networkError, response }) => {
    if (graphQLErrors) {
      graphQLErrors.forEach(({ message, locations, path }) => {
        const error = new Error(`[GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}`);
        logError(error);
      });
    }
    if (networkError) logError(new Error(`[Network error]: ${networkError}`));

    response.errors = null;
  });

  // This is very simple auth middleware - if using openId auth token
  // you really only need to provide the token as an authorization field
  // in the header
  const authOpenIdConnectLink = setContext((_, { headers }) => (
    jwtTokenFunc()
      .then(idToken => ({
        headers: {
          ...headers,
          authorization: idToken || '',
        },
      }))
  ));

  // This logic (mostly) copied from appsync's apollo client creation
  const link = ApolloLink.from([
    authOpenIdConnectLink,
    onErrorLink,
    ApolloLink.split(
      (operation) => {
        const { query } = operation;
        const { kind, operation: graphqlOperation } = getMainDefinition(query);
        const isSubscription = kind === 'OperationDefinition' && graphqlOperation === 'subscription';

        return isSubscription;
      },
      ApolloLink.from([
        new NonTerminatingHttpLink('subsInfo', { uri: GRAPHQL_URL }, true),
        new SubscriptionHandshakeLink('subsInfo'),
      ]),
      ApolloLink.from([
        new HttpLink({ uri: GRAPHQL_URL }),
      ]),
    ),
  ]);

  return new ApolloClient({
    connectToDevTools: process.browser,
    ssrMode: !process.browser, // Disables forceFetch on the server (so queries are only run once)
    link,
    cache: new InMemoryCache().restore(initialState),
  });
};

Issue Analytics

  • State:open
  • Created 5 years ago
  • Reactions:17
  • Comments:7

github_iconTop GitHub Comments

1reaction
akd-iocommented, Jan 14, 2020

I would love a comment on this too. I’m looking so much forward to getting to build apps with AppSync. With people calling the aws-appsync library “merely a wrapper of the apollo-client”, it surprises me to see the apollo-client only taking up 7% of the bundle size.

Any comments?

0reactions
pickfirecommented, Jul 20, 2020

We use appsync too but we put it under a feature module which save like ~55% (1MB) from the main bundle.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Small Bundles, Fast Pages: What To Do With Too Much ...
Analyze and fix JavaScript bundle performance issues with developer ... large bundle size will likely cause delays during load, render, ...
Read more >
Slimming down your bundle size - LogRocket Blog
Bundle optimization #2: Install lighter-weight alternative libraries. React's bundle size is still a bit large (124KB in our project), even ...
Read more >
Everything you can do to reduce bundle size for webapps
Web bundlers such as Webpack are a great tool to deploy web apps, but for more complex programs, bundle size can quickly become...
Read more >
5 Methods to Reduce JavaScript Bundle Size - Bits and Pieces
5 Methods to Reduce JavaScript Bundle Size · 1. Code Splitting with Webpack · 2. Using Webpack Plugins for Tree Shaking · 3....
Read more >
3 ways to reduce webpack bundle size - Jakob Lind
3 ways to reduce webpack bundle size · Easy: Run webpack in production mode · Medium: use an analyzer tool such as webpack-bundle-analyzer...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found