summaryrefslogtreecommitdiffstats
path: root/layout/docs/DynamicChangeHandling.md
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-12 05:35:37 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-12 05:35:37 +0000
commita90a5cba08fdf6c0ceb95101c275108a152a3aed (patch)
tree532507288f3defd7f4dcf1af49698bcb76034855 /layout/docs/DynamicChangeHandling.md
parentAdding debian version 126.0.1-1. (diff)
downloadfirefox-a90a5cba08fdf6c0ceb95101c275108a152a3aed.tar.xz
firefox-a90a5cba08fdf6c0ceb95101c275108a152a3aed.zip
Merging upstream version 127.0.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'layout/docs/DynamicChangeHandling.md')
-rw-r--r--layout/docs/DynamicChangeHandling.md83
1 files changed, 83 insertions, 0 deletions
diff --git a/layout/docs/DynamicChangeHandling.md b/layout/docs/DynamicChangeHandling.md
new file mode 100644
index 0000000000..50df613412
--- /dev/null
+++ b/layout/docs/DynamicChangeHandling.md
@@ -0,0 +1,83 @@
+# Dynamic change handling along the rendering pipeline
+
+The ability to make changes to the DOM from script is a major feature of
+the Web platform. Web authors rely on the concept (though there are a
+few exceptions, such as animations) that changing the DOM from script
+leads to the same rendering that would have resulted from starting from
+that DOM tree. They also rely on the performance characteristics of
+these changes: small changes to the DOM that have small effects should
+have proportionally small processing time. This means that Gecko needs
+to efficiently propagate changes from the content tree to style, the
+frame tree, the geometry of the frame tree, and the screen.
+
+For many types of changes, however, there is substantial overhead to
+processing a change, no matter how small. For example, reflow must
+propagate from the top of the frame tree down to the frames that are
+dirty, no matter how small the change. One very common way around this
+is to batch up changes. We batch up changes in lots of ways, for
+example:
+
+- The content sink adds multiple nodes to the DOM tree before
+ notifying listeners that they\'ve been added. This allows notifying
+ once about an ancestor rather than for each of its descendants, or
+ notifying about a group of descendants all at once, which speeds up
+ the processing of those notifications.
+- We batch up nodes that require style reresolution (recomputation of
+ selector matching and processing the resulting style changes). This
+ batching is tree based, so it not only merges multiple notifications
+ on the same element, but also merges a notification on an ancestor
+ with a notification on its descendant (since *some* of these
+ notifications imply that style reresolution is required on all
+ descendants).
+- We wait to reconstruct frames that require reconstruction (after
+ destroying frames eagerly). This, like the tree-based style
+ reresolution batching, avoids duplication both for same-element
+ notifications and ancestor-descendant notifications, even though it
+ doesn\'t actually do any tree-based caching.
+- We postpone doing reflows until needed. As for style reresolution,
+ this maintains tree-based dirty bits (see the description of
+ NS\_FRAME\_IS\_DIRTY and NS\_FRAME\_HAS\_DIRTY\_CHILDREN under
+ Reflow).
+- We allow the OS to queue up multiple invalidates before repainting
+ (though we will likely switch to controlling that ourselves). This
+ leads to a single repaint of some set of pixels where there might
+ otherwise have been multiple (though it may also lead to more pixels
+ being repainted if multiple rectangles are merged to a single one).
+
+Having changes buffered up means, however, that various pieces of
+information (layout, style, etc.) may not be up-to-date. Some things
+require up-to-date information: for example, we don\'t want to expose
+the details of our buffering to Web page script since the programming
+model of Web page script assumes that DOM changes take effect
+\"immediately\", i.e., that the script shouldn\'t be able to detect any
+buffering. Many Web pages depend on this.
+
+We therefore have ways to flush these different sorts of buffers. There
+are methods called FlushPendingNotifications on nsIDocument and
+nsIPresShell, that take an argument of what things to flush:
+
+- Flush\_Content: create all the content nodes from data buffered in
+ the parser
+- Flush\_ContentAndNotify: the above, plus notify document observers
+ about the creation of all nodes created so far
+- Flush\_Style: the above, plus make sure style data are up-to-date
+- Flush\_Frames: the above, plus make sure all frame construction has
+ happened (currently the same as Flush\_Style)
+- Flush\_InterruptibleLayout: the above, plus perform layout (Reflow),
+ but allow interrupting layout if it takes too long
+- Flush\_Layout: the above, plus ensure layout (Reflow) runs to
+ completion
+- Flush\_Display (should never be used): the above, plus ensure
+ repainting happens
+
+The major way that notifications of changes propagate from the content
+code to layout and other areas of code is through the
+nsIDocumentObserver and nsIMutationObserver interfaces. Classes can
+implement this interface to listen to notifications of changes for an
+entire document or for a subtree of the content tree.
+
+WRITE ME: \... layout document observer implementations
+
+TODO: how style system optimizes away rerunning selector matching
+
+TODO: style changes and nsChangeHint