[posted to four newsgroups, followups set to netscape.public.mozilla.performance] Mail Reply Performance Status A couple of weeks ago I made a patch to the editor to streamline mail reply performance as much as possible. The patch for this is attached to bug 35295. This note summarizes performance with this patch. Mail Reply performance has been slow in mozilla for a few reasons. One of the main ones is that when mail compose creates the compose window, it depended on the editor to insert the quoted mail reply. Inside the editor this went through the same code path as any other html paste. HTML paste in the editor is complicated. A lot of work is done that may not be needed when inserting a mail reply. My patch creates a separate, simplified code path for insert html in situations where you don't want this additional work, and makes InsertCitedQuotation() use this simpler code path. Summary for Those Who Don't Want To Read All This >31 seconds to respond to a 4000 line message (text + breaks). 7 seconds from mail creating an editor to when it hands off the quote to editor 1.6 seconds for parser to convert html stream into a document fragment 18.4 seconds for content to insert the document fragment into the document 3.45 seconds for layout to reflow the document 0.45 seconds for painting document More Details The Test Case Mail Reply performance degrades dramatically when replying to messages that have a large number of dom nodes that are all children of the body. So for this test I replied to a html message that was 4000 lines of text, each line separated by a break node <br>. The machine I used was my 300 MHz G3 mac portable. The build I used was a debug build of the tip, patched as described, and with some instrumentation calls added. The instrumentation impact on the results is not significant, but using a debug build is (don't know how much of a difference there). >From Mousedown to Mail Compose Creating the Editor It's worth looking into how long it takes to get from clicking on the "Reply" widget to Mail Compose actually creating an editor for the message body. I suspect it is a significant amount of time. I didn't investigate it - mail folks may want to do this. Editor Creation and Initialization Editor creation and Editor Initialization are pretty fast here. Construction took 50 microseconds. Init took 25 milliseconds. >From Mail getting a finished Editor to Mail calling InsertCitedQuotation Once the editor is up mail compose has to get ready to insert the data into the editor. I don't know the details of what is happening here (is it all Mime stuff? Is this when the original message is pulled over the wire if it hasn't been previously?). It takes 7 seconds, which is a rather long time and a big part of the overall time. Mail folks may want to profile this and look for improvements. Inside nsHTMLEditor::InsertCitedQuotation At this point mail compose hands off the html for those 4000 lines to the editor. This is the part of the process my patch has streamlined. Only four things happen inside the editor from this point on. The first is handled by the parser. The remaining three are handled by content/layout. Parsing the HTML for the Quote The first step is to convert the text stream of html into an object suitable for insertion into the DOM. CreateContextualFragment() does this. It's an nsIDOMNSRange call, but it really falls through to the parser. The parser builds up a DOM Document Fragment from the html stream. This takes 1.6 seconds in this test. Inserting the Document Fragment into the DOM Next we huck the docfrag into the document using the content call nsIDOMNode::AppendChild(). This takes a whopping 18.4 seconds. Layout folks can tell you better than I what is happening here, but I do know that in addition to moving the 8000 nodes in the document fragment into the mail compose document, it is also creating frames for those 8000 nodes and firing off a lot of content changed notifications. I know the process of moving the nodes into the document can be speeded up, and I believe that the notifications can be largely coalesced. I'm not sure if any improvements can be made to frame construction. Johnny Stenback is working on this. Reflow Next reflow is enabled on the editor. It was off before this so that we would only do one reflow after the document is fully created. Reflow takes 3.45 seconds, which is a pretty long time. Paint After reflow, we enable view updating on the editor. I believe this is where painting is happening. It takes 0.45 seconds. Whats Missing My patch rips out some things that we may not want ripped out. The first thing is that I'm not going through the transaction manager when we insert the docfrag. This means the operation is not undoable. That's not important for mail quoting because we don't want that undoable, and in fact mail compose turns off undo on the editor until it is finished building up the message. But if wanted to use this simplified codepath for other "live" editor actions then I should go through the transaction manager. I strongly suspect that doing so will add very little time. If I'm right about that I'll put in an updated patch to that effect later. Also removed is some editor postprocessing. This postprocessing was time intensive: if I put it back in it would add about 6 seconds to the total time. The two things that mattered here were replacement of preformatted newlines with break nodes, and insertion of break nodes into empty list items and table cells. Both of these steps used to be done for the same reason: to avoid deadspace in the message where the user would be unable to get a caret by clicking. Blank lines caused by newlines in preformatted html, and empty list items and table cells, all suffer from this problem. converting such newlines to breaks gives the same visual effect, and allows any blank lines to be clicked in. Similarly, adding a single <br> node into an empty list item or table cell has no visual effect, but again allows caret placement when the user clicks there. I have looked into the performance of the postprocessing before, and I know how to speed it up the checks. The result would be that it would not be terribly expensive to make these checks, if the document didn't actually need the changes. Ie, the scanning could be made much faster than it is. However, if the document needed many such changes, it would still be time intensive. This is because we would have to make thousands of changes to the dom, and that is expensive. To improve that I will need help from layout folks. There are two things off the top of my head that could be done to avoid this problem entirely. The first and most obvious is to do the work in the frame code and caret code to allow us to get a caret in these problem areas. Then we don't have to do any of this. The second is we could make a funky flavor of the parser to use here that actually did these conversions/insertions on the fly as it scanned the html stream. That would be a LOT faster than beating on the DOM afterwards. -- jfrancis .com -and- floppymoose .net @netscape @netscape