From 5461e037ee8eb497a13f049e212af6ce1aa50f60 Mon Sep 17 00:00:00 2001 From: hwillson Date: Mon, 3 Aug 2020 10:56:27 -0400 Subject: [PATCH 1/3] Add type/field policy code splitting docs section Demonstrate how to use `cache.policies.addTypePolicies()` to lazily load cache type/field policies. --- docs/source/caching/advanced-topics.mdx | 63 +++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/docs/source/caching/advanced-topics.mdx b/docs/source/caching/advanced-topics.mdx index 5d713c7addd..49fc753491f 100644 --- a/docs/source/caching/advanced-topics.mdx +++ b/docs/source/caching/advanced-topics.mdx @@ -366,3 +366,66 @@ persistCache({ ``` For more advanced usage, such as persisting the cache when the app is in the background, and additional configuration options, please check the [README of `apollo-cache-persist`](https://github.com/apollographql/apollo-cache-persist). + +## Code splitting + +Depending on the complexity and size of your cache type/field policies, you might not always want to define them up front, when you create your initial `InMemoryCache` instance. If you have type/field policies that are only needed in a specific part of your application, you can leverage `InMemoryCache`'s `policies.addTypePolicies()` method to adjust your cache policy map at any point. This can be really useful when leveraging techniques like route based code-splitting, using something like `react-loadable`. + +Let's say we're building a messaging app and have a `/stats` route that is used to return the total number of messages stored locally. If we use `react-loadable` to load our `Stats` component like: + +```jsx +import Loadable from 'react-loadable'; + +import Loading from './components/Loading'; + +export const Stats = Loadable({ + loader: () => import('./components/stats/Stats'), + loading: Loading, +}); +``` + +and wait until our `Stats` component is called to add a new type/field policy (using `cache.policies.addTypePolicies()`): + +```jsx:title=Stats.jsx +import React from "react"; +import { gql, useApolloClient, useQuery } from "@apollo/client"; +import gql from "graphql-tag"; + +const GET_MESSAGE_COUNT = gql` + { + messageCount @client { + total + } + } +`; + +const newPolicy = { + Query: { + fields: { + messageCount() { + // calculate and return the number of messages stored locally ... + return { + total: 123, + }; + }, + }, + }, +}; + +export function Stats() { + const client = useApolloClient(); + client.cache.policies.addTypePolicies(newPolicy); + + const { loading, data: { messageCount } } = useQuery(GET_MESSAGE_COUNT); + + if (loading) return "Loading ..."; + + return ( +

+ Total number of messages: {messageCount.total} +

+ ); +}; +``` + +our type/field policy code will only be included in the bundle a user downloads when (if) they access `/stats`. It won't be included in the initial application bundle, which helps keep the size of our initial bundle down, and ultimately helps with download and application startup times. From b79196b5efde1288f3e29c6295b77a25c6029948 Mon Sep 17 00:00:00 2001 From: Hugh Willson Date: Mon, 3 Aug 2020 19:54:29 -0400 Subject: [PATCH 2/3] Update docs/source/caching/advanced-topics.mdx Co-authored-by: Ben Newman --- docs/source/caching/advanced-topics.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/caching/advanced-topics.mdx b/docs/source/caching/advanced-topics.mdx index 49fc753491f..8940552e639 100644 --- a/docs/source/caching/advanced-topics.mdx +++ b/docs/source/caching/advanced-topics.mdx @@ -369,7 +369,7 @@ For more advanced usage, such as persisting the cache when the app is in the bac ## Code splitting -Depending on the complexity and size of your cache type/field policies, you might not always want to define them up front, when you create your initial `InMemoryCache` instance. If you have type/field policies that are only needed in a specific part of your application, you can leverage `InMemoryCache`'s `policies.addTypePolicies()` method to adjust your cache policy map at any point. This can be really useful when leveraging techniques like route based code-splitting, using something like `react-loadable`. +Depending on the complexity and size of your cache type/field policies, you might not always want to define them up front, when you create your initial `InMemoryCache` instance. If you have type/field policies that are only needed in a specific part of your application, you can leverage `InMemoryCache`'s `.policies.addTypePolicies()` method to adjust your cache policy map at any point. This can be really useful when leveraging techniques like route based code-splitting, using a tool like [`react-loadable`](https://www.npmjs.com/package/react-loadable). Let's say we're building a messaging app and have a `/stats` route that is used to return the total number of messages stored locally. If we use `react-loadable` to load our `Stats` component like: From 840cf97d0501b4f64631cf77414cbd56fa4d59e0 Mon Sep 17 00:00:00 2001 From: Hugh Willson Date: Mon, 3 Aug 2020 19:54:51 -0400 Subject: [PATCH 3/3] Update docs/source/caching/advanced-topics.mdx Co-authored-by: Ben Newman --- docs/source/caching/advanced-topics.mdx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/source/caching/advanced-topics.mdx b/docs/source/caching/advanced-topics.mdx index 8940552e639..40b46fef5ab 100644 --- a/docs/source/caching/advanced-topics.mdx +++ b/docs/source/caching/advanced-topics.mdx @@ -388,8 +388,7 @@ and wait until our `Stats` component is called to add a new type/field policy (u ```jsx:title=Stats.jsx import React from "react"; -import { gql, useApolloClient, useQuery } from "@apollo/client"; -import gql from "graphql-tag"; +import { useApolloClient, useQuery, gql } from "@apollo/client"; const GET_MESSAGE_COUNT = gql` {