Skip to content

Instantly share code, notes, and snippets.

@40thieves
Last active September 2, 2022 14:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save 40thieves/cd70d6af9045725cfebff6ec0b81854e to your computer and use it in GitHub Desktop.
Save 40thieves/cd70d6af9045725cfebff6ec0b81854e to your computer and use it in GitHub Desktop.
`matchBrackets` takes significant portion of doc change processing time

The matchBrackets function within @codemirror/language is run via the bracketMatchingState StateField whenever the doc or selection changes.

The following flamegraph was generated using this basic sandbox, modified from the default sandbox to extend the doc to 2000 lines:

no-throttling-img

See no-throttling-export.json for the exported flamegraph.

As you can see from this flamegraph, the matchBrackets function can take a significant portion of the update cycle, taking 5.21ms out of the 7.39ms dispatch cycle (70.5%).

The effect is magnified when throttling CPU by 6x:

6x-throttling-img

See 6x-throttling-export.json for the exported flamegraph.

Here, matchBrackets takes 24.17ms out of dispatch's 30.32ms (79.5%).

While investigating, I did find the maxScanDistance option, and tried setting that to a value much smaller than the default 10000. Unfortunately it appears that matchBrackets still takes a significant time to run. Here is another flamegraph generated using this modified sandbox which sets maxScanDistance to 100, and with CPU throttled by 6x:

max-scan-distance-img

See max-scan-distance-export.json for the exported flamegraph.

I can see that by itself, 5ms would not appear to cause a major performance problem, however we have found that this combined with our additional extensions does seem to cause "input lag", where input processing overflows into the next animation frame. We believe (and are confirming) that this occurs more commonly on lower end hardware.

Is it possible that the matchBrackets implementation could be optimised in some way? I've had a brief look at the code, and couldn't immediately come up with any suggestions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment