perf(web): make mileage exports cancellable
This commit is contained in:
@@ -2,6 +2,20 @@
|
||||
|
||||
This document records verified risks, the production controls that address them, and the next evidence to collect. It is intentionally operational: a passing build alone is not proof that the browser application is production-ready.
|
||||
|
||||
## 2026-07-16: cancellable, off-main-thread mileage export
|
||||
|
||||
The full-fleet mileage export previously performed three long-running phases as one opaque foreground action: paginating vehicle identities, paginating daily mileage rows and building the ExcelJS workbook on the browser main thread. Navigating away did not cancel the export requests, and a large `writeBuffer()` could make controls and route transitions unresponsive.
|
||||
|
||||
The export now owns one `AbortController` for its complete lifecycle. Every vehicle and mileage request consumes that signal, leaving the route aborts the controller, and the action can be cancelled from the same button. The UI reports determinate progress while the response total is known and an indeterminate stage while Excel is generated. Workbook creation and serialization run in an ES-module Web Worker; the worker transfers the resulting `ArrayBuffer` back without copying and is terminated on completion, error or cancellation. ExcelJS remains action-only and does not enter the initial route bundle; a main-thread fallback is retained only for browsers without Worker support.
|
||||
|
||||
This matches the long-task feedback and isolation guidance used by mature design systems: Carbon recommends progress feedback for operations that last more than a moment, while Material UI explicitly recommends Web Workers or batching for processor-intensive work:
|
||||
|
||||
- <https://carbondesignsystem.com/patterns/loading-pattern/>
|
||||
- <https://carbondesignsystem.com/components/progress-bar/usage/>
|
||||
- <https://mui.com/material-ui/react-progress/>
|
||||
|
||||
The evidence gate covers request-signal propagation, user cancellation before workbook generation, immediate abort before download, worker bundling, production build output and an authenticated production interaction smoke.
|
||||
|
||||
## 2026-07-16: 50-cycle authenticated route soak
|
||||
|
||||
The production ECS application completed 50 authenticated `monitor -> history -> statistics -> tracks -> monitor` cycles. Chrome performance and heap metrics were sampled every five cycles. Because the Browser channel does not permit `HeapProfiler.collectGarbage`, the gate uses post-warmup and 15-second-idle low-water marks instead of comparing transient allocation peaks.
|
||||
@@ -59,7 +73,7 @@ The navigation and progressive-loading direction follows mature observability sy
|
||||
1. Capture an allocation profile for data-heavy operator interactions: loaded history series, long track playback and repeated Excel exports.
|
||||
2. Bound or explicitly evict other high-cardinality query families, especially arbitrary history windows and track playback ranges.
|
||||
3. Retire or migrate the remaining legacy `App.tsx` integration suite after its compatibility coverage is replaced in V2.
|
||||
4. Preserve ExcelJS as an action-only dynamic import and consider moving large workbook generation off the main thread.
|
||||
4. Profile repeated large exports after the Web Worker migration and define an explicit maximum supported row/column envelope for browser-side workbooks.
|
||||
5. Add an automated release smoke that reads the previous `.release-assets` manifest and asserts every listed compatibility asset returns HTTP 200.
|
||||
|
||||
## 2026-07-15: query memory and vehicle-count semantics
|
||||
|
||||
Reference in New Issue
Block a user