Flutter's 7-Year-Old Touch Smoother Was Adding a Frame of Latency on Modern iPhones
Any Flutter app on iOS is paying a hidden 8–16 ms touch latency penalty on devices where UIKit's input delivery is already stable. This fix reclaims a full frame of responsiveness for scrolling and drag gestures, and the underlying scheduling corrections prevent frame-rate regressions when the old workaround is removed.
The `SmoothPointerDataDispatcher`, introduced nearly seven years ago to handle irregular touch delivery on the iPhone X, was still buffering 99% of pointer packets to the next VSync on current hardware. UIKit's delivery spread has shrunk from 12 ms to under 1 ms, making the smoother a pure latency penalty. Removing it caused frame rates to halve on some devices, revealing that the smoother had been masking a scheduling defect where the engine's internal `PostTask` calls caused it to miss the current `CADisplayLink` callback.
PR #191368 dismantles three waiting points in the touch pipeline. It replaces the smoother with a default dispatcher, switches to `RunNowOrPostTask` to avoid unnecessary re-posting on the same thread, and makes the `AwaitVSync` call synchronous within the same run-loop turn. A separate fix keeps `CADisplayLink` unpaused during continuous interaction and fires an immediate callback for the first frame from idle, preventing the 30 fps drops seen in earlier experiments.
The contributor, Knopp, also documented a running battle with Gemini Code Assist, which repeatedly flagged a non-existent data race because it failed to recognize that Flutter's iOS embedder merges the platform and UI threads by default.
A performance optimization that made sense on one hardware generation became a guaranteed latency regression on all subsequent ones, and it survived for seven years because it accidentally papered over a separate scheduling bug.
iOS's scheduler sometimes demotes threads to E-cores when their workload appears too light, which means a well-optimized rendering pipeline can be punished with worse frame pacing than a deliberately heavier one.
The two `PostTask` calls in the touch pipeline were not expensive in CPU time, but they shifted the phase of the `AwaitVSync` call just enough to miss the current display-link dispatch, costing an entire frame.
AI code review tools that lack awareness of platform-specific thread configurations can block valid patches with false positives, forcing contributors to spend time arguing with a bot about architecture it does not understand.
The discussion barely engages with the technical substance of the article. One thread dismisses the issue as typical AI behavior, then pivots to Gemini's image-generation prowess. Another comment expresses long-standing frustration with Flutter's scrolling latency on iOS and hopes for a fix. A final remark speculates about the author's employment status.
After all these years, Flutter scrolling on iOS has always felt less responsive than native, with a one-frame delay. Can this finally be fixed? [crying]