The iOS Render Loop, Frame by Frame
iOS frame drops are not one problem but two distinct failure modes—commit hitches and render hitches—that require different instruments and different fixes. Misdiagnosing a render hitch as a main-thread block, or vice versa, sends optimization effort to the wrong process entirely.
Every frame on iOS marches to a vertical sync beat through a five-stage pipeline: Event, Commit (Layout → Display → Prepare → Commit), Render Prepare, Render Execute, and Display. A hitch in any stage means a dropped frame. The pipeline is parallel—while the app prepares frame N, the render server processes N-1 and the display shows N-2—so the 16.7 ms budget is per-stage, not end-to-end.
Commit hitches happen when the app's main thread blocks on JSON parsing, synchronous I/O, lock contention, or when layout, text measurement, drawing, and image decoding overrun the deadline. Render hitches happen when the render server's CPU work (traversing the layer tree, computing animation states) or the GPU's pixel work (alpha blending, overdraw, off-screen rendering, large textures) can't finish in time.
Concrete fixes span the whole chain: pre-compute attributed strings and text layouts on background queues, throttle UI submission rates independently of data arrival, set explicit shadowPaths to avoid off-screen rendering, decode images to thumbnail dimensions before they hit the Prepare phase, and delete wrapper views that add no layout, clipping, or interaction responsibility. A companion open-source skill packages these rules so AI can audit a codebase for frame-drop risks directly.
Apple's hitch taxonomy (commit vs. render) is underused in practice; most teams still talk vaguely about 'main thread' vs. 'GPU' without tracing the specific stage, which leads to fixing the wrong thing.
The advice to avoid Auto Layout in favor of manual frames is often premature—constraint reuse and scoped layoutIfNeeded calls solve most cases, and manual frames lose readability for marginal gain unless Instruments proves otherwise.
Off-screen rendering is not a single cause but a family of effects (masks, dynamic shadows, blurs, corner clipping with sublayers), and rounded corners alone do not guarantee it; the diagnostic tool output should drive the fix, not a blanket rule.
Async drawing adds scheduling overhead and dual-bitmap memory pressure; it is a tradeoff, not a universal upgrade, and the sentinel-based cancellation pattern in YYAsyncLayer is the critical detail that prevents drawing onto the wrong cell.
Preparing message display data on background queues (parsing, attributed string assembly, YYTextLayout) shifts work from both the Event and Layout phases, which is more impactful than optimizing either phase in isolation.