mirror of
https://github.com/zadam/trilium.git
synced 2026-09-12 19:50:20 +05:00
docs(claude): carry the live-inspection recipes into the skills
Both were only in the auto-memory store, where they are recalled by relevance rather than read when the matching skill loads. measure-startup-requests gains the counterpart to its login-based capture: timing one module graph by importing it straight off the dev server, which needs no session. The `.catch` on that import is the whole trick — an ES graph is fetched and instantiated before any of it is evaluated, so a module that throws for want of a session still gives a valid number. The CKEditor figures are kept as the worked example, since they are what identified the module graph rather than `editor.create()` as the "first text note is slow" cost. inspecting-the-running-app gains the `window.glob.appContext` summoning tip, the NixOS system-chromium executablePath (its downloaded browsers fail on libX11), a Linux port kill next to the PowerShell one, and the pitfall that once produced a wrong diagnosis: an async re-render between the evaluate() that reads computed styles and the screenshot() can wipe the state being studied, which reads as the CSS never having painted. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
437c37d374
commit
b92cd6c453
@ -31,17 +31,28 @@ Use Playwright imported by **absolute path**
|
||||
(`file:///…/node_modules/playwright/index.mjs`) — a script written into the scratchpad cannot
|
||||
resolve `playwright` by name.
|
||||
|
||||
`window.glob` is exposed, so most UI can be summoned without clicking through to it:
|
||||
`glob.appContext.triggerCommand("showOptions")`, `"openInTreePopup"` (with
|
||||
`{ noteIdOrPath, hoistedNoteId }`), `"showDeleteNotesDialog"`, …, and `glob.froca` for note lookups.
|
||||
|
||||
Fixture gotchas:
|
||||
|
||||
- It opens on a **protected** note, so click another note first.
|
||||
- It runs the **new layout**, so there is no ribbon — the attributes editor opens from the
|
||||
`… attributes` button in `.status-bar`.
|
||||
- **On NixOS, Playwright's downloaded browsers fail on libX11.** Launch the system one instead:
|
||||
`chromium.launch({ executablePath: "/etc/profiles/per-user/<user>/bin/chromium" })` — the same
|
||||
trick as the untracked `apps/server/playwright.config.nixos.ts`.
|
||||
|
||||
## Stopping it
|
||||
|
||||
Killing the backgrounded `npx tsx` wrapper leaves the node child alive and still holding the port,
|
||||
so the next boot fails with "Port 37999 is already in use". Kill the listener:
|
||||
|
||||
```bash
|
||||
fuser -k 37999/tcp # Linux; or: ss -tlnp 'sport = :37999' to find the pid first
|
||||
```
|
||||
|
||||
```powershell
|
||||
Get-NetTCPConnection -LocalPort 37999 -State Listen | % { Stop-Process -Id $_.OwningProcess -Force }
|
||||
```
|
||||
@ -57,3 +68,9 @@ Get-NetTCPConnection -LocalPort 37999 -State Listen | % { Stop-Process -Id $_.Ow
|
||||
- **A mispositioned or self-dimming fixed-position menu** — walk the ancestors for `transform`,
|
||||
`filter` and `container-type` rather than reading the stylesheets; any of them creates a
|
||||
containing block and a stacking context (see "Dropdown menus and the backdrop blur" in `SKILL.md`).
|
||||
|
||||
**Transient state can vanish between reading it and screenshotting it.** An async re-render between
|
||||
the `evaluate()` that dumps computed styles and the later `screenshot()` can wipe the state you are
|
||||
studying (`fancytree-active`, a hover class, an open menu), which reads as "the CSS never painted"
|
||||
and has produced a wrong diagnosis before. Re-assert the state *at screenshot time*, and pixel-sample
|
||||
with `pngjs` (available through the e2e require) rather than eyeballing the image.
|
||||
|
||||
@ -37,6 +37,27 @@ node .claude/skills/measure-startup-requests/analyze-requests.mjs diff <before.j
|
||||
3. Capture again and compare: `analyze-requests.mjs diff baseline.json after.json`.
|
||||
4. `probe` confirms specific heavy deps stayed off the boot path.
|
||||
|
||||
## Timing one module graph, without logging in
|
||||
|
||||
The capture above needs a session. To weigh a *single* entry point instead — "what does reaching
|
||||
CKEditor actually cost?" — skip the login entirely: Vite serves module URLs unauthenticated.
|
||||
|
||||
- URL form: `http://localhost:8080/assets/v<version>/@fs/<absolute repo path>/…/file.ts`.
|
||||
- Navigate a blank page to that origin, `setContent("<html><body>")`, then take `performance.now()`
|
||||
around `await import(url).catch(() => {})`.
|
||||
- **The `.catch` is what makes this work.** An ES module graph is fully fetched and instantiated
|
||||
before any of it is evaluated, so a module whose *evaluation* throws without a session ("Logged in
|
||||
session not found") still yields a valid download-and-instantiate measurement.
|
||||
- Constructing an editor in that page needs `{ licenseKey: "GPL" }`, or `create()` throws
|
||||
`license-key-missing`.
|
||||
|
||||
This is how the "first text note is slow" delay was attributed to the module graph rather than to
|
||||
the editor (dev server, 2026-08): `packages/ckeditor5/src/index.ts` ~290 ms / 216 modules and
|
||||
`EditableText.tsx` ~355 ms / 328 modules, against `PopupEditor.create()` at 83 ms first and ~25 ms
|
||||
after. That is why the idle preload (`preloadCommonNoteTypes` in `note_types.tsx`) is the lever —
|
||||
and why the 428 KB emoji `definitionsUrl` fetch is not a suspect: `EmojiRepository.init()` fires it
|
||||
without returning the promise, so it never blocks `create()`.
|
||||
|
||||
## Interpreting results
|
||||
|
||||
- **Dev-mode numbers, not production.** The dev server serves unbundled ES modules (~500+ script
|
||||
|
||||
Loading…
Reference in New Issue
Block a user