I'm interested in getting feedback on the architecture of a web app I've inherited. Some useful context:
- App is client-side rendered, written in React and uses Apollo GraphQL for data fetching. SSR is out of scope and adds more complexity than can be justified for an admin tool.
- App has a few main top-level routes. The entry point to the app is a dashboard listing a huge number of "projects". Each project has a dedicated page (let's call it the Project Detail Page or PDP). A project consists of a bunch of project details/metadata, several assets, and posts that consume those assets.
- Using the PDP as an example, the page makes tons of small GraphQL queries (around 30 for an average page). There's a query to get all the project metadata. For each asset, there is one query to get the asset details and another to resolve its thumbnail. And for each post, there are also two queries.
We're interested in improving the performance of this application. To that end, I'm curious what the current best practices are data fetching architecture here. I've formed an opinion on this (described below) and would like feedback on if this is a good approach or not.
Proposed Architecture
- Having many small
useQuery
s distributed around the app is convenient for getting access to the relevant data in the places that care about that data. So, to that end, the current approach works nicely. I'd like to avoid implementing large scale state management (like Redux) as I think it complicates things and adds an unnecessary intermediate layer a lot of the time. - However, having many small queries adds a lot of network overhead and introduces a lot of layout shift as different parts of the page resolve at different times.
- My proposal would be to create a single, larger GraphQL query for each top-level page. This query would resolve the project details which includes asset IDs and post IDs, which would then be resolved into hydrated asset/post objects too before that data is returned in one payload. That way, all the granular
useQuery
s distributed around the app could remain in place and would basically be hitting the Apollo cache instead of the network. In a nutshell, using one big query to hydrate the cache and using it as a state management solution almost.
Does this approach make sense? Am I not thinking of something?