Neil's Place

November 3, 2011

Window Reflows on Startup

Filed under: Mozilla — enndeakin @ 2:02 pm

I took a look at what happens on Firefox startup on Mac with a profile I’ve used for testing for a while. Specifically, how often and why the root element (<window>) in the browser window is asked to be laid out. Each line below is an attempt to lay out (reflow) the root element. A reflow can happen as a result of a number of different things such as new elements being inserted, images being loaded and so forth. What happens is that the document layout objects are marked as dirty as necessary, then at a future point, a reflow occurs. This allows a script to make a number of changes without having each change cause a full refresh. I’ve broken down each attempt to mark the root element (or some other reflow root) as dirty, separated by commas in each line. In the table below, a reflow occurs 15 times.

Action

Time to finish
Hidden Window

0.55ms

Main Window is parsed and laid out

14.95ms

Attribute changed, and loaded page (about:blank) is laid out

0.78ms

Search icon is set

0.35ms

Scrollbar attributes changed, toolbarspring is inserted, window’s load event fires and listeners called and finished

2.21.ms

Scrollbar attributes changed, tabview.png is set

0.34ms

folderDropArrow.png is set

0.27ms

browser.js delayedStartup() is called, splitter is inserted into urlbar

0.24ms

menupopup is appended to back button, delayedStartup() finishes, bookmarks toolbar handling begins

5.77ms

chrome://browser/skin/places/query.png is set

0.56ms

chrome://browser/skin/page-livemarks.png is set

0.39ms

chrome://global/skin/tree/folder.png is set

0.46ms

Call to flush frames

0.33ms

Bookmark icon is set

0.48ms

Bookmark icon is set

0.37ms

The last few images are all the assignment of the icons on the bookmarks toolbar. These don’t occur if the toolbar is hidden. In total, approximately 400 changes to an element’s attribute are made and 41 nodes are appended to the document after it is parsed.

Now let’s take a look at the mobile version, running on an Android tablet. Here, 24 reflows occur over the 2200ms startup time.

Action

Time to finish
Insert html element into main window?, insert html element into hidden window?, parse and lay out main window

7.43ms (also 183.7ms reading xbl)

Four dirty marks caused by scrollbar attribute changes

1.07ms

Remove text node (a <br> is appended to a <div> immediately following), append <documenttab>

2.55ms

Append <notificationbox>

0.78ms

Some attributes on <label> and <image> elements are changed, some <label> elements are removed

1.20ms

scrollbar.pageincrement is changed

0.28ms

SizeToContent is called

0.22ms

Unknown reason, but probably caused by bug 230959

0.94ms

slider.pageincrement is changed, attributes on <tablet> are changed

5.329ms

Three dirty marks caused by scrollbar attribute changes

1.65ms

Attribute changed on a <scrollbox>

1.19ms

Attribute changed on a <scrollbox>

0.57ms

Attributes left, width and height changed on a <vbox>

1.40ms

Two scrollbar related dirty marks, mode attribute changed on various things (no dirty mark), loading attribute on an <image>

1.88ms

mode attribute changed on various things (no dirty mark), loading attribute on an <image>

0.76ms

Some <image> elements are inserted and removed

0.72ms

Unknown reason, probably a flush caused by retrieving some layout information

0.53ms

Unknown reason, probably a flush caused by retrieving some layout information

0.68ms

Loaded page starts appearing, <toolbarbutton> label changed

2.27ms

Text node appended to page

0.51ms

Text node removed from page, height changed on an <hbox> related to a nearby <canvas>.

1.54ms

mode attribute changed on various things (no dirty mark), loading attribute on an <image>

0.74ms

<box> is marked not hidden (think this is the autocomplete widget), insert frames into box, some attributes on <richlistitem> and <menuitem> are changed

33.78ms (also 265.18ms reading xbl)

Eight dirty marks caused by scrollbar attribute changes

2.70ms

Observations:

  • There are lots of changes to scrollbars here, despite no scrollbars on mobile Firefox being visible. The set listed in the last row is likely caused by the resize caused by the on-screen keyboard appearing. 120ms of time occurs from when this begins to when this ends, although it is likely that only a small amount of this is directly scrollbar related.
  • I didn’t measure XBL parsing time on desktop Firefox in this test, but it typically takes about 10% of the startup time. Of course, XBL caching should reduce the time to load XBL here. It should be noted though that parsing and creating the main document takes 25% of the rest of the time.
  • The time between reflow 2 and reflow 18 is 550ms. I’m not familiar enough with the mobile code, but this appears to be the time to process and manipulate things after the main document is parsed, equivalent to desktop Firefox’s handling in browser.js.
  • The last two rows are for the autocomplete and on-screen keyboard appearing. It takes up 675ms of time, but the main window has already appeared, so the user’s perception of the time to start up may not need to include this time.

3 Comments »

  1. Some of the mobile reflows might be due to our triple-resize event. There are 2 bogus ones and then it finally gets set to what the OS tells it to be.

    Comment by Taras Glek — November 3, 2011 @ 7:25 pm

  2. Why are multiple reflows done in the first place? Wouldn’t it be better to hold them off until the whole UI has been loaded?

    Comment by CAFxX — November 4, 2011 @ 10:09 am

  3. This is fascinating work, well done! It reflects the experience I’ve always had when restarting Firefox and that is one of a lot of activity.

    The simple question has to be asked: why isn’t most of this reflow made redundant by saving the window’s layout information before closing? I imagine a certain amount of re-checking would be necessary to make sure the window is not larger than a monitor that might have had it’s resolution changed in between Firefox restarts, for example. But other than it seems Firefox does a lot of work that slows down for no particular reason?

    The way XUL or the underlying Firefox codebase ‘draws’ windows has always been an oddity compared to most other Windows-based applications running on other toolkits – even GTK+ for Windows doesn’t seem to do so much work just to present the basic initial window. It seems that not only is this a waste of start up time but in some cases I still see the awful user experience of Firefox starting up with the window sized to a puny 200 x 200 pixels – on a desktop! I’ve never been able to figure out why that happens. I’ve always assumed that Firefox allowance for resized popup windows in JS has had something to do with it but maybe it’s just an inherant XUL weakness?

    Comment by pd — November 5, 2011 @ 6:34 am


RSS feed for comments on this post. TrackBack URI

Leave a reply to Taras Glek Cancel reply

Create a free website or blog at WordPress.com.