Last Comment Bug 626613 - 'onload' event for images is fired when loading begins, and not when it's finished
: 'onload' event for images is fired when loading begins, and not when it's fin...
Status: UNCONFIRMED
:
Product: Core
Classification: Components
Component: DOM: Events (show other bugs)
: Trunk
: x86 Windows XP
: -- normal (vote)
: ---
Assigned To: Nobody; OK to take it and work on it
:
Mentors:
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2011-01-18 04:06 PST by Maik Stöckmann
Modified: 2016-06-21 21:25 PDT (History)
11 users (show)
See Also:
Crash Signature:
(edit)
QA Whiteboard:
Iteration: ---
Points: ---
Has Regression Range: ---
Has STR: ---


Attachments
Testcase with the code from comment 0, with some obvious typo fixes (409 bytes, text/html)
2011-07-11 20:56 PDT, Boris Zbarsky [:bz] (Out June 25-July 6)
no flags Details
TestCase 2 (223.18 KB, application/zip)
2011-10-19 03:38 PDT, Stephane
no flags Details
Test for javascript loading image when server returns 304 (934 bytes, text/plain)
2012-09-04 07:05 PDT, sombra2eternity
no flags Details

Description Maik Stöckmann 2011-01-18 04:06:05 PST
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.
Comment 1 Tim (fmdeveloper) 2011-06-26 14:11:29 PDT
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/
Comment 2 Maik Stöckmann 2011-06-27 00:10:32 PDT
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.
Comment 3 Bertrand Gervais 2011-07-11 07:55:47 PDT
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 Tim (fmdeveloper) 2011-07-11 20:38:10 PDT
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?
Comment 5 Boris Zbarsky [:bz] (Out June 25-July 6) 2011-07-11 20:56:39 PDT
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 Bertrand Gervais 2011-07-12 01:04:08 PDT
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.
Comment 7 Boris Zbarsky [:bz] (Out June 25-July 6) 2011-07-12 05:52:37 PDT
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 Tim (fmdeveloper) 2011-08-27 14:44:54 PDT
Bertrand -> Any luck getting a reduce test case that exhibits the issue?
Comment 9 Stephane 2011-10-19 03:38:12 PDT
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.
Comment 10 Boris Zbarsky [:bz] (Out June 25-July 6) 2011-10-19 08:33:27 PDT
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 j.j. 2012-01-07 15:40:00 PST
Per bug 695859 comment 0 this should be fixed in Nightly 12
Comment 12 Boris Zbarsky [:bz] (Out June 25-July 6) 2012-01-09 21:19:35 PST
Well, comment 10 should be.  The original bug report here, unclear....
Comment 13 Maik Stöckmann 2012-01-18 12:12:13 PST
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)?
Comment 14 Maik Stöckmann 2012-01-19 06:57:08 PST
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 Oleksiy Krivoshey 2012-04-06 02:21:55 PDT
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.
Comment 16 Boris Zbarsky [:bz] (Out June 25-July 6) 2012-04-06 13:21:52 PDT
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 sombra2eternity 2012-09-04 06:01:37 PDT
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.
Comment 18 Boris Zbarsky [:bz] (Out June 25-July 6) 2012-09-04 06:10:13 PDT
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 sombra2eternity 2012-09-04 07:05:58 PDT
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 sombra2eternity 2012-09-04 07:17:29 PDT
(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 :/
Comment 21 Boris Zbarsky [:bz] (Out June 25-July 6) 2012-09-04 07:20:07 PDT
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 sombra2eternity 2012-09-04 07:24:43 PDT
(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 Ian Lesperance 2016-06-06 14:28:49 PDT
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>
Comment 24 Boris Zbarsky [:bz] (Out June 25-July 6) 2016-06-06 14:38:27 PDT
What that testcase shows is comment 10.
Comment 25 Boris Zbarsky [:bz] (Out June 25-July 6) 2016-06-06 14:39:54 PDT
Seth, did we switch away from having onload blocked on decode?  Comments above suggest it was working in Firefox 12...
Comment 26 Seth Fowler [:seth] [:s2h] 2016-06-21 21:24:37 PDT
(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).
Comment 27 Seth Fowler [:seth] [:s2h] 2016-06-21 21:25:02 PDT
Ack, s/comment 32/comment 23/ above.

Note You need to log in before you can comment on or make changes to this bug.