This repo demonstrates that mergeConfigs
and useSWRConfig
are called on the server-side even though (swr)[https://www.npmjs.com/package/swr] does not do much on the server-side.
These calls have a cost that is probably not readily apparent to users of swr
:
- In one example of a server-side rendered page with a deep menu using a heavy object (which was refactored after noticing this), skipping 3000 calls to
mergeConfigs
anduseSWRConfig
saved 200-250 ms of CPU time and reduced the server-side CPU consumption of the entire deployment by ~40% - In that same example, the client-side mobile First Input Delay dropped 100-200 ms by that same reduction in the number of useSWR calls made by menu items
Hooks can't be conditionally called in React, so it's not usually easily possible to skip a useSWR
or useSWRConfig
call on the server-side. Perhaps swr
should skip most of the code / specifically the config merges, on the server-side to save CPU time, such as when typeof window === 'undefined'
.
One or more of the following could be considered:
- Put a caveat in the docs that
useSWR
anduseSWRConfig
are not inexpensive to call and provide some suggestions on how to limit down the number of calls when leaf node components need the data provided or a handle to themutate
function - Warn in dev-mode when more than 100k calls are made to
mergeConfigs
oruseSWRConfig
(or some other threshold) during the process lifetime- This should be both a client-side and server-side warning as the cost is incurred on both sides
- Eliminate most of all of the work on the server-side if possible
- Reduce the cost of getting the
mutate
function fromuseSWRConfig
- Reduce the cost of calling
useSWR
by reducing the number of object merges viaOBJECT.assign
and/or other approaches
npm i
npm run dev
http://localhost:3000/
- Click the links
- Check the console logs for the server for
useSWRConfigCallCount
andmergeConfigsCallCount
- (no-swr)[http://localhost:3000/no-swr] will not call
mergeConfigs
oruseSWRConfig
on the server-side - (swr)[http://localhost:3000/swr] will call
mergeConfigs
1000 times anduseSWRConfig
1000 times on the server-side - (swr-config-only)[http://localhost:3000/swr-config-only] will call
useSWRConfig
1000 times but will not callmergeConfigs
at all
npm i
npm run build
npm run start > /dev/null
- Note: with the patch applied that logs calls, the time will get much slower if the output is not redirected to
/dev/null
, which is not a fair comparison
- Note: with the patch applied that logs calls, the time will get much slower if the output is not redirected to
- Test
no-swr
pageab -c 5 -n 100 http://127.0.0.1:3000/no-swr
- 50th percentile:
17 ms
- Test
swr
pageab -c 5 -n 100 http://127.0.0.1:3000/swr
- 50th percentile:
87 ms