fix(detail): stop the switch + zoom-load flicker - #532
Merged
Conversation
Two flicker problems reported after the zoom fixes deployed: Switching photos flickered the info panel: - HistogramChart/ToneAnalysis were fed `preview_url`, which on this deployment is the full-resolution (~30MP) image, so every switch RE-FETCHED + RE-DECODED a 30MP image just to compute the histogram (empty → recomputed → popped in). Feed them the same ~1280 display variant the slide already has cached instead (the histogram downscales to ~300px, so a variant is more than enough). No extra fetch, tiny decode. Falls back to preview_url only when there are no variants. - The histogram flashed its backdrop-blur loading spinner (and dimmed its canvas) on every recompute. Show the spinner only on the very first load; on a switch keep the previous histogram visible and let the spring animation morph to the new one. Zoom flickered continuously while the high-res image loaded: - The XHR's `loadingProgress` updates re-render ProgressiveImage many times during a multi-MB load, which re-rendered the WebGL viewer each time. Memoize the viewer so progress ticks don't touch it — its props are stable until the image actually loads. Mount/unmount (the #510 destroy lifecycle) is unchanged. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Zheaoli
added a commit
that referenced
this pull request
Jun 12, 2026
…oesn't flicker ToneAnalysis returned a spinner unconditionally while `loading` (`if (loading) return <spinner>`), so every photo switch collapsed the whole tone section to a tiny spinner and re-expanded it when the new analysis finished. That shrink/grow shifted the entire info panel's layout (histogram and device-info rows below jumped up then back) — the "info panel flashes/ reloads on switch" the user reported. #532 added the `loading && !histogram` guard to the histogram chart but not to tone analysis, so the histogram stopped flickering while this one kept doing it. Apply the same guard here: only show the spinner on the first analysis (`loading && !toneData`); on a switch keep the previous tone values rendered until the new ones are computed (the in-session LRU cache from #521 still returns instantly for revisited photos). No size change → no panel shift. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
pull Bot
pushed a commit
to candies404/PicImpact
that referenced
this pull request
Jun 12, 2026
…letterbox blur, keep tone panel) Rebuilt on top of besscroft#535 (which removed the preview fade animation). besscroft#535 alone did not fix the dominant flicker because it kept `object-contain md:max-h-[90vh]` and didn't touch the info panel. This adds the remaining, verified fixes: - Image height: `<img>` (preview + high-res) `md:max-h-[90vh]` → `object-contain w-full sm:h-full`, and the ProgressiveImage root wrapper `relative` → `relative sm:h-full` so the height:100% chain resolves (container sm:h-[90vh] → viewport → slide → wrapper → img). The img element then stays a constant 90vh for every aspect ratio instead of resizing ~607↔1366px and overflowing on each switch. Verified live: injecting the wrapper height made the slide img go 607→810px. - Blur placeholder: `style={{ objectFit: 'contain' }}` on the preview image so next/image renders the blur with `background-size: contain` (it reads style.objectFit, not the className) — otherwise the blur filled the fixed box via `cover` and the real image shrank to letterbox on load = a load flash. - Tone analysis panel: `if (loading)` → `if (loading && !toneData)` so a switch keeps the previous tone values rendered instead of collapsing to a spinner and shifting the whole info panel's layout. Mirrors the histogram guard from besscroft#532 (which was never applied to tone analysis). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Two flicker problems reported after the zoom-blank fixes deployed.
② Switching photos flickers the info panel
preview_url, which on this deployment is the full-resolution original (preview compression off). Each switch didnew Image(preview_url)+getImageData→ a 30MP fetch + decode → the panel went empty, recomputed, then popped in. Fix: feed them the same ~1280 display variant the slide already has browser-cached (the histogram downscales to ~300px, so a variant is plenty) → no extra fetch, tiny decode. Falls back topreview_urlonly when the photo has no variants.loading && !histogram); on a switch keep the previous histogram visible and let the existing spring animation morph to the new one.① Zoom flickers continuously while the high-res loads
The high-res XHR's
loadingProgressupdates re-renderProgressiveImagerepeatedly during a multi-MB load, which re-rendered the WebGL viewer on every tick. Fix:memothe viewer so progress ticks don't touch it — its props (src/dimensions) are stable until the image actually loads. Mount/unmount (the #510 destroy lifecycle) and a realsrcchange still re-touch it.Verification & follow-ups
tsc+eslintclean.-o.jpg+ CLS); ① (zoom) can't be exercised headless (no GPU / soft-nav intercept) — needs a real-device check that the continuous flicker is gone.PreviewImagere-render — memoizing slides/thumbnails would cut it). Both are follow-up polish; this PR targets the visible flicker.