Open Bug 626613 Opened 11 years ago Updated 1 year ago

'onload' event for images is fired when loading begins, and not when it's finished

Categories

(Core :: DOM: Events, defect, P5)

x86
Windows XP
defect

Tracking

()

UNCONFIRMED

People

(Reporter: maikstoeckmann, Unassigned)

Details

Attachments

(3 files)

User-Agent:       Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)
Build Identifier: Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.9.2.13) Gecko/20101203 Firefox/3.6.13 GTB7.1 ( .NET CLR 3.5.30729)

Javascript example - function that will be executed by user click:

var div = document.createElement("div"); document.appendChild(div);
var img = document.createElement("img"); div.appendChild(img);
img.opacity = 0.5;
img.onload = function(){div.backgroundColor = "red"};
img.src = "example.png";

Reproducible: Always

Steps to Reproduce:
see 'details'
Actual Results:  
image's background is set to red immediately

Expected Results:  
The expected behavior would be that image's background should is set to red when image loading has finished, in almost the same manner like the document.onload event. By the way, in InternetExplorer image.onload is fired correctly when image has been completely loaded.
Version: unspecified → 3.6 Branch
Reporter -> Are you still experiencing this issue with the latest version of Firefox 5? Does the issue occur with the latest nightly? http://nightly.mozilla.org/
Yes, this issue still occurs with the nightly build of 26-Jun-2011, and with the latest version of Firefox 5, too. You can test it here:

http://hm.denkmalgis.de/

If you zoom into the map (by mouse wheel up), the image tile div's background is set to white by "image onload" event. On Firefox the background is set BEFORE the image is really loaded. On IE the background is set AFTER the image has been loaded. Once the image has been saved to cache, this issue disappears. So you have to clean up the cache to test it again.
Version: 3.6 Branch → Trunk
I confirm the issue still occurs in Firefox 5 and Firefox 6 beta. Firefox is the only browser that does not handle the image onload event properly.
I see the issue on Mozilla/5.0 (Windows NT 5.1; rv:8.0a1) Gecko/20110711 Firefox/8.0a1 ID:20110711030829

See Bug 521894 - is this the same/related issue?
Component: General → DOM: Events
Product: Firefox → Core
QA Contact: general → events
This testcase does NOT show the problem for me.  The div turns red only after the image has finished loading.

Do you see something different on this testcase, if not, can you attach a testcase that shows the problem you're seeing?  The site cited in comment 2 has a _lot_ of things going on, and it's not clear to me which parts are actually relevant to the issue at hand, so if you have anything smaller that shows the problem it would be very helpful.
I agree your testcase clearly shows that the onload event is working for a single image.
I have tried loading a bigger image, to have time to see it appear progressively, and it is true the onload event is fired when the image is totally displayed.

Anyway, I still get this onload event problem on an application very similar to the one mentionned in comment 2. Is there a problem when the page contains many images ?
Try to visualize the site in comment 2 on Firefox and Chrome. On Firefox, try zooming with the mouse wheel. You will experience "white screens" because lower levels images (lower resolution) are removed too soon (the onload event of higher level images is fired too soon). On Chrome, images are displayed all the time when zooming, because lower level images are removed only when higher level images are fully loaded.

I will try to write a testcase showing the problem.
I do see the problem on the site from comment 2, yes.  It also has a huge amount of script that's difficult to make sense of without a huge time investment.

If you can create something smaller that shows the problem, that would be great.  Clearly there's a missing ingredient in my testcase, but I just can't tell what it is.
Bertrand -> Any luck getting a reduce test case that exhibits the issue?
Attached file TestCase 2
I think I have the same problem on a web aplpication under development.
It may currently be more easily visible in Aurora (if that's the same bug).
Try the "TestCase 2" of the latest build (9.0a2 (2011-10-18))

The image appears very slowly but the onload event seems to trigger immediately.
I'm not sure it meets specifications : In a web application, we need to be sure that all images are fully loaded and totaly displayed before running a fadeIn effect.
But I did not find any js/DOM event for that, except the onload event.
Attachment #567999 - Attachment mime type: text/plain → application/zip
Stephane, you're seeing something else, I think, and it's specific to large jpegs.  In particular, image decode for that image is somewhat slow for some reason, and image decode does not block the image's onload.  Please file a separate bug on that?
Per bug 695859 comment 0 this should be fixed in Nightly 12
Well, comment 10 should be.  The original bug report here, unclear....
Sorry for the long delay, but I was completely over-worked for months. No, with Nightly 12.0a1 it's the same problem. But now I extracted the relevant line from the huge Javascript files to one simple test case, that you can open here:

http://maps.kulturlandschaft-informatik.de/xxxtest/

There is a red div in the document body, and when the image.onload-event is fired, then it's color is set to green. As you see, the green color comes before the image data is loaded and displayed. I suppose, that it has to do with the fact, that the image es loaded from a dynamic source (PHP script)?
In addition to my message from yesterday: I now have noticed, that the problem only appears under some circumstances. It seems to have something to do with the cache and how many images are stored. I can regularly reproduce the problem this way:

1. Load http://maps.kulturlandschaft-informatik.de/xxxtest/ in the first tab
2. Open another tab and load http://www.kleks-online.de/
3. Go back to the first tab an click the Reload button (F5)

As of now, the problem occurs with every reload. But if I clean up the browser cache, the testcase runs properly again.
The same happens for me with Firefox 11 (Ubuntu Linux): onload event fires before image is completely loaded (rendered). In onload event handler all image properties are present and are correct (such as width, height, naturalWidth, complete=true, etc), so there is no way to 'catch' this situation.

It only happens with cached on disk images for which Firefox sends If-modified-since request (and receives back '304 not modified'). It doesn't happen on newly loaded images. 

It looks like onload fires before image is fully read from disk cache.

p.s.
The test case by Maik Stöckmann does replicate this problem for me.
Oleksiy, that sounds like exactly what I described in comment 10.  And the fix for it should be in Firefox 12, per comment 11.  Are you seeing the issue in current 12 beta build?
Hi, I'm on Firefox 15 recently installed over Ubuntu 12.04. I can confirm that the behavior described in comment #15 is still alive. Im working on a javascript function that loads dinamically an image and draw it to a canvas. If my server returns "Not Modified - 304" on the image headers the onload function is not fired. If I clean the cache and reload it works once.

Its hard to make a downladable test case for this because it needs an apache server involved. Appending a "?rnd="+Math.random()*10000 in the image.src acts as a workaround for now but Opera and Chrome shows correct behavior.
sombra2eternity@gmail.com, there's no need for a downloadable testcase.  Just a link that actually reproduces the problem reliably would be great!
I have seen that the code works ok when there is no CSS style using the same image for a border-image property. So I added a style for test.
(In reply to Boris Zbarsky (:bz) from comment #18)
> sombra2eternity@gmail.com, there's no need for a downloadable testcase. 
> Just a link that actually reproduces the problem reliably would be great!

I just created an attachment, if you can test it it works ok on chrome, but in firefox you only see the "alert(1)" once. If you change the src assignation for the commented line (the one with the random statement) you will find that it works always. If you need the server code for image loading I'll attach it too but its a fairly simple code that only checks the if-modified-sice header.

The problem here is that firefox in ver 15 send new headers (if-modified-since ...) that active some server features that was not activated in early versions. The firefox code against those features seems a bit untested. If you load several times the image via URL with tamper data opened you will see the 304 header too, but the image loads as expected, it only fails when loaded over javascript and get a 304.

Anyway, I find that the code works right when no CSS border-image using the same image loaded is present. Too weird :/
The point is that I've tried to reproduce this before with 304s and not been able to.  So your exact server setup is possibly relevant.  Is there a link that shows this happening against your server?

Though actually, could you please file a separate bug on your issue?  You're saying you don't see an onload event at all, whereas this bug is about is firing too early in some cases...
(In reply to Boris Zbarsky (:bz) from comment #21)
> The point is that I've tried to reproduce this before with 304s and not been
> able to.  So your exact server setup is possibly relevant.  Is there a link
> that shows this happening against your server?
> 
> Though actually, could you please file a separate bug on your issue?  You're
> saying you don't see an onload event at all, whereas this bug is about is
> firing too early in some cases...

Fair enought, I will open a new bug later for this, could you confirm that my attached test case works for you, its important the border-image point.
I can confirm that this bug also/still exists in Firefox 46.0.1 on OS X 10.11.5.

Reproducible with the following HTML:

    <html>
      <head>
        <script type="text/javascript">
          document.addEventListener("DOMContentLoaded", function() {
            var img = document.createElement("img");

            img.style = "background-color: red;";
            img.onload = function() {
              document.body.appendChild(img);
            };

            img.src = "http://placekitten.com/5000/5000";
          });
        </script>
      </head>

      <body></body>
    </html>
What that testcase shows is comment 10.
Seth, did we switch away from having onload blocked on decode?  Comments above suggest it was working in Firefox 12...
Flags: needinfo?(seth)
(In reply to Boris Zbarsky [:bz] (Out June 25-July 6) from comment #25)
> Seth, did we switch away from having onload blocked on decode?  Comments
> above suggest it was working in Firefox 12...

Yes, we deliberately moved away from that in bug 1174923. Previously we sometimes blocked onload until the image finished decoding, and we sometimes didn't, depending on the situation. Now we never do, consistently. This improves page load performance since we can overlap image decoding with running the JS associated with the load event and the probable resulting layout flushes, style flushes, etc. The new behavior is consistent with the spec.

This is not a problem in the vast majority of cases because of predictive image decoding (which unfortunately we don't have for CSS images; it's on the todo list). However, we can't realistically predict anything about the situation where JS is loading an image that's not in the document, as in comment 23. We don't know at what size such an image will be drawn or whether it will ever be displayed at all.

The right solution in cases like comment 32, if the developer needs guarantees about this, is to either create an ImageBitmap rather than just an Image (that's ideal) or to draw the image to a canvas once it's loaded, forcing it to be decoded (suboptimal but will also work).
Flags: needinfo?(seth)

Bulk-downgrade of unassigned, 4 years untouched DOM/Storage bugs' priority.

If you have reason to believe this is wrong (especially for the severity), please write a comment and ni :jstutte.

Severity: normal → S4
Priority: -- → P5
You need to log in before you can comment on or make changes to this bug.