Skip to content

Lower devicePixelRatio cap from 3 to 2 - #164

Closed
philips-clanker wants to merge 1 commit into
mainfrom
cap-devicepixelratio-issue-154
Closed

Lower devicePixelRatio cap from 3 to 2#164
philips-clanker wants to merge 1 commit into
mainfrom
cap-devicepixelratio-issue-154

Conversation

@philips-clanker

Copy link
Copy Markdown
Collaborator

Summary

Requested on #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.

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:

Cap Backing-store area vs. current (3x)
3 (current) 100%
2 (this PR) 44.4%
1 11.1%

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_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.

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 - clean
  • npx eslint src/main.ts - 0 errors
  • npx vitest run - 95 passed
  • npm run build - clean
  • Computed the backing-store area reduction at each candidate cap value
  • Manual: re-measure heap usage opening the same note that showed 900MB+
  • Manual: visually confirm handwriting/strokes are still acceptably crisp at 2x on a high-DPI device

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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants