Open Bug 667412 Opened 13 years ago Updated 2 years ago

Loading lots of text in a narrow textarea is very slow

Categories

(Core :: Layout: Block and Inline, defect)

x86
Linux
defect

Tracking

()

People

(Reporter: smontagu, Unassigned)

References

(Depends on 2 open bugs)

Details

(Keywords: perf)

Attachments

(1 file)

Attached file Testcase
I encountered this when trying to assess performance with the patch for bug 664087, and also whether recent bidi performance work has fixed bug 376359, but this is not a bidi issue -- this version of the testcase is LTR text only and still shows the problem.

In a profile of loading the testcase, 77.4% is spent in nsLineBox::RFindLineContaining, called from nsBlockFrame::AddFrames. Apparently we are hitting the "less common" case referred to in the comment there:

    // XXX_perf This is technically O(N^2) in some cases, but by using
    // RFind instead of Find, we make it O(N) in the most common case,
    // which is appending content.
Ah, this is an interesting case.  So the point here is that the textarea has tons of lines and that some of them are longer than the textarea width.  Each such line causes us to wrap and create a continuation, and then we have to find the right line to put that continuation in.  And we do the search in reverse, but the continuations are inserted all over, so it ends up being O(N^2).  Messing with the search order would not help here, of course.

fantasai, do you think we can try to do better here after the split?  If so, we should add a dep.
Component: Layout → Layout: Block and Inline
QA Contact: layout → layout.block-and-inline
Summary: Loading lots of text in a textarea is very slow → Loading lots of text in a narrow textarea is very slow
What I was thinking was that when we call InsertFrames from nsTextFrame::SetLength we already know the line (at least some of the time), so maybe we could pass it in and avoid the search?
We could try...

This seems like a situation that would be helped by something like a line cursor, actually: during reflow, search forward from the line currently being reflowed.
Passing in the line helps some, but it leaves us spending 44% of the time in nsLineBox::IndexOf, called from BuildTextRuns via the nsBlockInFlowLineIterator ctor.
Component: Layout: Block and Inline → Layout
Component: Layout → Layout: Block and Inline
I doubt the split would make a difference in what we can do here.
OK.  Do we have existing bugs on making it possible to add kids to a block without finding the right line?  I seem to recall some proposals about that...
Blocks: 680461
No longer blocks: 680461
This might be the same issue as bug 561578.
Depends on: 561578
Or more precisely, the underlying problem is the same: bug 190147.
Depends on: 190147
Depends on: 682052
A much shorter yet reproducible testcase on any textarea (not specially narrow) seems to be Github's stylesheet ( https://a248.e.akamai.net/assets.github.com/stylesheets/bundle_github.css - 'only' 300kB with very long lines).
The key part for this bug is that the textarea be narrow compared to the width of a typical line so there are lots of continuations being created.
As far as I can tell, fixing bug 682052 is the only way that this will ever be fixed, right?
That's the only way this will get _closer_ to being fixed.  Once we fix that, we might find another hotspot.  :(
Current Gecko Profiler trace says 76% in nsLineBox::RFindLineContaining() (no surprise), and 17% in nsTextFrame::LastInFlow(), and 2% in BuildTextRuns()
Severity: normal → S3
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: