Problem Description
After implementing the recent JavaScript scaling fix #8 (using zoom and multiple setTimeout calls), I reported potential lag or jank when flipping cards, exclusively on low battery. The interface feels less responsive, and card transitions are sometimes delayed.
Root Cause Analysis
The latency is probably caused by excessive layout thrashing and forced reflows triggered by the scheduleBoardFit() function. Here's why:
-
Multiple Rapid Recalculations
The function calls fitChessBoardToScreen() up to 7 times (via setTimeout delays: 0ms, 50ms, 150ms, 400ms, 900ms, plus 3 additional calls after fonts.ready). Each call forces:
- DOM measurements (
getBoundingClientRect, clientHeight, etc.)
- Style recalculations (setting
zoom, resetting styles)
- Layout reflows (especially with
zoom changes)
-
Blocking the Main Thread
While each call is wrapped in requestAnimationFrame, the cumulative effect of running multiple measurements and style changes in quick succession can block the main thread, causing visible jank.
-
AnkiDroid's WebView Constraints
The embedded WebView in AnkiDroid has limited resources, especially on low battery. Excessive DOM operations during card transitions compete with Anki's own rendering cycle.
Proposed Solution
Replace the multi-call scheduleBoardFit() with a single, debounced execution that:
- Waits for fonts to load (if needed)
- Runs once after a short delay, or immediately (check if it works correctly)
Testing Instructions
-
Test with:
- Normal system font size (should feel snappy)
- Large system font size (board should scale without lag)
- Card flipping (answer buttons should respond immediately)
- Orientation changes (board should adjust smoothly)
-
Verify:
- No visual regression in board positioning
- Board still fits screen at large font sizes
- Performance matches/exceeds original (pre-fix) version
Problem Description
After implementing the recent JavaScript scaling fix #8 (using
zoomand multiplesetTimeoutcalls), I reported potential lag or jank when flipping cards, exclusively on low battery. The interface feels less responsive, and card transitions are sometimes delayed.Root Cause Analysis
The latency is probably caused by excessive layout thrashing and forced reflows triggered by the
scheduleBoardFit()function. Here's why:Multiple Rapid Recalculations
The function calls
fitChessBoardToScreen()up to 7 times (viasetTimeoutdelays: 0ms, 50ms, 150ms, 400ms, 900ms, plus 3 additional calls afterfonts.ready). Each call forces:getBoundingClientRect,clientHeight, etc.)zoom, resetting styles)zoomchanges)Blocking the Main Thread
While each call is wrapped in
requestAnimationFrame, the cumulative effect of running multiple measurements and style changes in quick succession can block the main thread, causing visible jank.AnkiDroid's WebView Constraints
The embedded WebView in AnkiDroid has limited resources, especially on low battery. Excessive DOM operations during card transitions compete with Anki's own rendering cycle.
Proposed Solution
Replace the multi-call
scheduleBoardFit()with a single, debounced execution that:Testing Instructions
Test with:
Verify: