D
Widget TreeExpert80 XP6 min read

Describe Flutter's rendering pipeline from frame start to pixel output.

TL;DR: Flutter's rendering pipeline: vsync signal → build (widget tree diff) → layout (constraints/sizes) → paint (canvas commands) → composite (layers) → rasterize (GPU) → display.

Full Answer

Every frame begins with a vsync signal from the device display (typically 60/90/120Hz). Flutter's SchedulerBinding processes this signal and drives the rendering pipeline.

  • 1. Build phase: Dirty elements rebuild their widget trees (setState, provider changes)
  • 2. Layout phase: RenderObjects receive constraints and compute sizes (performLayout)
  • 3. Compositing bits phase: marks which layers need compositing
  • 4. Paint phase: RenderObjects emit canvas draw calls into a PictureLayer
  • 5. Composite phase: SceneBuilder assembles layers into a Scene
  • 6. Rasterize phase: Scene sent to GPU (Skia or Impeller) via dart:ui
  • 7. Display: GPU renders pixels to the screen

Impeller (Flutter's new rendering backend, default on iOS since Flutter 3.10, Android preview) pre-compiles shaders at startup, eliminating the shader compilation jank that plagued Skia.

🎯

The Flutter DevTools Timeline view shows each phase. Look for 'Build', 'Layout', 'Paint', and 'Raster' spans. Long raster spans indicate GPU bottlenecks; long build spans indicate widget rebuild issues.

Code Examples

dartScheduling a post-frame callback
Output
Frame rendered!
Widget size: Size(375.0, 56.0)

Common Mistakes

  • Performing heavy computation during the build phase — use compute() or isolates
  • Trying to access RenderBox size in build() — layout hasn't run yet; use addPostFrameCallback

Interview Tip

💡

Mentioning Impeller and the shader precompilation problem it solves shows you follow Flutter's development roadmap closely.

#rendering-pipeline#frame#vsync#Skia#Impeller#GPU