19

PLUGIN

I am using a jQuery plugi called lazyload.

What this does is lazy load images - meaning it does not render them in the browser until the image is within the scope of the viewport.

This is useful when you have a page that has many images, for example, and you don't want it to spend forever with the initial load.

FIREFOX

Ok, so I am also using Firefox version 23.0.1

PROBLEM

The plug in is great, however when scrolling down after some images I start getting errors where the image doesn't load (just has a generic place holder for a broken image link) and in the console it logs:

Image corrupt or truncated: [image url]

It is not that there is a problem with the image. They all render fine individually.

It is not on a SPECIFIC image as it is random. If I load the page again, the images that were corrupt may load now, with other images returning a broken link and logging corrupt in the console.

I searched around for this, and it seems that there is some problem with simultaneous fetches for an <img> src tag.

Possibly there should be a delay set on the fetch, however you cannot always tell how long the delay should be. And if one image is larger than another, it could still conflict (with a static delay time, as opposed to a complete callback).

Therefore, I would like to request:

a) If anybody knows of a solution to this (such as catching when the error occurs and re-triggering the load image function)
b) If anybody can propose an $.extend() to the library above (lazyload) that would create a callback function and wait until all active fetches are complete before loading the next one (IF this is the problem - I am not sure if it is) I am not a jQuery ninja so I am a little lost on the code. I could figure it out, but it would probably be dirty...
c) if this is NOT the problem, then some direction as to how I can solve this would be appreciated

shilovk
  • 11,718
  • 17
  • 75
  • 74
Walker Farrow
  • 3,579
  • 7
  • 29
  • 51
  • Check your network tab in your browser console/developer tools. How do the image requests look like? What headers are you receiving from the server? p/s: `If anybody can propose an $.extend() to the library above`... that's not how SO works. – Terry Sep 08 '15 at 21:27
  • Thanks - I checked the network tab and each file is called and gets an HTTP status 200 code. So the file exists. Some render, some dont. It doesn't seem particular to file size. Anything else I should check? ... – Walker Farrow Sep 08 '15 at 22:46
  • 1
    could you share the code in jsfiddle, its hard to predict what causing the issue. – Pavan Kumar Jorrigala Sep 11 '15 at 02:07

2 Answers2

7

As suggested on this answer to a problem similar to yours:

It appears that when changing the src attribute of the img tag, Firefox fires a load event. This is contrary to the HTML5 specification, which says that if the src attribute is changed, then any other fetch already in progress should be ended (which Firefox does), and no events should be sent. The load event should be sent only if the fetch was completed successfully. So I'd say that the fact that you get a load event is a Firefox bug.

And then:

The best option may be to create a new element each time you wish to change the src attribute.

Which makes sense. Inside lazyload code, you'll find this one part, that seems to be when the image loads, responding to an scrolling event that triggers appear:

    /* When appear is triggered load original image. */
    $self.one("appear", function() {
        if (!this.loaded) {
            if (settings.appear) {
                var elements_left = elements.length;
                settings.appear.call(self, elements_left, settings);
            }
            $("<img />")
                .bind("load", function() {

                    var original = $self.attr("data-" + settings.data_attribute);
                    $self.hide();
                    if ($self.is("img")) {
                        $self.attr("src", original);
                    } else {
                        $self.css("background-image", "url('" + original + "')");
                    }
                    $self[settings.effect](settings.effect_speed);

                    self.loaded = true;

You can put an AND operator followed by some flag or fuction return that verifies if the last image is already fully loaded on that part:

if ($self.is("img") && lastImageIsLoadde() === true) { /*pseudocode here*/

thus preventing that img src gets replaced before its correct time (since settings.placeholder is the image the script takes stand in the place of the one about to be loaded when scrolling) and see if it works for you.

Community
  • 1
  • 1
al'ein
  • 1,711
  • 1
  • 14
  • 21
  • That solution is though upon the idea that it'll be out of hand for you to create a new `` tag each time the viewport scope triggers the event. If it isn't a problem, then you should consider the linked answer (as I think you already have done :) ) – al'ein Sep 17 '15 at 19:23
  • 1
    thanks. This more or less points me in the right direction. What I think the actual problem is how Firefox handles memory for so many image tags opened at once. So I am going to modify this code so that when the image "disappears" from the viewport, it removes the img itself (or something like this). Hopefully this clears the mem. We will see... Tks – Walker Farrow Sep 17 '15 at 19:26
0

I would check first if you have an updated version of the lazyload library. https://github.com/tuupola/jquery_lazyload/blob/master/jquery.lazyload.min.js

Currently v 1.9.7 is the latest. It could be a bug they already fixed. ( changelog: https://github.com/tuupola/jquery_lazyload/blob/master/CHANGELOG.textile )

Secondly, wich jQuery version are you using? Maybe a very old jQuery with an old lazyload library causes this problem? (Or maybe the newest jQuery?)

If that's all fine, maybe you can look into how the lazyload is initiated? Do you have ajax-requests and re-initiate the lazyloading? (Should not cause problems, but you never know). Or try different doctype/html structure?

If nothing works, I would 'strip down' the html document to a really clean version where the lazyloading works (just localhost testing, or jsfiddle or something) and put back parts one by one. Eventually you should see where the functionality breaks.

With jQuery v1.9.1 and Lazyload v1.9.7 it should just work with this:

$('.lazy').lazyload();

Here is a jsfiddle for testing: http://jsfiddle.net/web_nfo/21qb88v1/

Or maybe Firefox is just the problem. Currently version 40 is the recent one. Maybe you also have a 'beta' version installed? Or safe-mode on?

Roel
  • 447
  • 4
  • 11