-
Notifications
You must be signed in to change notification settings - Fork 2.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add an API for predecoding images #2037
Comments
More:
|
Actually, the image is "transferred", meaning that the ImageBitmap object is neutered, and the buffer that it once held became the canvas backing store.
That is implementation dependent, the API is async and was deliberately spec'ed in a way that gives implementers the freedom (but not the obligation) to schedule the work on another thread. |
To try and move this forward, I've put together a small demo that demonstrates how this API would be used and the results you might see: In the video, an arrow keeps spinning using a raf animation. On the first full revolution, the image is "prepared" and appended into the DOM. In the first example ("sync"), the prepare function is as follows: function prepareImage() { This waits until the image is loaded, and appends it. You can see a noticeable jank which is the result of an image decode. In the second example ("async"), the prepare function is as follows: function prepareImage() { This waits until the image is loaded and decoded, then appends it into the DOM. The decode here uses similar code path to how images are typically decoded and locked (in the compositor). So the result is that when the decode promise resolves, the image is locked in the cache that is used at raster time. It is then unlocked after a few frames. Subsequent appends/raster of this image are hence not guaranteed to be jank-free. One issue I found with this approach is that the image can be arbitrarily large. In Chromium, we have a limit to how much memory can be locked for an extended period of time. If the image is large enough to breach the limit, the promise resolves but the result is still jank. In other words, the effect is similar to simply waiting for the onload callback and appending the image. I think it's reasonable to have a limit to how big of an image the user requests. Currently the promise still resolves, but it can also fail giving the user the opportunity to do something different. Does this seem reasonable? Overall, should we move forward with formalizing this proposal? |
That's a good demo. I think it's OK if UAs are allowed by break the contract for overly large images. I would like to move forward with the proposal. |
Ah yay, glad people are still wanting to work on this. I felt that when we split into two threads things kind of fizzled. Glad to see that's not the case. I'm happy to sign up for the spec work here, probably next week (this week is BlinkOn). If someone wants to get things started with some informal spec or algorithms or similar, even just in this thread, that would be a great headstart. E.g. what kind of phrasing you would use to enforce any normative requirements (of either the "must" or "should" variety). |
This seems very reasonable and it solves the problem in a way that createImageBitmap can't. I think the spec should be explicit about the fact that this API provides a "soft guarantee", especially if all implementations would otherwise be breaking the contract under RAM pressure. |
General +1 from me. I agree there are reasonable times to reject the promise (e.g. excessively large images). I think we probably want to experiment in the wild before we codify the cases under which this promise rejects, but in the meantime we should probably have a non-normative note in the spec that calls out the large image case. |
Notable design choices made: - Rejects for non-active documents (or documents that become non-active) - Immediately fulfills for vector graphics or other formats that do not require decoding - Fulfills for animated images after all of their frames are loaded, not just the first, ensuring jank-free animation Closes #2037. This also includes the editorial change of giving a <dfn> to the "update the rendering" step, and linking to it where it is mentioned.
This API alllows the author to request that the user agent decode the image, preferably off the main thread, so that when the returned promise fulfills, the image is ready to be inserted into the document, without causing dropped frames due to decoding delay. Notable design choices made: - Rejects for non-active documents (or documents that become non-active) - Immediately fulfills for vector graphics or other formats that do not require decoding - Fulfills for animated images after all of their frames are loaded, not just the first, ensuring jank-free animation Closes #2037. This also includes the editorial change of giving a <dfn> to the "update the rendering" step, and linking to it where it is mentioned.
This API allows the author to request that the user agent decode the image, preferably off the main thread, so that when the returned promise fulfills, the image is ready to be inserted into the document, without causing dropped frames due to decoding delay. Notable design choices made: - Rejects for non-active documents (or documents that become non-active) - Immediately fulfills for vector graphics or other formats that do not require decoding - Fulfills for animated images after all of their frames are loaded, not just the first, ensuring jank-free animation Closes #2037. This also includes the editorial change of giving a <dfn> to the "update the rendering" step, and linking to it where it is mentioned.
This API allows the author to request that the user agent decode the image, preferably off the main thread, so that when the returned promise fulfills, the image is ready to be inserted into the document, without causing dropped frames due to decoding delay. Notable design choices made: - Rejects for non-active documents (or documents that become non-active) - Immediately fulfills for vector graphics or other formats that do not require decoding - Fulfills for animated images after all of their frames are loaded, not just the first, ensuring jank-free animation Closes #2037. This also includes the editorial change of giving a <dfn> to the "update the rendering" step, and linking to it where it is mentioned.
This API allows the author to request that the user agent decode the image, preferably off the main thread, so that when the returned promise fulfills, the image is ready to be inserted into the document, without causing dropped frames due to decoding delay. Notable design choices made: - Rejects for non-active documents (or documents that become non-active) - Immediately fulfills for vector graphics or other formats that do not require decoding - Fulfills for animated images after all of their frames are loaded, not just the first, ensuring jank-free animation Closes whatwg#2037. This also includes the editorial change of giving a <dfn> to the "update the rendering" step, and linking to it where it is mentioned.
This thread is a spinoff of #1920. Around #1920 (comment) we came to the conclusion that there were two distinct use cases being addressed: the "deferring" use case, served by the content attribute discussed in #1920, and the "predecoding" use case, which I want to discuss here.
The tentative idea is something like:
In #1920 (comment) there was discussion as to whether scaling/cropping should be part of this, but it sounded like probably not.
Note that something similar can already be accomplished on the platform today, by using ImageBitmap and canvas:
This has a couple potential drawbacks:
aria-label
inferred from the original img'salt
; does not get access to right-click save image as)But in the end maybe it's enough to argue for not adding a new API for something that can already be done. What do people think?
/cc @vmpstr @smfr @ojanvafai @grorg
The text was updated successfully, but these errors were encountered: