"Making Code Lens fast on a 3,000-file repo: 18 s to 5.9 s setup, 4 s to under 0.8 s per match"
Code Lens matches the text you select on screen against a map of your Project's code, then labels each component with its file and line. On the small apps in our benchmarks, a match takes about 220 ms. On a 2,986-file repository, 22 MB of source with 363 page trees, the first Lens or X-ray froze Bigshot for about 22 seconds, and every one after that for 2 to 4 seconds. The pointer turned into the spinning wheel and the app stopped drawing.
Bigshot 1.7.6 fixes it. These are the numbers on that repository, before and after:
| Before | After | |
|---|---|---|
| Matcher setup, first lens | 18.1 s, app frozen | 5.9 s, in the background |
| Match, 20 to 45 lines of text | 1.9 to 3.8 s, app frozen | 0.14 to 0.73 s, in the background |
| Peak memory | 1.5 GB | 1.2 GB |
The matches are the same. Results were byte-identical on six sets of screen lines, and the Lens corpus of 20 stacks still scores 482 of 587 lines with no false positives.
Why it froze
The Code map is a SQLite index on your Mac. Before a match, Bigshot loads it into a matcher: every string in the code that could appear on screen, split into normalised segments, with where each one is used. Then it looks for the longest runs of screen text that match a segment.
Both steps ran on the main thread. The service that owns the Code map was a main-actor class, so loading the matcher and matching a selection ran where the app draws its windows. Indexing rebuilt the matcher on the main thread too. On a 600-file repo setup takes about 3 seconds and a match about 50 ms, which went unnoticed. On five times the files, with many more translation keys and data strings, it didn't.
What changed
- Load and match in the background. The matcher is built and queried off the main thread. The app keeps drawing, the lens shows its loading card, and if you change the selection before a result lands, the old result is dropped.
- Warm the matcher early. It starts loading when a lens opens, while you are still dragging out the selection, and again right after the Code map is indexed. Most of the 5.9 s now passes before you let go.
- Build segments on every core. Normalising the strings was a single loop. It now runs in parallel.
- Find short runs through a word index. The longest-match step scanned every segment for each line of screen text. A word index now finds the candidate segments directly, which took a match from seconds to under a second.
What is still slow
5.9 seconds is still a long setup, and 1.2 GB is a lot of memory for a matcher. We don't load it when Bigshot starts, because most launches never open a lens and that memory would be held for nothing. The next step is to store the normalised segments in the index itself, so setup becomes a plain load from disk and memory drops with it.
If Code Lens is slow on your repository, update to 1.7.6.
More from the blog
"Code Lens X-ray: see the line of code behind each line on screen"
X-ray in Bigshot's Code Lens replaces the text under a loupe with the source line that shows it, and draws how the page's components, lists and translation files connect. How it works, what it gets wrong, and what it gives a coding agent.
Make a moodboard while you browse, then have Claude Code build from it
Tag the parts of websites you like as you capture them in Bigshot, then ask Claude Code to use the tag. A real run with ten captures from patch.io and cursor.com/compile, one prompt and a restyled homepage.
How accurate is Code Lens? 587 screen lines across 20 frameworks and app setups
We tested 587 screen lines across 20 small fixture apps. Code Lens finds the render site within one line for 82% of them, against 34% for literal repository search. We also tested whether EmbeddingGemma 2 improves that.