Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

Already on GitHub? Sign in to your account

IE occasionally aborts image load #40

Open
bluescrubbie opened this Issue Oct 18, 2012 · 36 comments

Comments

Projects
None yet

We're using imagesloaded in a lazy-loading widget. A few of the initial images have hard coded src, the rest are inserted lazily from a data-src attribute. On IE9, the Network Developer tab shows the lazy images aborting on the first attemp and then immediately reloading successfully. However, the hard-coded images occasionally abort as well, and never get loaded. This happens irregularly, sometimes reloading with a clear cache 30 times before it happens again.

I can't reproduce the problem when I remove imagesloaded (the src is otherwise untouched for them).
So far, I've been unable to reproduce it on JSFiddle http://jsfiddle.net/bluescrubbie/VxFb4/12/.

I know it's obscure, but I thought I'd let you know.

Owner

desandro commented Oct 19, 2012

Thanks so much for reporting this issue. Since this is a bit tricky to reproduce, we're going to have to just leave this issue open. Hopefully others will come across this issue and chime in.

@IanLunn IanLunn referenced this issue in IanLunn/Sequence Nov 2, 2012

Closed

ie9 hangs on preloader #129

treacher commented Nov 8, 2012

I have come across this problem as well. It can be quite easily reproduced in IE9 with the following link: http://masonry.desandro.com/demos/images.html

If you go to this page and then refresh it a bunch of times you will notice that some times the images abort and some times they don't.

When I remove imagesLoaded the images do not seem to abort.

I stumbled on this issue today on one of our production websites that relies pretty heavily on imagesloaded.

If I disable cache I can't reproduce the error. There are some old gists that have fixes for IE9 caching issues, but they are dating back to 2011 (version 1.0.4). Could that still be the same bug/error ?

Collaborator

darsain commented Nov 20, 2012

@JanLaureys nope. That's a different issue. We haven't encountered this before.

I think this is an IE bug (SURPRISE) where IE sometimes fails to load images where we reset src. Unfortunately that's the only way how to reliably check the image state in IE whatsoever, so I don't even know where to start with fixing this.

But I might be wrong. I haven't tested the exact cause of this yet, but I can see it happening on link by @Galkon.

Korijn commented Dec 15, 2012

I've got the same issue, I'll try the bleeding edge version and see if I can find a fix. Any special programming guidelines you'd like me to apply?

tallhat commented Feb 24, 2013

i'm getting IE9 broken images some of the time (but fairly often) - other browsers seem ok. it's pretty random, would really really like to find a way to fix! :)

I can reproduce by following @Galkon 's method in IE9 on Win 7. Had a visitor complain about this today.

I ran into this issue on a project recently as well. In IE9, we would sometimes see images failing to load or load with corrupted data. When we saw corrupted images, Fiddler showed that IE would request the image, abort the request and then request the same image again. This makes sense from what's in the last few lines of the each() call in the imagesLoaded source on line 115:

if ( el.readyState || el.complete ) {
   el.src = BLANK;
   el.src = src;
}

Whether or not the initial request is aborted or not seems to depend on whether the request can completely finish (or not trigger at all) before we hit these lines, which is 100% indeterminate. That explains why it's such an intermittent problem.
The workaround I ended up using on the project is a modification of the basic idea above. However, instead of changing the src attribute on the image element itself, it creates a new element with the same src, setting an event handler beforehand so we make sure we don't miss anything. Then, if we catch an event from either element, we can be pretty confident that the same event happened (or will happen) on the other one. From the initial testing I've done, this seems to eliminate the aborted requests and corrupted images. Also, IE appears smart enough to not send out another HTTP request for the temporary image element, which is great.
The source for my workaround is below. It's clearly not as versatile as imagesloaded but hopefully the ideas are useful.

//function for executing a callback when all images in the jQuery object are loaded (or fail).
$.fn.waitForImages = function (callback){
    var $images = this.find('img').add(this.filter('img')),
        loaded = [],
        temporary = [];


    if ($images.length < 1){ //no images to wait for, trigger immediately
        setTimeout(callback, 0);
        return;
    }

    function loadHandler(event){

        //get a reference to the original image that this event is referring to
        var img = $(this).data('originalImage') || this;

        if ($.inArray(img, loaded) === -1){
            loaded.push(img);
        }

        if (loaded.length >= $images.length){ //all images are done, clean up and schedule the main callback

            //remove all added event handlers on original img elements
            $images.unbind('load error', loadHandler);

            //remove all added event handlers on temporary img elements 
            for (var i=0; i<temporary.length; i++){
                temporary[i].unbind('load error', loadHandler);
            }

            //DONE!!!
            setTimeout(callback, 0);
        }
    }               

    return $images
        .bind('load error', loadHandler)
        .each(function( i, el ){ //triggers the load event on images we already know are done

            if (this.complete){ //true in Chrome and FF for loaded and failed images; true in IE for loaded images ONLY
                $(this).load();
            } 

            else if (this.readyState){ //special cases for IE
                if (this.src.lastIndexOf('/') === this.src.length - 1){ //src was set to the empty string; IE stores this as the window url without the filename
                    $(this).load();
                } else { 
                    //hack for getting an event triggered in IE so we can tell whether or not
                    //the image failed or if we're still waiting for it. We'll create another img element,
                    //attach an event handler to it, and give it the same src. If either the original or this
                    //temporary element fire an event, then we'll know what happened and for all purposes can assume the same thing 
                    //happened to the other one. Notice that we don't need to add the temporary img element to the DOM.
                    var $tempImg = $('<img />');
                    temporary.push($tempImg);
                    $tempImg.bind('load error', loadHandler);
                    $tempImg.data('originalImage', this); //attach a reference to the original element to the temporary one; we'll use this
                        //later so we don't double count events
                    $tempImg.attr('src', this.src);
                }
            }
        });
}
Collaborator

darsain commented Mar 8, 2013

Yeah. Creating a temporary element for each unresolved image would definitely solve any issues attached to hard resetting the original's src. I'll dig into it later. Thx for an idea! :)

I'm actually doing this very thing in several other websites/libraries, wonder why it never clicked to me that it could be used to replace the src reset.

Owner

desandro commented Mar 8, 2013

My only concern is how this affects memory. Can this be done as a fallback, so we're not duplicating every image?

Collaborator

darsain commented Mar 8, 2013

@desandro is the image fully loaded in the memory even when it is not in the DOM?

I ran into this recently as well, and had to fix in a hurry - I appended

if ( el.readyState || el.complete ) {
                el.src = BLANK;
                el.src = src+"?" + new Date().getTime();
            }

Didn't really have the time yet to check the implications (I know that CDN's would hate it...), but it appears to work for me.

oporko commented Apr 16, 2013

I've also been affected by this issue, very problematic for me because it intermittently prevents a large background image from loading on a very visual site. It seems to happen in IE10 as well as IE9.

euanlau commented Apr 23, 2013

I am affected by this issue as well. I am working on a prototype that uses imagesloaded. I really like imagesloaded and appreciate all the hard work that is put into it, but this bug makes it unusable pretty much.

rglepper commented May 2, 2013

I'm having this same issue. It happens randomly on ie8 and ie9 affecting images that are big (more than 200KB)

Collaborator

darsain commented May 16, 2013

I've finished my next iteration on ImagesLoaded. It is a draft, but it uses a new determination process, so I'd like people to test it out before I continue with this. It should solve the issues above.

You can grab the code here: imagesloaded.js
And read the documentation here: Darsain/imagesloaded

The API is completely changed, so reading the docs is recommended.

Haven't written tests yet so there might be bugs.

Same issue here with IE10. Here's a simple example which actually breaks on IE9 as well.

Collaborator

darsain commented May 18, 2013

@alebelcor that example breaks everywhere, because it doesn't work. $ is not jQuery, and it seems you can't hotlink from imgur (at least for me the images are 403 - Forbidden).

Also, perhaps you could take a look at the message riiiight above you? It contains an ImagesLoaded version with a new way of determining images loading which should fix current issues, and needs to be tested.

Owner

desandro commented May 27, 2013

v3 has tests passing IE9. I recommend you upgrade imagesLoaded to v3 and report back if you continue to experience issues.

I have found that this issue cannot be replicated in all IE installs. There is one computer with IE which this can almost always be replicated when requesting a substantial number of images (20+), while it never happens on my computer (the one I used to implement the code). It appears that the browser aborts the images from loading. [Insert not so kind words about IE here]. Not even sure where to go from here.

I had implemented the v3 and the same issue kept occurring. I then created a page with 50+ images, no JavaScript at all and loaded it on the problematic computers which still presented the problem. After more testing, we found out that the computers which still had this issue were using a German proxy (rest of us are on US networks). I am not sure if this helps anyone but it seems that the 'IE aborting images request' problem that I was having had nothing to do with this plugin and an intrinsic problem with IE and some network configurations. I should also add that the image URLs we use, are actually redirects to images on different servers but we have not determined if that is related or not.

Owner

desandro commented Jul 25, 2013

@generalChaos Thanks for following up.

Just wanted to chime in here and say that I also have encountered this problem, including with the most recent 3.0.4 release of imagesLoaded and in all versions of IE (that is, 8, 9 and 10). Essentially, some images will not be loaded and are displayed as a black X, although they maintain their (CSS-defined) size/position properties in IE9 and 10. Sometimes only 1 or 2 images (out of say 20) will run into this issue, other times most of them will fail. Network profile shows that the http requests for the images in question are aborted. No script errors in console in any versions of IE.

As generalChaos mentioned it does seem to be in some way related to network speed/configuration, like maybe the requests are aborted if they are not completed fast enough. However, I've encountered this on both staging web servers and local dev installs, so I'm not positive about this (as the image requests should be satisfied rather quickly when retrieving them from localhost).

I've run into this issue twice on different projects, one using isotope/mosaic and another using maxImage and jquery.cycle. In both instances removing imagesLoaded fixed the image loading problems. I'm sorry I don't have more insight to offer, just wanted to mention that I've run into this as well using imagesLoaded with Internet Explorer. That being said this is a fantastic plugin that works flawlessly on all other browsers and I love it!

We noticed this issue when IE was aborting requests on hidden images. Whenever we tried to open a modal gallery with images from the same path, the requests would return a 304 for aborted requests!

It's a little domain specific to our use case, but, here's how we were able to address it:

var loadFaultTolerantImage = function(src) {
    var attempts = 0;
    var $image = $("<img>", {
        alt: "",

        // Important to help IE reset image width/height after a
        // failed load. This prevents a cache-busted image from
        // having a width and height of 28x30
        css: {
            height: "auto",
            width: "auto"
        }
    });
    var image = $image.get(0);

    image.onerror = function() {
        // To prevent infinite loops, stop trying after
        // three attempts
        if (attempts++ < 2) {
           this.src = src + "#ie-cache-bust";
        }
    };

    image.src = src;

    return $image;
};

We've found this works quite well, but I do not admit that it is perfect. Any thoughts on this solution?

@desandro desandro referenced this issue in metafizzy/isotope Oct 20, 2013

Closed

Images Not Displaying in IE 9 #550

Hello,

I updated to the latest version of imagesloaded from here: http://desandro.github.io/imagesloaded/
Specfically, I am using this javascript file: http://desandro.github.io/imagesloaded/imagesloaded.pkgd.js

It seems to have fixed the image not displaying issue, which is awesome, but...

It seems to have a side effect of not loading the initial grid of images.

You can see what I mean by going here:

http://jr-watkins.tumblr.com/

Also, FYI I was not seeing the network related issues mentioned above.

Quick update. I had to revert back an older version of imagesloaded since it was deemed that the images not displaying in IE was a better experience than no images loading on the initial page load.

So for now, my example of the issue at http://jr-watkins.tumblr.com/ is back to where I started with the images randomly not displaying for IE.

Just a quick note @mikemuggli: I was having the exact same issue with IE9 and IE10 in isotope, but commenting out the imagesLoaded bit from isotope and including the file you mentioned above worked perfectly for me! Are you sure you commented out / removed the imagesLoaded function from isotope?

edit: oh and by the way - you have an error on your page in relation to imagesLoaded (Uncaught TypeError: undefined is not a function imagesloaded.js:93)

nice page btw :)

@lupik lupik referenced this issue in metafizzy/isotope Oct 30, 2013

Closed

mishmash on loading isotope layout in Chrome #558

I met this issue on both IE 9 and IE10. Bxslider occasionally keeps the bx-loader div all the time. It's kind of annoying.

I can confirm this error occurs sporadically in IE11 as well.

Up, this bug is still present in IE11

deajan commented Nov 26, 2014

@desandro Just in case this might help, i had various troubles with images not loading under IE (giving DOM7009 errors among others) where all other browsers worked great. I found out that the color depth of the image was a cause, all browsers except IE could load 32bit depth images. Once converted to 24bit, IE just worked fine.
Hope this might help :)

taseenb commented Jan 14, 2015

Same problem here on IE11. I was hiding the images with display:none and visibility:hidden. I removed both and it works. An alternative way to hide images is:

.hidden-images {
  position: absolute;
  z-index: -9999;
  left: -9999px;
  top: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

deajan commented Jan 16, 2015

@taseenb Can you give a quick code example ? I don't really get what you're doing.

taseenb commented Jan 16, 2015

@deajan imagine you put all the images you need to preload in the dom:

<div id="images-to-preload" class="hidden-images">
    <img src="image1.jpg">
    <img src="image2.jpg">
    <img src="image3.jpg">
    <img src="image4.jpg">
</div>

Of course, you don't want them to be visible.
So you add the css for .hidden-images that will just move them off screen.
And finally you can use imagesloaded.

deajan commented Jan 16, 2015

@taseenb Thanks... I'll try to adapt this to my drupal isotope module see if it gets my problem solved.

I believe I've found the same error in my WinJS project, so I guess it's perhaps an issue going forwards

@desandro desandro changed the title from IE9 occasionally aborts image load to IE occasionally aborts image load Jun 13, 2016

@desandro desandro removed this from the v3 milestone Jun 13, 2016

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment