# Elements

## What are elements?

* The element tree is anchored in the `WidgetsBinding` and established via `runApp` / `RenderObjectToWidgetAdapter`.
* `Widget` instances are immutable representations of UI configuration data that are “inflated” into `Element` instances (via `Element.inflateWidget`). Elements therefore serve as widgets' mutable counterparts and are responsible for modeling the relationship between widgets (e.g., the widget tree), storing state and inherited relationships, and participating in the build process, etc.
* All elements are associated with a `BuildOwner` singleton. This instance is responsible for tracking dirty elements and, during `WidgetsBinding.drawFrame`, re-building the element tree as needed. This process triggers several lifecycle events (e.g., `initState`, `didChangeDependencies`, `didUpdateWidget`).
* Elements are assembled into a tree (via `Element.mount` and `Element.unmount`). Whereas these operations are permanent, elements may also be temporarily removed and restored (via `Element.deactivate` and `Element.activate`, respectively).
  * Elements transition through several lifecycle states (`_ElementLifecycle`) in response to the following methods: `Element.mount` (`initial` to `active`, `Element.activate` is only called when reactivating), `Element.deactivate` (`active` to `inactive`, can be reactivated via `Element.activate)`, then finally `Element.unmount` (`inactive` to `defunct`).
  * Note that deactivating or unmounting an element is a recursive process, generally facilitated by the build owner's inactive elements list (`BuildOwner._inactiveElements`). All descendant elements are affected (via`_InactiveElements._deactivateRecursively` and`_InactiveElements._unmount`).
* Elements are attached (i.e., mounted) to the element tree when they're first created. They may then be updated (via `Element.update`) multiple times as they become dirty (e.g., due to widget changes or notifications). An element may also be deactivated; this removes any associated render objects from the render tree and adds the element to the build owner's list of inactive nodes. This list (`_InactiveElements`) automatically deactivates all nodes in the affected subtree and clears all dependencies (e.g., from `InheritedElement`).
  * Parents are generally responsible for deactivating their children (via `Element.deactivateChild`). Deactivation temporarily removes the element (and any associated render objects) from the element tree; unmounting makes this change permanent.
  * An element may be reactivated within the same frame (e.g., due to tree grafting), otherwise the element will be permanently unmounted by the build owner (via `BuildOwner.finalizeTree` which calls `Element.unmount`).
  * If the element is reactivated, the subtree will be restored and marked dirty, causing it to be rebuilt (re-adopting any render objects which were previously dropped).&#x20;
* `Element.updateChild` is used to update a child element when its configuration (i.e., widget) changes. If the new widget isn't compatible with the old one (e.g., doesn't exist, has a different type, or has a different key), a fresh element is inflated (via `Element.inflateWidget`). Once an element is retrieved or inflated, the new configuration is applied via `Element.update`; this might alter an associated render object, notify dependents of a state change, or mutate the element itself.
  * When an element is re-inflated, it has no access to any existing children; that is, children associated with the old element aren't passed to the new element. Thus, all descendants need to be re-inflated, too (there are no old elements to synchronize).
  * Global keys are one exception: any children associated with a global key can be restored without being re-inflated.

## What are the element building blocks?

* Elements are mainly broken down into `RenderObjectElement` and `ComponentElement`. `RenderObjectElements` are responsible for configuring render objects and keeping the render object tree and widget tree in sync. `ComponentElements` don't directly manage render objects but instead produce intermediate nodes via mechanisms like `Widget.build`. Both processes are driven by `Element.performRebuild` which is itself triggered by `BuildOwner.buildScope`. The latter is run as part of the build process every time the engine requests a frame.
* `ProxyElement` forms a third category of elements that wrap a subtree of elements (and are configured by `ProxyWidget`). These generally augment the subtree in some way (e.g., `InheritedElement` injects heritable state). Proxy elements use notifications to inform subscribers when its configuration changes (`ProxyElement.update` invokes `ProxyElement.updated` which, by default, calls `ProxyElement.notifyClients`). Subclasses manage subscribers in an implementation-specific way.
  * `ParentDataElement` updates the parent data of all closest descendant render objects (via `ParentDataElement._applyParentData`, which is called by `ParentDataElement.notifyClients`).&#x20;
  * `InheritedElement` notifies a set of dependents whenever its configuration is changed (i.e., when `InheritedElement.update` is invoked).`InheritedElement._dependants` is implemented as a mapping since each dependent can provide an arbitrary object to use when determining whether an update is applicable. Dependents are notified by invoking `Element.didChangeDependencies`.

## How is the render tree managed by `RenderObjectElement`?

* Render object elements are responsible for managing an associated render object. `RenderObjectElement.update` applies updates to this render object to match a new configuration (i.e., widget).
  * The render object is created (via `RenderObjectWidget.createRenderObject`) when its element is first mounted. The render object is retained throughout the life of the element, even when the element is deactivated (and the render object is detached).&#x20;
    * A new render object is created if an element is inflated and mounted (e.g., because a new widget couldn't update the old one); at this point, the old render object is destroyed. A slot token is used during this process so the render object can attach and detach itself from the render tree (which can vary from the element tree).
  * The render object is attached to the render tree when its element is first mounted (via `RenderObjectElement.attachRenderObject`). If the element is later deactivated (due to tree grafting), it will be re-attached when the graft is completed (via `RenderObjectElement.inflateWidget`, which includes special logic for handling grafting by global key).
  * The render object is updated (via `RenderObjectWidget.updateRenderObject`) when its element is updated (via `Element.update`) or rebuilt (via `Element.rebuild`).
  * The render object is detached from its parent (via `RenderObjectElement.detachRenderObject`) when the element is deactivated. This is generally managed by the parent (via `Element.deactivateChild`) and occurs when children are explicitly removed or reparented due to tree grafting. Deactivating a child calls `Element.detachRenderObject` which recursively processes descendants until reaching the nearest render object element boundary. `RenderObjectElement` overrides this method to detach its render object, cutting off the recursive walk.
* Render objects may have children. However, there may be several intermediate nodes (i.e., component elements) between its `RenderObjectElement` and the elements associated with its children. That is, the element tree typically has many more nodes than the render tree.
  * Slot tokens are passed down the element tree so that these `RenderObjectElement` nodes can interact with their render object's parent (via`RenderObjectElement.insertChildRenderObject`, `RenderObjectElement.moveChildRenderObject`, `RenderObjectElement.removeChildRenderObject`). Tokens are interpreted in an implementation-specific manner by the ancestor `RenderObjectElement` to distinguish render object children.
* Elements generally use their widget's children as the source of truth (e.g., `MultiChildRenderObjectWidget.children`). When the element is first mounted, each child is inflated and stored in an internal list (e.g., `MultiChildRenderObjectElement._children`); this list is later used when updating the element.
* Elements can be grafted from one part of the tree to another within a single frame. Such elements are “forgotten” by their parents (via `RenderObjectElement.forgetChild`) so that they are excluding from iteration and updating. The old parent removes the child when the element is added to its new parent (this happens during inflation, since grafting requires that the widget tree be updated, too).
* Elements are responsible for updating any children. To avoid unnecessarily inflation (and potential loss of state), the new and old child lists are synchronized using a linear reconciliation scheme optimized for empty lists, matched lists, and lists with one mismatched region:

1. The leading elements and widgets are matched by key and updated.
2. The trailing elements and widgets are matched by key with updates queued (update order is significant).
3. A mismatched region is identified in the old and new lists.
4. Old elements are indexed by key.
5. Old elements without a key are updated with null (deleted).
6. The index is consulted for each new, mismatched widget.
7. New widgets with keys in the index update together (re-use).
8. New widgets without matches are updated with null (inflated).
9. Remaining elements in the index are updated with null (deleted).

## What are the render object element building blocks?

* `LeafRenderObjectElement`, `SingleChildRenderObjectElement`, and `MultiChildRenderObjectElement` provide support for common use cases and correspond to the similarly named widget helpers (`LeafRenderObjectWidget`, `SingleChildRenderObjectWidget`, `MultiChildRenderObjectWidget`)
  * The multi-child and single-child variants pair with `ContainerRenderObjectMixin` and `RenderObjectWithChildMixin` in the render tree.
* These use the previous child (or null) as the slot identifier; this is convenient since `ContainerRenderObjectMixin` manages children using a linked list.

## How are elements managed by `ComponentElement`?

* `ComponentElement` composes other elements. Rather than managing a render object itself, it produces descendant elements that manage their own render objects through building.
* Building is an alternative to storing a static list of children. Components build a single child dynamically whenever they become dirty.
* This process is driven by `Element.rebuild` which is invoked by the build owner when an element is marked dirty (via `BuildOwner.scheduleBuildFor`). Component elements also rebuild when they're first mounted (via `ComponentElement._firstBuild`) and when their widget changes (via `ComponentElement.update`). For `StatefulElement`, a rebuild may be scheduled spontaneously via `State.setState`. In all cases, lifecycle methods are invoked in response to changes to the element tree (for example, `StatefulElement.update` will invoke `State.didUpdateWidget`).
* The actual implementation is supplied by `Element.performRebuild`. Component elements override`Element.performRebuild` to invoke `ComponentElement.build` whereas render object elements update their render object via `RenderObjectWidget.updateRenderObject`.
* `ComponentElement.build` provides a hook for producing intermediate nodes in the element tree. `StatelessElement.build` invokes the widget’s build method, whereas `StatefulElement.build` invokes the state’s build method. `ProxyElement` simply returns its widget's child.
* Note that if a component element rebuilds, the child element and the newly built widget will still be synchronized (via `Element.updateChild`). If the widget is compatible with the existing element, it'll be updated instead of re-inflated. This allows existing render objects to be mutated instead of being recreated. Depending on the mutation, this might involve any combination of layout, painting, and compositing.
* Reassembly (e.g., `Element.reassemble`) marks the element as being dirty; most subclasses do not override this behavior. This causes the element tree to be rebuilt during the next frame. Render object elements update their render objects in response to `Element.performRebuild` and therefore also benefit from hot reload.

## How does building work?

* Only widgets associated with `ComponentElement` (e.g., `StatelessWidget`, `StatefulWidget`, `ProxyWidget`) participate in the build process; `RenderObjectWidget` subclasses, generally associated with `RenderObjectElements`, do not; these simply update their render object when building. `ComponentElement` instances only have a single child, typically that returned by their widget’s build method (`ProxyElement` returns the child attached to its widget)..
* When the element tree is first anchored to the render tree (via `RenderObjectToWidgetAdapter.attachToRenderTree`), the `RenderObjectToWidgetElement` (a `RootRenderObjectElement`) assigns a `BuildOwner` for the element tree. The `BuildOwner` is responsible for tracking dirty elements (`BuildOwner.scheduleBuildFor`), establishing build scopes wherein elements can be rebuilt / descendant elements can be marked dirty (`BuildOwner.buildScope` / `BuildOwner.scheduleBuildFor`), and unmounting inactive elements at the end of a frame (`BuildOwner.finalizeTree`). It also maintains a reference to the root `FocusManager` and triggers reassembly after a hot reload.
* When a `ComponentElement` is mounted (e.g., after being inflated), an initial build is performed immediately (via `ComponentElement._firstBuild`, which calls `ComponentElement.rebuild`).
* Later, elements can be marked dirty using `Element.markNeedsBuild`. This is invoked any time the UI might need to be updated implicitly (or explicitly, in response to `State.setState`). This method adds the element to the dirty list and, via `BuildOwner.onBuildScheduled`, schedules a frame via `SchedulerBinding.ensureVisualUpdate`. The actual build will take place when the next frame is processed.
  * Some operations trigger a rebuild directly (i.e., without marking the tree dirty first). These include `ProxyElement.update`, `StatelessElement.update`, `StatefulElement.update`, and `ComponentElement.mount`. In these cases, the intention is to update the element tree immediately.
  * Other operations schedule a build to occur during the next frame. These include `State.setState`, `Element.reassemble`, `Element.didChangeDependencies`, `StatefulElement.activate`, etc.
  * Proxy elements use notifications to indicate when underlying data has changed. In the case of `InheritedElement`, each dependent's `Element.didChangeDependencies` is invoked which, by default, marks that element as being dirty. This causes the descendant to rebuild when any of its dependencies change.
* Once per frame, `BuildOwner.buildScope` will walk the element tree in depth-first order, only considering those nodes that have been marked dirty. By locking the tree and iterating in depth first order, any nodes that become dirty while rebuilding must necessarily be lower in the tree; this is because building is a unidirectional process -- a child cannot mark its parent as being dirty. Thus, it is not possible for build cycles to be introduced and it is not possible for elements that have been marked clean to become dirty again.
* As the build progresses, `ComponentElement.performRebuild` delegates to the `ComponentElement.build` method to produce a new child widget for each dirty element. Next, `Element.updateChild` is invoked to efficiently reuse or recreate an element for the child. Crucially, if the child’s widget hasn’t changed, the build is immediately cut off. Note that if the child widget did change and `Element.update` is needed, that child will itself be marked dirty, and the build will continue down the tree.
* Each `Element` maintains a map of all `InheritedElement` ancestors at its location. Thus, accessing dependencies from the build process is a constant time operation.
* If `Element.updateChild` invokes `Element.deactivateChild` because a child is removed or moved to another part of the tree, `BuildOwner.finalizeTree` will unmount the element if it isn’t reintegrated by the end of the frame.

## How does element inheritance work?

* `InheritedElement` provides an efficient mechanism for publishing heritable state to a subset of the element tree. This mechanism depends on support provided by `Element` itself.
* All elements maintain a set of dependencies (`Element._dependencies`, e.g., elements higher in the tree that fill a dependency) and a mapping of all `InheritedElement` instances between this element and the root (`Element._inheritedWidgets`). The dependencies set is mainly tracked for debugging purposes .
* The map of inherited elements serves as an optimization to avoid repeatedly walking the tree. Each dependency is uniquely identified by its instantiated type; multiple dependencies sharing a type shadow one another (in this case, shadowed dependencies may still be be retrieved by walking the tree).
  * This mapping is maintained by `Element._updateInheritance`. By default, elements copy the mapping from their parents. However, `InheritedElement` instances override this method to insert themselves into the mapping (the mapping is always copied so that different branches of the tree are independent).
  * This mapping is built on the fly (via `Element._updateInheritance`) when elements are first mounted (via `Element.mount`) or are reactivated (via `Element.activate`). The mapping is cleared when elements are deactivated (via `Element.deactivate`); the element is removed from each of its dependency's dependent lists (`InheritedElement._dependents`). As a result, it's usually not necessary to manually walk an element's ancestors.
* Inherited relationships are established via `Element.dependOnInherited` (`Element.inheritFromElement` is a simple wrapper). In general, the inherited ancestor should be available in `Element._inheritedWidgets`. This process causes the inherited element to add the dependent element to its list of dependencies (via `InheritedElement.updateDependencies`).
  * When an element is reactivating (e.g., after grafting), it is notified of dependency changes if it had existing or unsatisfied dependencies (e.g., a dependency was added but a corresponding `InheritedElement` wasn't found in `Element._inheritedWidgets`).
* Elements are notified when their dependencies change via `Element.didChangeDependencies`. By default, this method marks the element as being dirty.
