Skip to content

Speed up viewer and frontend eslint: local cache + drop slow rule - #2586

Merged
hahn-kev merged 2 commits into
developfrom
viewer-lint-perf
Aug 24, 2026
Merged

Speed up viewer and frontend eslint: local cache + drop slow rule#2586
hahn-kev merged 2 commits into
developfrom
viewer-lint-perf

Conversation

@hahn-kev-bot

@hahn-kev-bot hahn-kev-bot commented Aug 20, 2026

Copy link
Copy Markdown
Collaborator

Improved linting performance with a local cache, and droped a rule in the viewer which I don't think was useful, but was quite slow.

Scenario Time
Cold, before (rule on, no cache) ~103s
Cold, after (rule dropped, cache being built) ~65s
Warm (cache hit, unchanged files) ~3.5s

most of the time taken by linting in the frontend is a rule checking that we're awaiting promises, instead of using them as a value, eg if (promise) instead of if (await promise) but that's a very useful rule to I left it on. It's got caching locally now, but a cold run is still slow.


🤖 AI summary

frontend/viewer (and to a lesser extent frontend) lint was slow. Profiling with TIMING showed the cost was concentrated in a few type-aware rules plus a full TypeScript program build, not eslint itself.

Changes

  • Drop @typescript-eslint/no-duplicate-type-constituents (both packages). In the viewer it was ~60% of rule time (~15s) and flagged nothing — it does expensive type-relation checks against our large generated dotnet-types unions. (In frontend its cost is negligible; dropped there only for parity.)
  • Enable eslint --cache on the local lint script in both packages, and gitignore .eslintcache. Warm re-runs only re-lint changed files.
  • frontend only: enabling --cache required removing the explicit svelteConfig pass in parserOptions — it embedded svelte.config.js's warningFilter/onwarn functions into the eslint config, which eslint can't serialize for its cache. svelte-eslint-parser auto-loads svelte.config.js from disk instead, so the compile-warning filter still applies (verified: no element_invalid_self_closing_tag warnings leak back, same problem count).

Viewer timings (measured back-to-back, same machine state)

Scenario Time
Cold, before (rule on, no cache) ~103s
Cold, after (rule dropped, cache being built) ~65s
Warm (cache hit, unchanged files) ~3.5s

Warm re-runs are consistently 3–4s — this is the everyday local iteration case. Cold absolute times vary with machine load.

Deliberately NOT done: CI caching. ESLint's file cache keys on each file's own mtime/content and does not track cross-file type dependencies. Verified empirically: change a type in file A, leave an importing file B untouched, and a cached run misses the real no-floating-promises error in B — under both metadata and content cache strategies. So caching stays off in CI (lint:report) to keep the type-aware gate sound; caching is local-only.

Deliberately NOT changed: no-misused-promises. It dominates frontend lint time (~80%), but it's a valuable rule (catches async handlers passed where void is expected). Tuning checksVoidReturn.attributes: false and switching to projectService were both measured and neither reduced its cost, so it's left as-is — local caching already removes the day-to-day pain.

Test plan

  • pnpm run lint in both frontend/viewer and frontend reports the same problem counts as before the change (viewer 14, frontend 8).
  • Warm lint re-run (no file edits) completes in ~3–4s in both packages.
  • frontend: confirmed no element_invalid_self_closing_tag compile warnings leak back after dropping the explicit svelteConfig pass.
  • CI (lint:report) is unchanged and remains uncached.

hahn-kev and others added 2 commits August 20, 2026 11:27
The viewer's `lint` was ~73s cold. TIMING=25 profiling showed a single
type-aware rule, @typescript-eslint/no-duplicate-type-constituents,
consumed ~60% of rule time (~15s) while flagging nothing in this codebase
— it does expensive type-relation checks against our large generated
dotnet-types unions. Disable it.

Also enable `--cache` on the local `lint` script (73s -> ~3.5s on warm
re-runs) and gitignore .eslintcache. Caching is deliberately NOT applied
to CI (`lint:report`): ESLint's file cache keys on each file's own
mtime/content and does not track cross-file type dependencies, so a
change in one file leaves a stale cached result for an unchanged importer
— verified that both metadata and content cache strategies miss a real
no-floating-promises error introduced via a dependency change. CI stays
uncached so the type-aware gate remains sound.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Apply the same lint-perf learnings from the viewer package to the LexBox
web app. Enable `--cache` on the local `lint` script (~105s -> ~3s on warm
re-runs) and gitignore .eslintcache.

Enabling --cache required removing the explicit `svelteConfig` pass in
parserOptions: it embedded svelte.config.js's warningFilter/onwarn
functions into the ESLint config, which ESLint cannot serialize for its
cache. svelte-eslint-parser auto-loads svelte.config.js from disk instead,
so the compile-warning filter still applies (verified: no
element_invalid_self_closing_tag warnings leak back, same 8 problems).

Also disable @typescript-eslint/no-duplicate-type-constituents for parity
with the viewer. As with the viewer, caching stays off in CI (lint:report)
because ESLint's file cache does not track cross-file type dependencies.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@github-actions github-actions Bot added 💻 FW Lite issues related to the fw lite application, not miniLcm or crdt related 📦 Lexbox issues related to any server side code, fw-headless included labels Aug 20, 2026
@coderabbitai

coderabbitai Bot commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: a306661c-f91f-44bf-abab-23eaf124150e


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@hahn-kev hahn-kev added the self-reviewed 👁️ I reviewed this myself and with AI and decided it was safe to merge without a second set of eyes label Aug 20, 2026
@argos-ci

argos-ci Bot commented Aug 20, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Argos notifications ↗︎

Build Status Details Updated (UTC)
default (Inspect) ✅ No changes detected - Aug 20, 2026, 5:04 AM
e2e (Inspect) ✅ No changes detected - Aug 20, 2026, 5:11 AM

@hahn-kev
hahn-kev merged commit abfd414 into develop Aug 24, 2026
32 checks passed
@hahn-kev
hahn-kev deleted the viewer-lint-perf branch August 24, 2026 03:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

💻 FW Lite issues related to the fw lite application, not miniLcm or crdt related 📦 Lexbox issues related to any server side code, fw-headless included self-reviewed 👁️ I reviewed this myself and with AI and decided it was safe to merge without a second set of eyes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants