Search code examples
relayjsrelayrelaymodern

Disable relayjs garbage collection


Is there a way to disable the relayjs garbage collection (version 5.0.0 or 6.0.0)?

We are still using relayjs classic and it caches all data in a session. This makes loading previous pages fast while fetching new data. In relayjs 5.0.0 they have a dataFrom on the QueryRenderer that can be set to "STORE_THEN_NETWORK" which will try the relay cache store first and fetch from the network, just like rejay classic. Except that the newer versions of relay uses a garbage collection feature to remove data that is not currently used. This makes almost all pages fetch data from the network.


Solution

  • I managed to get this working. The key thing here is the environment.retain(operation.root); which will retain the objects in the cache.

    Then in the QueryRenderer use the fetchPolicy="store-and-network".

    See my full Relay Environment file below.

    import {Environment, Network, RecordSource, Store} from 'relay-runtime';
    
    function fetchQuery(operation, variables) {
        const environment = RelayEnvironment.getInstance();
        environment.retain(operation.root);
    
        return fetch(process.env.GRAPHQL_ENDPOINT, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json'
            },
            credentials: 'include',
            body: JSON.stringify({
                query: operation.text,
                variables
            })
        }).then(response => {
            return response.json();
        });
    }
    
    const RelayEnvironment = (function() {
        let instance;
    
        function createInstance() {
            return new Environment({
                network: Network.create(fetchQuery),
                store: new Store(new RecordSource())
            });
        }
    
        return {
            getInstance: function() {
                if (!instance) {
                    instance = createInstance();
                }
                return instance;
            }
        };
    })();
    
    export default RelayEnvironment;
    

    Also got this from the Relay Slack Channel. Haven't tried it yet.

    const store = new Store(new RecordSource());
    (store as any).holdGC(); // Disable GC on the store.