Open Bug 844245 Opened 12 years ago Updated 2 years ago

need a way to find out when an image is ready to display

Categories

(Core :: DOM: Core & HTML, defect, P5)

18 Branch
defect

Tracking

()

People

(Reporter: djf, Unassigned)

Details

In desktop browsers displaying web content, the time to load an image file over the network is generally much greater than the time required to decode that image for display. For mobile apps, however, the situation may be reversed because images may come from the local file system and the CPU is lower powered. Bug 837909, for example, is about the FirefoxOS Gallery app. It loads 2 megapixel photos from the local SD card quite quickly, but the image does not appear on screen for 500 to 1000 ms after the image 'load' event is delivered. In that bug I have a small preview image displayed, and want to replace it with the full-size image. But I want to do this seamlessly, without displaying a blank screen, so I need to know when the full 2 megapixel image is ready to be displayed. The load event does not help here. I need something like the 'canplay' event that video and audio tags have. For the gallery app I have had to resort to using setTimeout() which is obviously a horrible hack.
Cc'ing Chris, Vivien and Kevin because I've discussed this bug with all of them.
Does imagelib even tell the DOM when decoding is done?
Anything implementing imgINotificationObserver receives a DECODE_COMPLETE notification.
Part of the trickiness here is that a "has been decoded" event only makes sense if content can also ask the UA to start decoding the image. I'm not ashamed to admit that I'm nowhere near smart enough to understand the current "automatic" start-decoding logic. So the request here is for both a "please decode this" API and also a "has been decoded" notification. It's possible to drawImage() to a <canvas> to force an image to be decoded, but then that throws away all our logic to decode in chunks for UI responsiveness. So another "fix" for this would be off-main-thread canvas.
Thanks for opening this David. Just wanted to mention Bug #818765 here as well, which the fix includes a setTimeout with an arbitrary number to get around this issue. If/when this addressed we should remove the setTimeout in that fix.
For img elements (and not style images like background or borders images) if they are in the dom and they are not display: none and they are not in a document that has isActive == false (ie in a hidden tab) then they should be decoded. I think that is right. Bug 689623 will change this shortly, but only on desktop. The strategy for mobile and b2g will probably need to be somewhat different and will be a separate issue. In particular I haven't thought much about b2g yet, so we can shape what kind of behaviour we want there.
What's wrong with the load event?
> For img elements (and not style images like background or borders images) if they are in > the dom and they are not display: none and they are not in a document that has isActive > == false (ie in a hidden tab) then they should be decoded. Suppose I have a blob URI B for a large JPEG image and I do var elem = document.createElement('img'); elem.src = B; document.body.appendElement(elem); If I understand the above correctly, it's suggesting that appendElement must block until we decode B, right? I don't think appendElement blocks, so I don't see how the above can be right.
(In reply to Justin Lebar [:jlebar] from comment #8) > > For img elements (and not style images like background or borders images) if they are in > > the dom and they are not display: none and they are not in a document that has isActive > > == false (ie in a hidden tab) then they should be decoded. > > Suppose I have a blob URI B for a large JPEG image and I do > > var elem = document.createElement('img'); > elem.src = B; > document.body.appendElement(elem); > > If I understand the above correctly, it's suggesting that appendElement must > block until we decode B, right? I don't think appendElement blocks, so I > don't see how the above can be right. You're right of course. I didn't word it correctly. "then they should be decoded" should probably read something like "then they will either be decoded or queued for decoding". I was answering the question of what conditions would "ask" for a decode of an image, not when the decode is complete.
OS: Mac OS X → All
Hardware: x86 → All
We currently do 5ms of decoding when an image finishes loading from the network (and all the other conditions tn mentioned in comment 6 are true). Bug 841579 will actually make it so that, in this case, onload doesn't fire until the image *finishes* decoding. Will that be enough? Or do you need something more formalized in the DOM, like <img ondecode=>?
Decode should be blocking the load event in most cases today, AIUI.
Ugh, ok, so decode blocks the document onload, but not the load event on the image. /me sighs
(In reply to Joe Drew (:JOEDREW! \o/) from comment #10) > We currently do 5ms of decoding when an image finishes loading from the > network (and all the other conditions tn mentioned in comment 6 are true). > Bug 841579 will actually make it so that, in this case, onload doesn't fire > until the image *finishes* decoding. > > Will that be enough? Or do you need something more formalized in the DOM, > like <img ondecode=>? Having onload not fire until the image is decoded would enable a brittle fix for my gallery issue, and it would be much, much better than using setTimeout() like I am now. I don't know if the HTML spec has anything to say about this, and my sense that this is just a gecko implementation detail is why I describe the fix as brittle. I'll take it though. Is the patch in bug 841579 something we could uplift to b2g-18? Or too risky? For a more full-featured solution you could consider emulating HTMLMediaElement and firing a metadataloaded event when the image size was available and an 'canplay' or 'canshow' event when decoding is done. I don't know if it is worth trying to shepard something like that through the standards process.
Blocks: 889728
Do we have any plans to implement David's suggested solution (emulating HTMLMediaElement) or uplift 841579 to b2g-18? I'm running into this issue with leo devices where the camera is capable of capturing larger images and the settimeout workaround is not sufficient. I've tested mc builds and can confirm that this issue does not reproduce. Thanks, Mark
No longer blocks: 889728
https://bugzilla.mozilla.org/show_bug.cgi?id=1472046 Move all DOM bugs that haven’t been updated in more than 3 years and has no one currently assigned to P5. If you have questions, please contact :mdaly.
Priority: -- → P5
Severity: normal → S3
You need to log in before you can comment on or make changes to this bug.