# iced mental model

## iced is not immediate mode

Worth correcting up front, because the misconception leads to bad
code: **iced is not immediate mode**. There's no "per paint" or "per
frame" concern. iced redraws on request, and `view()` is called
whenever a batch of messages finishes processing — not on a
wall-clock cadence. Treat `view` as declarative.

## State: expensive transformations, declarative view

`State::new` and `State::update` are where the **expensive** state
transformations happen. That's the right place for parsing, validation,
computing derived state — anything non-trivial.

`State::view` should be **fast and declarative**. You're describing
what should appear, not when it appears. Don't assume `view` runs at
any specific time, and don't put expensive computations there.

## Widget: layout is the expensive pass, draw is the cheap one

Widgets split into two phases:

- **`Widget::layout`** — the more expensive pass. Computes layout
  nodes from constraints. May write to widget state for ephemeral
  things like focus, or for heavily cached operations like culling a
  long list down to just the visible portion.
- **`Widget::draw`** — blazing fast, microseconds. Just breezes
  through the pre-computed shapes from the layout pass.

That's why text uses the `Paragraph` API: it **must** be laid out in
advance during `Widget::layout` before being drawn in `Widget::draw`.

## The skill

Reasoning about when things get *calculated* vs. when they get
*displayed* is the core step to understand both how iced works
internally and how to write fluent iced apps. If you find yourself
thinking "every frame" or "redraw cost" — stop, you're modeling it
wrong.
