Gecko:Table reflow optimization

From MozillaWiki
Jump to: navigation, search


Preface

With the looming reflow branch the table reflow code will face a major rewrite. This is the last ditch effort to keep some of the optimizations and more important Boris asked for it. This document will be useless for practical work once the reflow branch is done. This document assumes that the reader is fluent with the reflow namings and main variables.

Introduction

As a lot of real web pages use table based layouts, having a fast table reflow is must. The fastest reflow is the reflow that we do not execute, so tables try to avoid not needed reflows. Furthermore they have allready storage mechanisms, that the reflow branch will establish for all frames.

Cached sizes

Table frames have two caches at the parent level (table frame) and child level (table cells). These caches can be queried without reflow

  • nsTableCellFrame
    • GetPass1MaxElementWidth() - MEW
    • GetDesiredSize() - desired width
    • GetMaximumWidth() - maximum width.
  • nsTableFrame
    • GetMinWidth() - MEW
    • GetDesiredWidth() - desired width
    • GetPreferredWidth() - maximum width.

The layout strategy computes from the cell parameters and the style information the table size parameters.

With the information of the layout strategy one does know which cells don't have the right size and can mark them as dirty.

Reflow avoidance

Nested tables

This is the most important optimization.

The table reflow has to be a two stage process, as outlined in the CSS 2.1 specification. The initial reflow of a table is a unconstrained reflow to get the maximum width and the MEW for all table cells. Once this is done we will know the three main sizes, maxwidth, MEW and specified size for all table cells. This information is balanced and the widths for every column is computed. The table cells will have the same width as the column. With the column information we do a resize reflow.

Now assume a nested table and look at the innermost table, the outer table will cause first a unconstrained initial reflow. So the inner table will execute a initial unconstrained reflow too as a result we will know the table maximum width and MEW, but it will defer the resize reflow. There is no unconstrained resize reflow. Then the outer table will cause a contrained resize reflow based on the information that the inner table provided. By this the inner table will not execute more than two reflows regardless how deep the nesting is. The optimization is done at nsTableFrame::Reflow.

Resize without available size change

As we cache all neccessary sizes, there is no need to reflow just to return the MEW or the maximum width. We do this at the outermost level in nsTableOuterFrame::Reflow.