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

UNCONFIRMED
Unassigned

Status

()

Core
DOM: Events
UNCONFIRMED
6 years ago
10 months ago

People

(Reporter: Maik Stöckmann, Unassigned)

Tracking

Trunk
x86
Windows XP
Points:
---

Firefox Tracking Flags

(Not tracked)

Details

Attachments

(3 attachments)

(Reporter)

Description

6 years ago
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.

Updated

6 years ago
Version: unspecified → 3.6 Branch

Comment 1

6 years ago
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/
(Reporter)

Comment 2

6 years ago
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.

Updated

6 years ago
Version: 3.6 Branch → Trunk

Comment 3

6 years ago
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.

Comment 4

6 years ago
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
Created attachment 545316 [details]
Testcase with the code from comment 0, with some obvious typo fixes

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.

Comment 6

6 years ago
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.

Comment 8

6 years ago
Bertrand -> Any luck getting a reduce test case that exhibits the issue?

Comment 9

6 years ago
Created attachment 567999 [details]
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.

Updated

6 years ago
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?

Comment 11

5 years ago
Per bug 695859 comment 0 this should be fixed in Nightly 12
Well, comment 10 should be.  The original bug report here, unclear....
(Reporter)

Comment 13

5 years ago
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)?
(Reporter)

Comment 14

5 years ago
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.

Comment 15

5 years ago
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?

Comment 17

5 years ago
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!

Comment 19

5 years ago
Created attachment 658067 [details]
Test for javascript loading image when server returns 304

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.

Comment 20

5 years ago
(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...

Comment 22

5 years ago
(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.

Comment 23

11 months ago
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)
Ack, s/comment 32/comment 23/ above.
You need to log in before you can comment on or make changes to this bug.