Boost Flutter List Performance: Deep Dive into Rendering, Optimization, and Reuse Strategies
This article explores Flutter's rendering pipeline, identifies performance bottlenecks in scrollable list scenarios, and presents a series of low‑level optimizations—including partial refresh, element and RenderObject reuse, load‑more handling, and GC suppression—that raise frame rates above native levels while reducing jank.
Introduction
Taobao's "Taot" uses Flutter in many complex business scenarios, but on low‑end devices the scroll performance of Flutter list views lags behind native Android/iOS. After extensive profiling and low‑level optimizations the average frame rate exceeds 50 fps, yet noticeable stutter remains, prompting further technical breakthroughs.
Rendering Mechanism
Flutter renders on top of the native system, so its rendering mechanism closely mirrors native pipelines. After receiving a VSync signal the engine triggers beginFrame , then proceeds through Animation , Build , Layout , Compositing Bits , Paint , and finally Compositing where the layer tree is rasterized and sent to the GPU.
Core Rendering Stages
The stages most relevant to performance are Build (constructing the widget and element trees), Layout (calculating sizes), and Paint (generating the layer tree). RenderObjects are created during Build, laid out in Layout, and painted in Paint; most performance work focuses on these objects.
Streaming List Scenario
In a scrollable list Flutter uses SliverList (implemented as SliverMultiBoxAdaptorWidget) which internally manages child creation via SliverMultiBoxAdaptorElement. New items entering the viewport are created with createChild, while items leaving are removed with removeChild. The element‑to‑render‑object relationship is maintained by ContainerRenderObjectMixin, which stores children in a doubly‑linked list.
Optimization Strategies
Three‑layer optimization is proposed:
Load More : Automatically detect when more data is needed and inject a footer widget via a custom ReuseSliverChildBuilderDelegate.
Partial Refresh : When only newly added items need rebuilding, bypass full performRebuild and create just the required children.
Element & RenderObject Reuse : Cache detached Elements and RenderObjects by type, reuse them for new items, and avoid full deactivation/attachment cycles.
GC Suppression & Asynchrony
Dart's generational GC can be throttled during scrolling, though deep engine changes are required and benefits are limited. Heavy non‑UI work can be offloaded to a thread‑pool‑like isolate using compute, but gains were marginal.
Core Implementation
class SliverList extends SliverMultiBoxAdaptorWidget {</code>
<code> @override</code>
<code> RenderSliverList createRenderObject(BuildContext context) {</code>
<code> final SliverMultiBoxAdaptorElement element = context as SliverMultiBoxAdaptorElement;</code>
<code> return RenderSliverList(childManager: element);</code>
<code> }</code>
<code>}Similarly, ReuseSliverMultiBoxAdaptorElement overrides createChild and removeChild to perform caching and reuse, and its update method decides between partial refresh and full rebuild.
Results
Performance tests with PerfDog show a 2‑3 fps increase in average frame rate and a 1.5 % reduction in jank after applying the optimizations and switching to the UC Hummer engine.
Usage
Replace the standard SliverList with ReuseSliverList (or a custom reuse‑enabled widget) and use ReuseSliverChildBuilderDelegate when a footer or load‑more callback is required. Avoid assigning Key to item/footer widgets unless you need strict key‑based reuse.
Notes
When reusing Elements, ensure state is refreshed in didUpdateWidget. Implement optional lifecycle callbacks ( onAppear, onDisappear) via the ReuseSliverLifeCycle mixin for resource management.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
