Closed Bug 1399265 Opened 2 years ago Closed 2 years ago

Switching from "Raw Data" to "JSON" tab hangs

Categories

(DevTools :: JSON Viewer, defect)

56 Branch
defect
Not set

Tracking

(firefox-esr52 unaffected, firefox55 unaffected, firefox56 wontfix, firefox57 fixed, firefox58 fixed)

RESOLVED FIXED
Firefox 58
Tracking Status
firefox-esr52 --- unaffected
firefox55 --- unaffected
firefox56 --- wontfix
firefox57 --- fixed
firefox58 --- fixed

People

(Reporter: frank, Assigned: Oriol)

References

(Depends on 1 open bug)

Details

(Keywords: regression, Whiteboard: [qf])

Attachments

(1 file)

This can be easily verified in about:telemetry, viewing the Raw JSON data. First go to the "Raw Data" tab, then switch back to the "JSON" tab - it hangs for >40s for me.

Here is the profile: https://perfht.ml/2wnZH6p

Note: I've tested this on smaller JSON blobs, and it is definitely still present, though doesn't take quite as long (try Histograms.json, for example).
Product: Core → Toolkit
Whiteboard: [qf]
Sean, can you please take a quick look at the profile? Thanks!
Flags: needinfo?(sstangl)
The attached profile unfortunately doesn't have enough information, because the buffer was too small. I was able to reproduce the lag locally with a much larger buffer:

https://perfht.ml/2jDm2vw

That profile shows an 11,374ms pause in nsLineBox::RFindLineContaining(). It seems like we're hitting a pathological case during reflow. Olli, do you see anything meaningful in the callstack of that function?
Flags: needinfo?(bugs)
I'm not too familiar with reflow. -> dholbert
Flags: needinfo?(bugs) → needinfo?(dholbert)
So, it seems this is the JSON viewer doing something silly, which happens to trigger a slow case in Gecko.

In the STR, when you switch between views, the way our JSON viewer hides the current view is: it restyles it to have "height:0; width:0; visibility:hidden".  And so, Gecko dutifully tries to layout the content into that width.

Unfortunately, in this case, we have megabytes of text, all on a single line, with "white-space: pre-wrap".  And as it happens,  that's one of the things that triggers exponential layout of some sort, which I think is tracked in bug 643918.  I don't know enough about the linebreaking code in play here to know whether we can optimize it to avoid this blowup. (Maybe "width:0" might even be an edge case that we could add some special-case handling for?)

But I suspect the most direct way to avoid this would be for the JSON viewer to hide this content by styling it with "display:none", so that we actually get rid of it rather than trying to lay it out into a width:0 container.
Flags: needinfo?(dholbert)
(In reply to Daniel Holbert [:dholbert] from comment #4)
> But I suspect the most direct way to avoid this would be for the JSON viewer
> to hide this content by styling it with "display:none", so that we actually
> get rid of it rather than trying to lay it out into a width:0 container.

Moving to Toolkit::Telemetry in the hope that people who work on about:telemetry can look into this.
Component: General → Telemetry
Nothing to do with us, I'm afraid.

Passing to JSON viewer component: Anyone here have a cycle to spare to turn a width:0 height:0 into a display: none? Or half a cycle to point out the offending code?
Component: Telemetry → Developer Tools: JSON Viewer
Product: Toolkit → Firefox
(In reply to Chris H-C :chutten from comment #6)
> Passing to JSON viewer component: Anyone here have a cycle to spare to turn
> a width:0 height:0 into a display: none? 

Actually, the "width: 0" is really the problem here -- that's what triggers the slow relayout of the resized pane's contents.  And I *think* the page renders the same (but faster) without that -- the remaining "height:0;visibility:none" styles should probably be sufficient to hide the pane.

> Or half a cycle to point out the
> offending code?

I don't actually know what JS is responsible for making these tweaks -- I'm just using the DOM inspector and am observing it happening (the style attribute being manipulated).

As a "proof of concept", here's one extremely hacky solution:
 - Edit this file:
https://dxr.mozilla.org/mozilla-central/source/devtools/client/jsonview/css/json-panel.css
  ...to add the following rule:
   .hidden {  width: 100% !important; }

This overrides the problematic "width:0" that some JS sticks into the style attribute when hiding this pane.  This is probably not actually how we'd like to solve the problem, but it's maybe a good way to prototype whether that's sufficient.

This also works but is more overkill since it triggers frame destruction/reconstruction whenever we hide/show a pane:
  .hidden { display: none; }
Comment on attachment 8911556 [details]
Bug 1399265 - Avoid relayout when switching tab in devtools

https://reviewboard.mozilla.org/r/182988/#review188162

::: devtools/client/shared/components/tabs/tabs.js:334
(Diff revision 1)
> -          // than display:none and visibility:collapse.
> +          // destruction and reconstruction. 'width' is not changed to avoid relayout.
>            let style = {
>              visibility: selected ? "visible" : "hidden",
>              height: selected ? "100%" : "0",
> -            width: selected ? "100%" : "0",
>            };

The styles could also be moved to the stylesheet:
```css
.tab-panel-box.hidden {
  visibility: hidden;
  height: 0;
}
```
But maybe they are here to increase their specificity.
Assignee: nobody → oriol-bugzilla
Status: NEW → ASSIGNED
Comment on attachment 8911556 [details]
Bug 1399265 - Avoid relayout when switching tab in devtools

https://reviewboard.mozilla.org/r/182990/#review188246

Thanks for tracking down the code to fix! This makes sense to me conceptually -- but I don't know this code at all, so I probably shouldn't r+ any changes here.

Could you request review from someone who has touched this file before?  Maybe Jan Odvarko (:Honza) who has hg blame on this chunk of code that you're modifying?
Attachment #8911556 - Flags: review?(dholbert)
Flags: needinfo?(sstangl) → needinfo?(oriol-bugzilla)
Comment on attachment 8911556 [details]
Bug 1399265 - Avoid relayout when switching tab in devtools

https://reviewboard.mozilla.org/r/182990/#review188384
Attachment #8911556 - Flags: review?(odvarko)
Since it is a relayout problem I thought you would be more appropriate. Switched review to Honza.
Flags: needinfo?(oriol-bugzilla)
Comment on attachment 8911556 [details]
Bug 1399265 - Avoid relayout when switching tab in devtools

https://reviewboard.mozilla.org/r/182990/#review188768

Looks great to me, thanks Oriol!

Honza
Attachment #8911556 - Flags: review?(odvarko) → review+
Keywords: checkin-needed
Pushed by jodvarko@mozilla.com:
https://hg.mozilla.org/integration/autoland/rev/94a5ac215768
Avoid relayout when switching tab in devtools r=Honza
Keywords: checkin-needed
https://hg.mozilla.org/mozilla-central/rev/94a5ac215768
Status: ASSIGNED → RESOLVED
Closed: 2 years ago
Resolution: --- → FIXED
Target Milestone: --- → Firefox 58
Is this worth uplifting to firefox57?
Blocks: 1248380
Keywords: regression
Version: unspecified → 56 Branch
*Way* faster now, thanks for the fix!
Comment on attachment 8911556 [details]
Bug 1399265 - Avoid relayout when switching tab in devtools

Approval Request Comment
[Feature/Bug causing the regression]: n/a
[User impact if declined]: Performance not improved.
[Is this code covered by automated tests?]: -
[Has the fix been verified in Nightly?]: yes
[Needs manual test from QE? If yes, steps to reproduce]: no
[List of other uplifts needed for the feature/fix]: n/a
[Is the change risky?]: low risk (feature is for developers)
[Why is the change risky/not risky?]: only one line of css changed
[String changes made/needed]: n/a
Attachment #8911556 - Flags: approval-mozilla-beta?
Comment on attachment 8911556 [details]
Bug 1399265 - Avoid relayout when switching tab in devtools

Fix a regression, taking it.
Should be in 57b4
Attachment #8911556 - Flags: approval-mozilla-beta? → approval-mozilla-beta+
(In reply to Jan Honza Odvarko [:Honza] from comment #18)
> [Is this code covered by automated tests?]: -
> [Has the fix been verified in Nightly?]: yes
> [Needs manual test from QE? If yes, steps to reproduce]: no

Setting qe-verify- based on Honza's assessment on manual testing needs.
Flags: qe-verify-
Product: Firefox → DevTools
You need to log in before you can comment on or make changes to this bug.