Commit 1988bff
feat(core): add loadingDelay prop with anti-flicker delay-before-show
Loading indicator was synchronously set on every page change and only cleared
by a 500ms polling fallback. Cached / key-reused pages flashed the spinner
~500ms then hid it — annoying visual noise especially when paging quickly
through pre-loaded images.
Three coordinated changes implement the industry-standard "delay-before-show"
pattern (see Ant Design Spin `delay`, react-loadable `delay`, TanStack Query):
1. New public prop `loadingDelay: number` (default 200ms; range 0-1000 in
playground). Defers `isFetching=true` setState by N ms; if the image
loads within the window via any path (onLoad event, polling, or cdU
fast-path), the delay timer is cancelled → loading indicator never shows.
2. cdU page-change fast-path: when `node.complete && naturalWidth > 0`
on the new center (cached image, key-reused side→center), call
`handleImageLoadEnd` directly. Skips loading state entirely, no timer
needed. Combined with the scale-calibration interrupt and canZoom
recompute already wired here, all three concerns now share the same
"new center is ready" branch.
3. handleImageLoad (centerOnLoad path) now calls handleImageLoadEnd. Was
relying solely on 500ms polling to clear loading; onLoad is the canonical
"image is loaded" signal — using it directly cuts the polling-driven
flash window from ~500ms to one render cycle.
Behavior matrix:
Cached page change → no Loading shown (fast-path)
Fast load (<200ms) → no Loading shown (delay timer cancelled)
Medium load (200-500ms) → Loading shown 0-300ms
Slow load (>500ms) → Loading shown N-200ms (vs N-500ms before)
Tests added (4 new, 112 total):
- Cached page change: #zmageLoading not in DOM throughout (fast-path lock)
- loadingDelay=50 prop: Loading appears around 50ms for uncached page
- Fast onLoad cancels delay timer: Loading never shown
- StrictMode unmount cancels loadingShowDelayTimer (cleanup invariant)
Public docs synced (sync-public-docs skill, all 8 destinations):
- types/global.ts InterfaceAndInteractionParams; defProp.loadingDelay
- getConfigFromProps + Browser context value (single-source plumbing)
- home/schema/param-schema.ts (PARAM_SCHEMA + defProp mirror)
- 7 i18n files (en/de/es/fr/ja/ko/zh-CN), all 283 keys parity verified
- README.md / README.zh-CN.md interface props table + Full type comment
- AGENTS.md prop quick-reference Interface row
- llms.txt API table row; docs/llms.txt regenerated via home build
- llms-eval/eval.test.mjs new contract assertion (16/16 pass)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>1 parent d2834bf commit 1988bff
24 files changed
Lines changed: 657 additions & 395 deletions
File tree
- docs
- assets
- packages
- core/src
- __tests__
- components
- Browser
- Image
- types
- home/src
- i18n
- schema
- llms-eval
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
84 | 84 | | |
85 | 85 | | |
86 | 86 | | |
87 | | - | |
| 87 | + | |
88 | 88 | | |
89 | 89 | | |
90 | 90 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
242 | 242 | | |
243 | 243 | | |
244 | 244 | | |
| 245 | + | |
245 | 246 | | |
246 | 247 | | |
247 | 248 | | |
| |||
270 | 271 | | |
271 | 272 | | |
272 | 273 | | |
273 | | - | |
| 274 | + | |
274 | 275 | | |
275 | 276 | | |
276 | 277 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
237 | 237 | | |
238 | 238 | | |
239 | 239 | | |
| 240 | + | |
240 | 241 | | |
241 | 242 | | |
242 | 243 | | |
| |||
265 | 266 | | |
266 | 267 | | |
267 | 268 | | |
268 | | - | |
| 269 | + | |
269 | 270 | | |
270 | 271 | | |
271 | 272 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
72 | 72 | | |
73 | 73 | | |
74 | 74 | | |
75 | | - | |
76 | | - | |
| 75 | + | |
| 76 | + | |
77 | 77 | | |
78 | 78 | | |
79 | 79 | | |
| |||
Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
This file was deleted.
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
72 | 72 | | |
73 | 73 | | |
74 | 74 | | |
75 | | - | |
76 | | - | |
| 75 | + | |
| 76 | + | |
77 | 77 | | |
78 | 78 | | |
79 | 79 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
71 | 71 | | |
72 | 72 | | |
73 | 73 | | |
| 74 | + | |
74 | 75 | | |
75 | 76 | | |
76 | 77 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
71 | 71 | | |
72 | 72 | | |
73 | 73 | | |
| 74 | + | |
74 | 75 | | |
75 | 76 | | |
76 | 77 | | |
| |||
0 commit comments