Repository navigation
UI: cache the server version so the sidebar does not reload it on every navigation #29917
Description
Summary
Fetch the server version once per page load and reuse it in the sidebar, instead of refetching /api/version every time the sidebar mounts.
Motivation
The version label under the logo in the sidebar shows Loading... and then the version again each time the user moves between top-level pages (Applications, Settings, User Info, Documentation). Each move also sends a new GET /api/version request, even though the server version cannot change while the page is open.
This happens because every route renders its own <Layout>, so a top-level navigation remounts <Sidebar>:
Lines 327 to 347 in 1e2cf75
| <Route | |
| key={path} | |
| path={path} | |
| render={routeProps => | |
| route.noLayout ? ( | |
| <div> | |
| <route.component {...routeProps} /> | |
| </div> | |
| ) : ( | |
| <DataLoader load={() => services.viewPreferences.getPreferences()}> | |
| {pref => ( | |
| <Layout | |
| onVersionClick={() => this.setState({showVersionPanel: true})} | |
| navItems={this.navItems} | |
| pref={pref}> | |
| <Banner> | |
| <route.component {...routeProps} /> | |
| </Banner> | |
| </Layout> | |
| )} | |
| </DataLoader> |
<Sidebar> then fetches the version with argo-ui's useData, which always starts with loading = true:
argo-cd/ui/src/app/sidebar/sidebar.tsx
Line 34 in 1e2cf75
| const [version, loading, error] = useData(() => services.version.version()); |
On a full page load this request is also a duplicate, because app.tsx already fetches the version once at module load (versionLoader):
Line 98 in 1e2cf75
| const versionLoader = services.version.version(); |
Proposal
Cache the version result for the lifetime of the page. For example, memoize the promise in VersionService.version() (and clear it on failure so a retry is possible), or keep the resolved value in a module-level variable in sidebar.tsx. Then use the cached value as the sidebar's initial state, so a remount renders the version immediately without a request. The existing versionLoader in app.tsx already relies on the same assumption that the version does not change during a page load.
This would also fix the label getting stuck on Loading... when /api/version fails, because useData never resets loading on error and the render checks loading before error.
Moving <Layout> outside <Switch> would stop the remount entirely, but it also touches noLayout routes and extension routes, which seems too broad for this change.
I'm happy to open a PR for this.
Activity