Lower devicePixelRatio cap from 3 to 2 - #164
Closed
philips-clanker wants to merge 1 commit into
Closed
Conversation
Requested on issue #154 after real profiling: a SupernoteView note measured 900MB+ heap usage, vs. 108MB for the same content already exported to plain markdown + image attachments. #163's zoom-aware raster scale doesn't help here - confirmed by computing its formula against realistic values, it produces no reduction at all at a typical fit-width zoom on a 3x-DPR device (an iPhone, the device in this report), since high-DPI crispness at that zoom genuinely wants close to full native resolution. Backing-store memory scales with the *square* of devicePixelRatio (it sizes both width and height), so this cap matters far more than it looks like at a glance: capping at 3 meant a currently-loaded page's backing store could be up to 9x its CSS-displayed pixel count. Lowering to 2 cuts that to 4x - a ~56% reduction in backing-store memory for every currently-loaded page on any 3x-DPR device, at any zoom level, unlike the zoom-aware scale. 2 is a deliberate middle ground, not the theoretical minimum: capping at 1 (no supersampling at all) would cut memory further still (~11% of original vs. ~44% at a cap of 2) but visibly reintroduces the "chunky artifacts on a high-DPR screen" this whole DPR-aware rendering scheme exists to avoid - see drawPageImage()'s own history. 2 still supersamples enough for legible handwriting on typical high-DPI phones/tablets while meaningfully bounding memory. Extracted into a named MAX_DEVICE_PIXEL_RATIO constant rather than an inline literal, so it's one obvious place to revisit if 900MB-ish usage is still too much even at this cap.
This was referenced Jul 31, 2026
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.
Summary
Requested on #154 after real profiling: a
SupernoteViewnote measured 900MB+ heap usage, vs. 108MB for the same content already exported to plain markdown + image attachments. #163's zoom-aware raster scale doesn't help here - confirmed by computing its formula against realistic values, it produces no reduction at all at a typical fit-width zoom on a 3x-DPR device (an iPhone, the device in this report), since high-DPI crispness at that zoom genuinely wants close to full native resolution.Change
Backing-store memory scales with the square of
devicePixelRatio(it sizes both width and height), so this cap matters far more than it looks like at a glance:Lowering to 2 gives a ~56% reduction in backing-store memory for every currently-loaded page on any 3x-DPR device, at any zoom level - unlike #163, which only helps at lower DPR or more extreme zoom-out.
2 is a deliberate middle ground, not the theoretical minimum - capping at 1 would cut memory further (~11% of original) but visibly reintroduces the "chunky artifacts on a high-DPR screen" this whole DPR-aware rendering scheme exists to avoid in the first place. 2 still supersamples enough for legible handwriting on typical high-DPI phones/tablets while meaningfully bounding memory.
Extracted into a named
MAX_DEVICE_PIXEL_RATIOconstant rather than an inline literal, so it's one obvious place to revisit if 900MB-ish usage is still too much even at this cap.Trade-off to be aware of
This is a real quality trade-off: handwriting/strokes will render at 2x supersampling instead of 3x on the highest-DPI devices, which may be perceptibly (if subtly) less crisp on close inspection. Flagging this explicitly since it's a deliberate choice, not a bug - if it's not an acceptable trade-off, the alternative is living with the higher memory usage (or pursuing more invasive lazy-rendering strategies).
What I could not verify
Same caveat as the rest of this issue's PRs: no Obsidian/Electron/X server in my environment, so I can't confirm the actual resulting heap usage or judge the visual quality trade-off myself. Please re-measure heap usage the same way you did before (900MB+) and compare, and judge whether the slightly-reduced supersampling is noticeable/acceptable on your device.
Test plan
npx tsc --noEmit- cleannpx eslint src/main.ts- 0 errorsnpx vitest run- 95 passednpm run build- clean