Skip to content

[Performance] Cache compiled glob matchers in matchGlob - #8539

Draft
github-actions[bot] wants to merge 1 commit into
mainfrom
performance-maintenance-34852179334
Draft

github-actions[bot] wants to merge 1 commit into
mainfrom
performance-maintenance-34852179334

Conversation

@github-actions

Copy link
Copy Markdown
Contributor

WHY are these changes introduced?

matchGlob in packages/cli-kit/src/public/node/fs.ts delegated to minimatch(key, pattern, options), and that helper parses the pattern into a new Minimatch instance on every single call.

The callers all match the same small set of patterns against a large set of paths, so the pattern parsing — not the matching — dominates the cost:

  • applyIgnoreFilters (packages/theme/src/cli/utilities/asset-ignore.ts:46) runs over every file of a theme, on theme push, theme pull, reconciliation, and remote polling.
  • theme-fs.ts:107 calls it per file-watcher event during theme dev.
  • The app file watcher (file-watcher.ts:245,325-326) and config-selection.ts:88,112,138 match every event/path against their pattern lists.

WHAT is this pull request doing?

Cache the compiled Minimatch instances by pattern and options, and reuse them. Minimatch instances are stateless across match() calls, so results are unchanged — only the redundant re-parsing goes away.

Measured on a synthetic 3000-file theme against 5 ignore patterns, comparing the old and new implementations in the same process (both keep an identical 2300 files):

before after
full ignore-filter sweep (3000 files × 5 patterns) 52.15 ms 2.16 ms (~24x)
single file-watcher event (1 file × 5 patterns) 20.04 µs 0.78 µs (~26x)

Added matchGlob unit tests, which had none before, covering matching, repeated use of a cached pattern, per-options cache separation, and the comment-pattern (#…) short-circuit that minimatch() handled explicitly.

How to manually test your changes?

shopify theme dev
shopify theme push
shopify app dev

Ignore patterns in .shopifyignore and --ignore / --only flags should behave exactly as before, with faster filtering on large themes.

Checklist

  • I've considered possible cross-platform impacts (Mac, Linux, Windows)
  • I've considered possible documentation changes
  • I've considered analytics changes to measure impact
  • The change is user-facing — I've identified the correct bump type (patch for bug fixes · minor for new features · major for breaking changes) and added a changeset with pnpm changeset add

minimatch() parses the pattern into a new Minimatch instance on every
call. Since the same handful of patterns is matched against thousands of
paths (theme ignore filters run over every file of a theme, the app file
watcher over every event), that parsing dominates the cost.

Compiled matchers are stateless, so they can be cached by pattern and
options and reused.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants