Skip to content

perf: load response bodies lazily instead of eager whole-config discovery #98

Description

@MaxMichel2

Part of #72

Depends on #76. Should land before #79 (the UI rework should be built against the lazy-loading model from the start, not reworked twice).

Summary

Stop loading every response body for every operation eagerly on app start. Split "what variants exist" (cheap: status code + example name, from parsed spec metadata) from "what does this variant's body contain" (real I/O: reading the externalValue file), and only pay the second cost when a user actually opens an operation's detail screen or previews a variant.

Why this matters for this migration specifically

NetworkMockViewModel.loadConfiguration() (devview-networkmock/src/commonMain/kotlin/com/worldline/devview/networkmock/viewmodel/NetworkMockViewModel.kt:138-193) discovers and loads the full body content of every response variant for every operation, upfront, before the user has opened anything. MockResponse bundles content: String directly into the object discovery returns (devview-networkmock-core/src/commonMain/kotlin/com/worldline/devview/networkmock/core/model/MockResponse.kt:79-84), so there's currently no way to get "what variants exist" metadata without also paying to load and decode every variant's full body text.

This is wasted work even for what's actually rendered on the main screen: EndpointCard's state chip only needs the currently selected variant's status code, which comes from OperationMockState in DataStore — it never reads response content. A lazy, per-operation loading path already exists as a precedent and just isn't used by the main screen: NetworkMockEndpointViewModel.loadEndpoint() (devview-networkmock/src/commonMain/kotlin/com/worldline/devview/networkmock/viewmodel/NetworkMockEndpointViewModel.kt:97-137) already re-resolves and discovers just one operation when its detail screen opens. The main screen doesn't use that pattern — it does the expensive thing for every operation, and then the detail screen does it again, per-operation, on demand.

This was always true of the bespoke JSON format, just invisible in practice, because nobody hand-writes hundreds of mock endpoints by hand. OpenAPI's entire pitch — point DevView directly at a real, possibly large, production spec — is exactly what makes this a real, user-visible cold-start cost instead of a theoretical one. Shipping the migration with the eager path means the feature that motivated the migration is the thing that makes it slow.

What to build

  • MockConfigRepository's discovery (post-feat: derive response variants from declared OpenAPI examples #76, which already replaces probing with reading declared examples) returns a lightweight descriptor — status code + example name, no content — for populating the main list screen and EndpointDescriptor/OperationDescriptor's available-responses list.
  • The content-bearing MockResponse type is only ever constructed by a loadMockResponse-equivalent call, invoked lazily:
    • by NetworkMockEndpointViewModel when its screen actually opens (already the existing pattern there, just needs to be the only place this happens for a given operation, not a redundant second load)
    • by the preview/diff sheet when a variant is actually long-pressed
  • NetworkMockViewModel.loadConfiguration() no longer calls the content-loading discovery path synchronously for every operation before the list can render — it only needs the lightweight descriptors, which come from already-parsed spec metadata (near-zero additional I/O beyond parsing the spec itself, which feat: OpenAPI 3.x spec loader (JSON + YAML) #73 already has to do once).

Acceptance criteria

  • A test with a large synthetic spec (a few hundred operations, a few declared response variants each) confirms that loading the main list screen does not read or decode every response body file — only the spec document itself is parsed.
  • The main list screen renders correctly (names, paths, methods, current-state chips) from metadata only.
  • The endpoint detail screen and preview/diff sheet still show correct response content when actually opened.
  • Existing tests for both NetworkMockViewModel and NetworkMockEndpointViewModel are updated to reflect the split between metadata and content loading.

Files likely touched

  • devview-networkmock-core/src/commonMain/kotlin/com/worldline/devview/networkmock/core/repository/MockConfigRepository.kt
  • devview-networkmock-core/src/commonMain/kotlin/com/worldline/devview/networkmock/core/model/MockResponse.kt (or a new lightweight sibling type)
  • devview-networkmock/src/commonMain/kotlin/com/worldline/devview/networkmock/viewmodel/NetworkMockViewModel.kt
  • devview-networkmock/src/commonMain/kotlin/com/worldline/devview/networkmock/viewmodel/NetworkMockEndpointViewModel.kt
  • Test files for both ViewModels

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions