WICG / canvas-formatted-text

Other
82 stars 17 forks source link

Why is `format()` async? #24

Closed travisleithead closed 3 years ago

travisleithead commented 3 years ago

It is unclear to me what is it a necessary for making the format() function async. Can we get more information on the rationale?

@nhelfman

travisleithead commented 3 years ago

My thinking was that: we don't know how huge the data model might be--we expect it to be relatively small in most cases (as these basically map to paragraphs), but assuming it was a lot more text (with style), it might take a long while for the layout process to run, hence making it async to ensure it doesn't block the main thread. Additionally, if multiple format calls are made on the main thread, they can be queued by the implementation to run consecutively, saving time after main thread execution. It also more-or-less ensures that you only get one format call per formatted text object per task cycle. Those are the rationale I was thinking about when making it async. Happy to be wrong or to entertain arguments for making it sync, since that's just an easier coding pattern to use.

yjbanov commented 3 years ago

Glad this is already filed. I was just going to file an issue about this.

Async format() doesn't work for Flutter, and I imagine for anything that uses requestAnimationFrame to drive animations. The browser assumes the task scheduled for an animation frame will synchronously complete all the UI modifications (DOM updates, canvas draws, WebGL surface flush) and produce pixels at the end of it. If a computation is scheduled asynchronously you have an incomplete frame, and the drawn UI is wrong (and in case of Flutter there's nothing to draw since layout happens before paint and layout didn't finish; we could leave the previous frame but that will look like jank).

For use-cases where text layout should occur asynchronously I think it's reasonable to recommend web workers. If the use-case proves to be popular and web workers have some fundamental unfixable limitations, then an asynchronous version of format can be introduced as an optimization. The reverse is not possible. If we begin with an asynchronous format, there's no way to make it synchronous. Asynchrony is infectious this way.

travisleithead commented 3 years ago

Having web workers as the async alternative does make a lot of sense.