aFarkas / lazysizes

High performance and SEO friendly lazy loader for images (responsive and normal), iframes and more, that detects any visibility changes triggered through user interaction, CSS or JavaScript without configuration.
MIT License
17.56k stars 1.73k forks source link

Not working properly in Angular #261

Open peddinti opened 8 years ago

peddinti commented 8 years ago

We use images in our feed and since the main rendering is getting blocked until all the feed items are rendered, which in turn waits for the image, I am trying to use lazysizes with LQIP technique.

However, what i am seeing is that high-quality image is getting rendered instead of the low-quality image. Here is how i am using it.

<img ng-src="{{$ctrl.feedItem.large_image_url | lowQualityImageUrl}}" data-src="{{$ctrl.feedItem.large_image_url}}" class="lazyload blur-up"/>

The lowQualityImageUrl filter converts the high-quality image URL to low-quality image URL. I removed the data-src to make sure the src takes the low-quality image URL value <img ng-src="https://process.filepicker.io/Agxb1eRqwSB2mr4BhJwj2z/output=q:1/https://www.filepicker.io/api/file/3vCh0885S2anZMhP5Ahn" class="blur-up lazyloaded" src="https://process.filepicker.io/Agxb1eRqwSB2mr4BhJwj2z/output=q:1/https://www.filepicker.io/api/file/3vCh0885S2anZMhP5Ahn">

When I add the data-src, the img element looks like <img ng-src="https://process.filepicker.io/Agxb1eRqwSB2mr4BhJwj2z/output=q:1/https://www.filepicker.io/api/file/3vCh0885S2anZMhP5Ahn" data-src="https://www.filepicker.io/api/file/3vCh0885S2anZMhP5Ahn" class="blur-up lazyloaded" src="https://www.filepicker.io/api/file/3vCh0885S2anZMhP5Ahn">

I also checked my network calls in chrome inspect element and i don't see a call being made to the low-quality image URL. Am i missing something?

aFarkas commented 8 years ago

Is your problem fixed if add the data-sizes="auto" attribute?

peddinti commented 8 years ago

Hi no it doesn't, if I add data-src and ng-src, it is not even rendering the image. if i remove data-src, then the image is rendering. If i remove ng-src and use src and data-src, it is only rendering the low-quality image. not sure what is hapening.

aFarkas commented 8 years ago

Can you provide a simplified testcase?

tomholford commented 8 years ago

@peddinti Did you resolve this issue? If so, how? Experiencing the same thing you've described - no network calls to the LQIP image that's referenced in ng-src.

Have tried various things like setting lsConfig.init = false and then intializing after the ng-src={{}} is interpolated and including the attrchange plugin. Seems like the way Angular tries to update the src attr after interpolating ng-src conflicts with how LS tries to update it from data-src?

tomholford commented 8 years ago

@aFarkas here's a simple test case, note that the LQIP is not loading: https://jsbin.com/japipabipo/edit?html,js,output

edit: updated to use ng-class as suggested in #290, still no luck :( https://jsbin.com/duleseqisa/1/edit?html,js,output

aFarkas commented 8 years ago

Angular seems to have problems as soon as a data-src attribute is in place. Also note, that you should set lazyload class with ng-class:

You can change it like this:

    <script>
      window.lazySizesConfig = window.lazySizesConfig || {};
      lazySizesConfig.srcAttr = 'data-lazy';
    </script>
    <img ng-src="{{lqip}}" data-lazy="{{hq}}" ng-class="{'lazyload': true, 'blur-up': true}" />

Here is a fixed testcase: https://jsbin.com/xoyegipate/1/edit?html,js,output

tomholford commented 8 years ago

Thanks! This works swimmingly now :)

For anyone else who stumbles across this thread, here's how I implemented this in my Angular project:

(function () {
  'use strict';

  angular
    .module('myApp')
    .run(run);

  function run($window) {
    // to init lazysizes at app start
    $window.lazySizesConfig = $window.lazySizesConfig || {};
    $window.lazySizesConfig.srcAttr = 'data-lazy';
    $window.lazySizesConfig.srcsetAttr = 'data-lazyset';
  }
}());