Flutter 是怎么实现 element 重用的
Flutter 三棵树中 element 树实现了 flutter 组件重用,element 树的存在保障了 flutter 页面流畅渲染。通过代码来分析下 element 复用流程。
首先常见 element 主要分为两大类,RenderObjectElement 和 ComponentElement
SingleChildRenderObjectElement.update() -> Element.updateChild()
MultiChildRenderObjectElement.update() -> Element.updateChildren
ComponentElement.
Element.updateChildren()
- Update the top of the list.
// if canUpdate (which means key is the same and runtime type is the same) reuse and update, remember the index, if not goto next step- Scan the bottom of the list.
// if canUpdate remember the last canUpdate item index, if not goto next step- Scan the old children in the middle of the list.
// keep the middle of the list items with key, save in a map- Update the middle of the list.
// check newWidget items from step 1’s index to step 2’s index, if key exsit in map of step 3 and can be reused, reuse it and update, if not recreate element- Update the bottom of the list.
// if canUpdate, reuse and update
Element.updateChild()
->inflateWidget(newWidget, newSlot)
->newWidget.createElement()
ComponentElement.performRebuild()
-> ComponentElement.build()
-> Element.updateChild()
child.widget == newWidget
-> check slot, update slot, reuse
Widget.canUpdate(child.widget, newWidget)
-> child.update(newWidget);
else
-> inflateWidget(newWidget, newSlot)
// if can reuse by GlobalKey, else createElement
Element reuse scenario
- Under a MultiChildRenderObjectElement, key and runtime are not changed. Doesn’t matter if position changes.
- Under a SingleChildRenderObjectElement or ComponentElement, widget not change or widget changed but key and runtime not changed, or widget changed but have a GlobalKey which element can be reused.
Flutter 是怎么实现 element 重用的