Closed Bug 1513095 Opened 2 years ago Closed 2 years ago

Loading breakpoints is slow on pages with many scripts


(DevTools :: Debugger, defect, P2)

65 Branch


(firefox66 fixed)

Firefox 66
Tracking Status
firefox66 --- fixed


(Reporter: wartmanm, Assigned: wartmanm)


(Blocks 1 open bug)



(1 file)

User Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:65.0) Gecko/20100101 Firefox/65.0

Steps to reproduce:

The app I'm working on has about 250 scripts, which are not bundled at all in debug mode.  Loading pages with any breakpoints set takes several seconds longer.  I understand that I have a lot of scripts, but this still seems like too much time.

Actual results:

This is a fairly typical profile, with 5 breakpoints set:
It shows several seconds spent in Debugger::findScripts(), and GetScriptLineExtent() in particular.

Looking up the stack, it appears that _addSource() is called for every script, which calls _setBreakpointAtGeneratedLocation() for every breakpoint, which calls Debugger::findScripts(), which calls ScriptQuery::consider() for every script.  This would mean that loading breakpoints for the entire page takes quadratic time with respect to the number of scripts.

Expected results:

I think that the slowdown could be avoided by filtering breakpoints down to those that match the script passed to _addSource().  This wouldn't stop multiple breakpoints in the same file all calling findScripts() for that file, but it would stop them calling it for every single script.

This is more tentative, but I think the commonFilter check in consider() would benefit from being moved ahead of the line and possibly realm checks, as well.  The URL and source comparisons seem like they should be pretty cheap and would have a very low false-positive rate.
Component: Untriaged → Debugger
Product: Firefox → DevTools
Only attempt to add breakpoints for the current source in Thread._addSource(),
reducing the number of costly Debugger::findScripts() calls made when loading a

In addition, speed up findScripts() itself by moving the cheaper URL/source
checks in commonFilter() ahead of the line number checks.
I created a benchmark page that loads jquery 100 times:
In each of these profiles, I set a breakpoint on line 10347 of jquery number 100 and reloaded the page.

Here is the original:
1600ms is spent in _addSource, 31% of which is in consider().

In this one, commonFilter() is moved to the top:
1100ms is spent in _addSource, 1% of which is in consider().
I tested this without the _addSource change, because calling consider() 9900 fewer times would make the effect that much less noticeable.

Finally, this one has commonFilter() moved, and filtering added to _addSource():
700ms is spent in _addSource, almost all of which is spent in delazifying.
Thanks so much for the thorough investigation into all of this. This logic is definitely suboptimal at the moment, good find. If you're interested in contributing more, we have a Slack instance Devtools discussions:
Blocks: dbg-perf
Ever confirmed: true
Priority: -- → P2
Pushed by
Improve performance when loading breakpoints on pages with many scripts r=loganfsmyth
Closed: 2 years ago
Resolution: --- → FIXED
Target Milestone: --- → Firefox 66
Assignee: nobody → mattheww

Thanks again for this!

Thanks for this patch, this had a significant impact on DAMP:

== Change summary for alert #18687 (as of Thu, 10 Jan 2019 17:54:21 GMT) ==


6% damp custom.jsdebugger.pause.DAMP linux64 pgo e10s stylo 348.73 -> 327.91
5% damp custom.jsdebugger.pause.DAMP windows7-32 opt e10s stylo 402.41 -> 381.99
4% damp custom.jsdebugger.pause.DAMP windows10-64 opt e10s stylo 408.64 -> 390.40
4% damp custom.jsdebugger.pause.DAMP linux64 opt e10s stylo 400.30 -> 382.50
4% damp custom.jsdebugger.pause.DAMP windows10-64-qr opt e10s stylo 405.86 -> 388.15

For up to date results, see:

Depends on: 1530423
You need to log in before you can comment on or make changes to this bug.