@sjpnz/query-shared-worker-persister
v0.0.1-alpha4
Published
A persister for storing query data in a SharedWorker, to be used with TanStack/Query
Downloads
3
Readme
Tanstack Query SharedWorker Persistence
This package allows Tanstack Query state to be persisted using a SharedWorker. By leveraging this functionality, query caches can be shared and reused across multiple browsing contexts within the same origin.
Key benefit: When opening a new tab or window in your Tanstack Query-based application, it won't need to refetch queries that are already cached, improving performance and reducing unnecessary network requests.
A practical use case is caching an access token. Typically, there's no need for multiple tabs to maintain separate access tokens, making this an ideal scenario for shared persistence.
Getting Started
Installation
Install the package in your project using npm:
npm install @sjpnz/query-shared-worker-persister
Configuration
Follow these steps to configure QueryClient
persistence. While the examples use React, a similar approach applies to other frameworks.
Create a
QueryClient
andSharedWorker
persister:import { QueryClient } from '@tanstack/react-query'; import { createSharedWorkerPersister } from '@sjpnz/query-shared-worker-persister'; const queryClient = new QueryClient(); const sharedWorkerPersister = createSharedWorkerPersister();
(Recommended) Use a
broadcastQueryClient
:For optimal performance and to ensure true global sharing of cached values across tabs, it's highly recommended to use a
broadcastQueryClient
. This prevents different tabs from overwriting each other's cached values.import { broadcastQueryClient } from '@tanstack/react-query-broadcast-client-experimental'; broadcastQueryClient({ queryClient });
Replace
QueryClientProvider
withPersistQueryClientProvider
:Replace the standard
<QueryClientProvider>
with a<PersistQueryClientProvider>
in your app's root component:import { PersistQueryClientProvider } from '@tanstack/react-query-persist-client'; const persistOptions = { persister: sharedWorkerPersister, }; export default function App() { return ( <PersistQueryClientProvider client={queryClient} persistOptions={persistOptions} > <h1>Hello, world!</h1> {/* Your app components */} </PersistQueryClientProvider> ); }
With these configurations in place, your Tanstack Query cache will now be shared across multiple tabs and windows within the same origin. This means queries can be reused without unnecessary refetching when opening new tabs or windows in your application.
Best Practices and Recommendations
To get the most out of this package and ensure optimal performance, consider the following recommendations:
Configure
staleTime
for your queriesSetting an appropriate staleTime is crucial for effective caching. Without it, queries will not be loaded from the cache, negating the benefits of this package.
See the following links for more details:
- https://tanstack.com/query/latest/docs/framework/react/guides/important-defaults
- https://tkdodo.eu/blog/react-query-as-a-state-manager
// Configure all queries to be considered stale after 5 minutes const STALE_TIME = 1000 * 60 * 5; // 5 minutes const queryClient = new QueryClient({ defaultOptions: { queries: { staleTime: STALE_TIME, }, }, });
Use a Named Identifier for Your Application
Employing a unique identifier ensures that the cache remains relevant to your specific application, preventing conflicts in shared environments.
// Define a unique identifier for your application const APP_NAME = "MY_AWESOME_APP"; // Configure the SharedWorker persister with the app-specific key const persister = createSharedWorkerPersister({ key: APP_NAME }); // If using broadcastQueryClient, apply the same identifier broadcastQueryClient({ queryClient, broadcastChannel: APP_NAME, });
Implement Cache Busting with Version Control
Provide an application version to invalidate the cache when it doesn't match the current application version. This ensures that outdated data isn't persisted when one tab/window has a newer application version than another.
const APP_VERSION = "MY_AWESOME_APP_v1.2.3"; const persistOptions = { persister: persister, buster: APP_VERSION, }; export default function App() { return ( <PersistQueryClientProvider client={queryClient} persistOptions={persistOptions} > <h1>Hello, world!</h1> </PersistQueryClientProvider> ); }
Troubleshooting
The first thing you should do is use the Devtools to verify behaviour. You should see queries available in the cache.
There are some common and known reasons why you may not be seeing query caching working properly.
- Your queries do not have a
staleTime
set, meaning they will (by default) not be loaded from the cache. - BroadcastChannel is not natively supported in your browser.
- SharedWorker is not natively supported in your browser.
Regarding browser support, all modern browsers should support this functionality.
If you're experiencing issues with query caching, follow these steps to diagnose and resolve common problems:
Verify Behavior with Devtools
Start by using the Tanstack Query Devtools to inspect your query cache. You should see queries available in the cache if everything is working correctly.
Common Issues and Solutions
Queries Not Loading from Cache
Problem: Queries are refetching unnecessarily.
Possible Cause: No staleTime set for queries.
Solution: Set an appropriate staleTime for your queries. By default, queries are considered stale immediately,which can lead to unnecessary refetching. Example:
useQuery({ queryKey: ['myData'], queryFn: fetchMyData, staleTime: 60000, // 1 minute });
Cross-Tab Synchronization Not Working
Problem: Changes in one tab aren't reflected in others.
Possible Cause: BroadcastChannel API not supported or not properly implemented.
Solution: Ensure you're using the
broadcastQueryClient
as recommended in the setup. Check if your browser supportsBroadcastChannel
. A polyfill or fallback mechanism will be used in its absence. Browser support via caniuse: https://caniuse.com/broadcastchannelShared Worker Not Functioning
Problem: Persistence across tabs/windows isn't working at all.
Possible Cause:
SharedWorker
not supported by the browser.Solution: Verify browser support for
SharedWorker
. Browser support via caniuse: https://caniuse.com/sharedworkers
Browser Compatibility
While all modern desktop browsers should support the required APIs (
SharedWorker
andBroadcastChannel
), you may encounter issues with older browser versions or mobile browsers.To check current browser support:
SharedWorker
: https://caniuse.com/sharedworkersBroadcastChannel
https://caniuse.com/broadcastchannel
Additional Debugging
If issues persist:
Check your browser's console for any error messages. Ensure all dependencies are up to date. Verify that your implementation matches the setup guide exactly.
If you're still experiencing problems after trying these solutions, consider opening an issue on the project's GitHub repository with a detailed description of your setup and the issue you're facing.