perf: reduce ValidScopedCSSClass save latency on large themes#1181
Draft
perf: reduce ValidScopedCSSClass save latency on large themes#1181
Conversation
Two changes that together drop the LSP save latency introduced by
ValidScopedCSSClass from ~4.5s to <500ms on large themes after the
first save of a session.
1. Session-scoped CSS class cache in runChecks
Before, every save tore down the getCSSClassesForURI memoization and
re-parsed every .liquid file with a {% stylesheet %} tag to rebuild
the theme-wide class set. Now the Map<uri, Promise<Set<string>>>
lives at makeRunChecks scope. When a save fires, the saved URI is
evicted from the cache; every other entry stays warm. First save
pays the full scan; subsequent saves re-parse one file.
2. Substring short-circuit in extractCSSClassesFromLiquidUri
Skip toLiquidHtmlAST entirely when source contains no
'{% stylesheet'. On Horizon (240 liquid files, 128 with stylesheet
tags) this skips ~47% of parses on the first scan. Also helps the
CLI: ~19.2s → ~17.4s on Horizon.
Also adds [theme-check] timing logs in runChecks for profiling.
7514d8f to
ddd51bf
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes the save-lag reported in #1179. On larger themes, saving a file caused VS Code to hang for several seconds on "Getting code actions from 'Shopify Liquid'". This PR brings the post-first-save latency back into the sub-second range.
What was happening
The
ValidScopedCSSClasscheck decides whether a CSS class used in a class attribute is defined somewhere the current file can see. To answer that, it needs to know which classes are declared across the theme — in the file itself, in its ancestors, in the snippets it renders (transitively), and in the CSS assets.The language server runs this logic from scratch on every save. It doesn't just re-check the file the user edited — it also re-reads and re-parses every Liquid file in the theme that could contribute CSS classes, to rebuild the "every class declared anywhere" set it uses as a filter. For a large theme that is roughly a hundred full syntax-tree parses on every keystroke save. Nothing was cached between saves, even though the overwhelming majority of files haven't changed.
What this PR changes
Two architectural changes to the language-server pipeline, nothing user-facing:
Session-scoped cache for per-file CSS class extraction. The mapping from file → set of classes it declares is now built once per language-server session and kept alive across saves. When the user saves a file, only that file's entry is invalidated; everything else stays warm. The first save of a session still pays the full scan, but every subsequent save only re-parses the single file that changed.
Early exit for files that can't contribute classes. A large portion of Liquid files have no
stylesheettag at all and therefore cannot declare any CSS classes. We now detect that with a cheap substring check on the raw source and skip the full parse entirely for those files. This helps the cold path (first save, CLI runs).The check's logic, its output, and its public API are all unchanged.
Impact
(Measured on a 240-file theme locally.)
Companion work
recommendedconfig as an immediate unblock for users on the released version. Once this PR ships, that change can be reverted and the check put back inrecommended.Draft notes
[theme-check]are included in this draft for reviewers to validate on their own themes. They will be removed before this PR is marked ready for review.Test plan
main, subsequent saves are sub-second{% stylesheet %}content, save, confirm that file's ancestors see the new class immediately (no stale cache)yarn test🤖 Generated with Claude Code