Skip to content

Analytics Donor tab: three sequential fetch waves put the slowest, dependency-free call (globalappsspecifications, 5-15s) last #342

Description

@2ndtlmining

Reported alongside #341: selecting the Donor tab in Analytics takes a long time to show anything. Same symptom, different cause — this one is not the donation scan, so the fix in #341 will not touch it.

The load is three sequential waves

client/src/analytics/DonorTab/index.jsx:645:

wave 1   await fetch_donor_nodes(donorWallet)
wave 2   await Promise.all([ fetch_donor_utilization_source(), fetch_global_stats(null) ])
wave 3   await Promise.all([ fetch_total_network_utils(stage1), fetch_global_app_specs_raw() ])

Measured, cold:

call wire uncompressed time
fluxinfo?projection=benchmark 368 KB 3.9 MB 2.7s
fluxinfo?projection=apps.resources,ip 46 KB 668 KB 0.4s
globalappsspecifications 703 KB 1.75 MB 4.8 – 14.6s (3 runs)

The slowest call is started last, and it depends on nothing

fetch_global_app_specs_raw() is by a wide margin the most expensive thing the tab does — and it sits in wave 3, behind two full waves of waiting, even though it takes no arguments and depends on no earlier result.

Only one real data dependency exists in the whole effect: fetch_total_network_utils(stage1) needs stage1 from fetch_global_stats. Everything else is independent:

  • fetch_donor_nodes(donorWallet) — needs only the wallet, known up front
  • fetch_donor_utilization_source() — no arguments
  • fetch_global_stats(null) — explicitly passed null
  • fetch_global_app_specs_raw() — no arguments

So the critical path should be two waves, not three:

wave 1   Promise.all([ fetch_donor_nodes, fetch_donor_utilization_source,
                       fetch_global_stats(null), fetch_global_app_specs_raw ])
wave 2   fetch_total_network_utils(stage1)

That hides the 5–15s spec fetch behind the ~3s of fluxinfo work happening anyway, instead of adding to it.

Nothing survives leaving the tab

networkNodes.js:40 sets RESULT_TTL_MS = 60 * 1000, and _shared() keeps its result in a module-level variable — in-memory only. Exactly the shape #341 describes for the donation scan. Leave the tab for more than a minute, or reload, and all four fluxinfo projections are re-fetched from scratch.

fetch_global_app_specs_raw() is the exception and shows what good looks like: api/specs.js already persists to localStorage under homeAppSpecsRaw_v1 with a 5-minute TTL and a trimmed payload. A warm spec cache makes this tab feel fine; a cold one is the 15-second case.

Proposal

  1. Flatten the waterfall to two waves. Pure reordering, no caching involved, no behaviour change — the largest single win and by far the cheapest to make.
  2. Render progressively rather than all-or-nothing. setLoading(false) fires only after the last wave, so the nodes table — resolved in wave 1 — is withheld until the spec fetch lands. Nodes and utilisation should paint as they arrive; only the apps table needs to wait on specs.
  3. Persist the fluxinfo projections, as Donation section reloads from scratch on every return to Home: 19 sequential explorer requests behind a 60s in-memory TTL #341 proposes for the donation scan. benchmark is 3.9 MB uncompressed, so it must be trimmed to the fields actually read before anything is written — _trimSpecForCache in api/specs.js is the precedent. Measure before committing to this one; if a trimmed benchmark still will not fit comfortably, persist apps.resources,ip only and leave benchmark network-bound.

Do 1 and 2 first and re-measure. They are low-risk and may well be enough on their own, which would make 3 unnecessary.

Acceptance

  • The donor nodes table renders without waiting on globalappsspecifications
  • Independent fetches are issued concurrently; only fetch_total_network_utils waits on fetch_global_stats
  • Switching away from the Donor tab and back does not re-run the full load
  • cancelled still guards every setState after an await, and switching wallets mid-load still discards the stale response

Related: #341 (same class of problem on Home, different data path).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions