Web speed improvements for issue 327 (rebased) #515

Closed
kayg wants to merge 0 commits from issue/327-web-fast-2 into dev
Owner

Replaces PR #508. Rebased the web speed work onto dev at 74336c9 and kept the current links fix from PR #513 / issue #448. The stale-list guard now applies to the first list page, worker fill pages, recent refreshes, and the saved list. The worker fill callback uses the since tick captured when loadNotes began.

Checks

Svelte check:

svelte-check found 0 errors and 12 warnings in 7 files

Editor unit tests:

Test Files 18 passed (18)
Tests 135 passed (135)

The full web E2E suite was run as broad coverage for this PR. The PR adds perf specs rather than E2E files:

Chromium 1440
508 skipped
169 passed (11.9m)

WebKit 1440
511 skipped
166 passed (23.4m)

The first full Chromium 390 run had a stale-list test setup race. The notes.list response completed before the route was installed; the fixture now installs the route before reloading. The old run summary was:

1 failed
78 skipped
598 passed (33.1m)

The four requested E2E specs then ran on Chromium 1440, WebKit 1440, and Chromium 390. The stale-list regression passed in all three projects. The multi-project run had two WebKit Trash click stability timeouts while another WebKit run was active on the shared host:

2 failed
10 skipped
78 passed (11.2m)

The isolated WebKit 1440 Trash spec passed all three tests, including both timed out cases:

3 passed (37.0s)

100k boot performance

Same perf VM, fixture, and server binary; three cold runs on each build:

web.chromium.boot.cold_tbt ms {"n":3,"p50":22506.4,"p95":24967.4,"max":24967.4}
web.chromium.boot.cold_tbt ms {"n":3,"p50":369,"p95":408.5,"max":408.5}

The VM has Node 22.11, which cannot load the perf config's top-level await. I used a temporary runner in a unique VM scratch directory for the same boot test. The copied config was restored and the runner was removed; the repository config is unchanged.

Replaces PR #508. Rebased the web speed work onto dev at 74336c9 and kept the current links fix from PR #513 / issue #448. The stale-list guard now applies to the first list page, worker fill pages, recent refreshes, and the saved list. The worker fill callback uses the `since` tick captured when `loadNotes` began. ## Checks Svelte check: ```text svelte-check found 0 errors and 12 warnings in 7 files ``` Editor unit tests: ```text Test Files 18 passed (18) Tests 135 passed (135) ``` The full web E2E suite was run as broad coverage for this PR. The PR adds perf specs rather than E2E files: ```text Chromium 1440 508 skipped 169 passed (11.9m) WebKit 1440 511 skipped 166 passed (23.4m) ``` The first full Chromium 390 run had a stale-list test setup race. The `notes.list` response completed before the route was installed; the fixture now installs the route before reloading. The old run summary was: ```text 1 failed 78 skipped 598 passed (33.1m) ``` The four requested E2E specs then ran on Chromium 1440, WebKit 1440, and Chromium 390. The stale-list regression passed in all three projects. The multi-project run had two WebKit Trash click stability timeouts while another WebKit run was active on the shared host: ```text 2 failed 10 skipped 78 passed (11.2m) ``` The isolated WebKit 1440 Trash spec passed all three tests, including both timed out cases: ```text 3 passed (37.0s) ``` ## 100k boot performance Same perf VM, fixture, and server binary; three cold runs on each build: ```text web.chromium.boot.cold_tbt ms {"n":3,"p50":22506.4,"p95":24967.4,"max":24967.4} web.chromium.boot.cold_tbt ms {"n":3,"p50":369,"p95":408.5,"max":408.5} ``` The VM has Node 22.11, which cannot load the perf config's top-level await. I used a temporary runner in a unique VM scratch directory for the same boot test. The copied config was restored and the runner was removed; the repository config is unchanged.
kayg added 14 commits 2026-10-16 23:10:27 +00:00
perf/web.sh measures the built app as production serves it on 10k and 100k
fixture Homes, Chromium (CPU 4x) and WebKit: bundle sizes, boot (TBT as
web.dev defines it, every long task, first paint, time to interactive),
keystroke to paint, the blaze test (#271), scrolling, memory, layout shift
and main-thread CPU. web.* budgets in perf/budgets.json; CI gates the
bundle sizes. docs/perf/web.md.

Replaces #360.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018Yyy8fQGxPLkLa8v8NXz7T
- frontmatterEnd walks lines without copying and remembers per document.
- The note metadata keeps `base` under its own key, written only when it
  changed (older records still read).
- A preview whose text matches the live document swaps its binding in
  place (a compartment) instead of building and parsing a new state.
- Clouds worked out in slices (lib/slices.ts), date labels morph only once
  tapped, the offline merge code loads only when a merge runs.

Replaces #402 and part of #454.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018Yyy8fQGxPLkLa8v8NXz7T
- lib/notes-index.ts: notes newest first by binary search, tag counts,
  file to id, the Journal's order; views are told once per batch.
- groups() slices ordered lists by binary search; NoteList works out its
  visible rows from group sizes (lib/list-window.ts). Nothing walks every
  note on the main thread.
- The background fill (#422, pages of 2000) is fetched and parsed in a
  worker (lib/notes-fill.worker.ts) and handed over 250 notes at a time;
  without a worker, pages of 500 the plain way.
- The first note's text comes over plain HTTP (notes.peek) when nothing is
  remembered, instead of waiting for its room; peeks come 12 at a time.
- Typing: properties re-read only when an edit reaches them, the bar's
  block list replaced only when it held something.
- Theme colour once per frame; the Settings bar builds at the next idle.

Replaces #394, #407 and the rest of #454.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018Yyy8fQGxPLkLa8v8NXz7T
Fill pages are fetched by a worker now, whose requests the page doesn't
always see: the app marks html[data-listed] when the whole list is in, and
the harness waits for it (builds without the fill worker: request silence).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018Yyy8fQGxPLkLa8v8NXz7T
Test stale note lists deterministically
Some checks failed
CI / server (pull_request) Successful in 26s
CI / rust (pull_request) Failing after 2m4s
CI / web (pull_request) Failing after 47s
3c2c2bc040
Author
Owner

Superseded by replacement PR #518: #518. The fixes and verification for issue #327 are on issue/327-web-fast-3 at f20c348e2928fae38470dd743c863fd231bc8568. Closing this PR as requested.

Superseded by replacement PR #518: https://git.kayg.org/kayg/calternal/pulls/518. The fixes and verification for issue #327 are on `issue/327-web-fast-3` at `f20c348e2928fae38470dd743c863fd231bc8568`. Closing this PR as requested.
kayg closed this pull request 2026-10-17 02:24:21 +00:00
Some checks failed
CI / server (pull_request) Successful in 26s
CI / rust (pull_request) Failing after 2m4s
CI / web (pull_request) Failing after 47s

Pull request closed

Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
kayg/calternal!515
No description provided.