Coder Social home page Coder Social logo

ng-defer-load's Introduction

ng-defer-load

ng-defer-load is an Angular directive to load elements lazily.

It uses Intersection Observer API to check if an element is in viewport and falls back to scroll detection mechanism for unsupported browsers.

Installation

Using npm:

$ npm i @trademe/ng-defer-load

Usage

  1. Import DeferLoadModule into the module corresponding to your component

  2. Use the directive with the element you wish to lazy load

  <div
    (deferLoad)="showMyElement=true">
    <my-element
       *ngIf=showMyElement>
      ...
    </my-element>
</div>

Note: You might want to have a loading state for your element with approximately same height as the element.

Server Side Rendering

ng-defer-load supports Server Side Rendering from version 1.1.0

It loads the element on the server by default supporting Search Engine Optimization. If you do not want to pre-render the element in server, you can set preRender to false on the element as below:

  <div
    [preRender]="false"
    (deferLoad)="showMyElement=true">
    <my-element
       *ngIf=showMyElement>
      ...
    </my-element>
</div>

Fall back support

ng-defer-load supports a fall back in browsers or devices (like older iPhones) that do not support the IntersectionObserver API. This uses the scroll position and the element's offset. This is enabled by default.

If you do not want to allow this fallback, and would prefer the browser to just render the element regardless, you can set fallbackEnabled to false on the element as below:

  <div
    [fallbackEnabled]="false"
    (deferLoad)="showMyElement=true">
    <my-element
       *ngIf=showMyElement>
      ...
    </my-element>
</div>

Demo

Demo of ng-defer-load in use is available here.

License

Released under the MIT license.

Release notes

v1.0.1 - Initial version

v1.1.0 - Supports Universal - Server Side Rendering

v2.0.0 - Supports Angular 6

v3.0.0 - Supports Angular 7

v3.1.0 - Made it possible to switch off scroll fallback

v8.0.0 - Supports Angular 8/9

v8.1.0 - Supports more package formats (using ng-packagr)

v8.2.0 - Added option to remove listeners after load

v8.2.1 - Fix for IE11 and older browsers

v8.2.2 - Updated dependencies due to security advisories

v14.0.0 - Supports Angular 12+ (targeting Angular 14) with partial Ivy builds. Additionally, drops support for IE11.

ng-defer-load's People

Contributors

dependabot[bot] avatar dhayhak avatar elwynelwyn avatar kenese avatar kiwiaddo avatar leonelngande avatar mvremmerden avatar mzoellner avatar nickgeek avatar vamsivempati avatar vinayakpatil avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ng-defer-load's Issues

isVisible() -> element.offsetTop -> proposal of replacement

Hi @VamsiVempati,

First of all, cool library, really cool library! I'm trying to lazy load my images in order to improve the accessibility of my website and I landed on your awesome work, thx a lot

I implemented your directive and it turned out that it was ignored by the lighthouse test. I digged a bit and it turned out that the images of my website (https://fluster.io) were loaded straight at the begin aka not lazy loaded because the images were recognized as being already displayed where actually the scroll was still at the top

In the directive https://github.com/TradeMe/ng-defer-load/blob/master/src/defer-load.directive.ts method isVisible (), the element y position is resolved doing

 let elementOffset = this._element.nativeElement.offsetTop;

which in my case always returned a small value, way smaller than the scrollPosition which seemed correct. After a couple of try I replaced the above code with the following one and it solved my problem

let elementOffset = this._element.nativeElement.getBoundingClientRect().top + window.scrollY;

doing so, my offset was correctly calculated.

Don't know if there is something really special in my website or if you think that it could be an improvement for the directive? If you think that isn't a bad idea, I could of course send a PR

Best regards
David

Angular 8 & IVY rendering support

Lately I've upgraded my project to latest angular 8.2.14. Despite of warning during npm install, defer-load is working well.
But, when I enable IVY engine it fails during loading application

Uncaught ReferenceError: Directive is not defined
    at vendor-es2015.js:117166
    at Object../node_modules/@trademe/ng-defer-load/__ivy_ngcc__/dist/defer-load.directive.js (vendor-es2015.js:117181)
    at __webpack_require__ (runtime-es2015.js:80)
    at Object../node_modules/@trademe/ng-defer-load/__ivy_ngcc__/dist/defer-load.module.js (vendor-es2015.js:117201)
    at __webpack_require__ (runtime-es2015.js:80)
    at Object../node_modules/@trademe/ng-defer-load/__ivy_ngcc__/dist/index.js (vendor-es2015.js:117238)
    at __webpack_require__ (runtime-es2015.js:80)
    at Module../src/app/app.module.ts (main-es2015.js:603)
    at __webpack_require__ (runtime-es2015.js:80)
    at Module../src/main.ts (main-es2015.js:2540)

It would be great to make it work with IVY

FF 52 loads all content

Firefox <= 52 loads all content on current tab and all other tabs in Angular 8 and ng-defer-load v8.2.1. What browsers are supported?

Seems not support Angular 8

Thanks for this nice module. I've tried with Angular 7 and it works perfectly fine. Yet, I've just upgraded my Angular app to v8, and found out that the defer load kind of stop working. I'm not sure if this is caused by the lazy loading modules introduced in Angular 8.

Angular: 8.1
ng-defer-load: "^3.0.1"

Extend peer dependencies to Angular 7

This is a...

  • feature request
  • bug report
  • usage question

What toolchain are you using for transpilation/bundling?

  • @angular/cli

Environment

NodeJS Version: 10.9.0
Typescript Version: 3.1.6
Angular Version: 7.0.3
@trademe/ng-defer-load: 2.0.0
@angular/cli version: 7.0.5
OS: Windows 10

Expected Behaviour:

No warnings should be shown

Actual Behaviour:

running npm install throws the following warning:

npm WARN @trademe/[email protected] requires a peer of @angular/common@^6.0.0 but none is installed. You must install peer dependencies yourself.
npm WARN @trademe/[email protected] requires a peer of @angular/core@^6.0.0 but none is installed. You must install peer dependencies yourself.
npm WARN @trademe/[email protected] requires a peer of @angular/platform-browser@^6.0.0 but none is installed. You must install peer dependencies yourself.

Additional Notes:

Need to add support for Angular7, there is no big difference between v6 and v7, and package already have support for v6.
We should make sure to update codelyzer package to 4.5.0 to work with Angular 7 too.

Performance Improvements - Reuse same IntersectionObserver as suggested in docs

Google Developer docs available at https://developers.google.com/web/updates/2016/04/intersectionobserver
suggests:

If you need to observe multiple elements, it is both possible and advised to observe multiple elements using the same IntersectionObserver instance by calling observe() multiple times

It seems that this directive creates new IntersectionObserver for each element, so if there are let;s say 20 images we will end up with 20 IntersectionObservers. What if we could re-use the same IntersectionObserver?

Angular 5 - Building issues

Hello,

We are facing some build issues, any help would be helpful.

Screenshot 2020-07-15 at 16 14 41

ionic info

`Ionic:

Ionic CLI : 6.10.1 (/Users/joaolourenco/.nvm/versions/node/v12.16.2/lib/node_modules/@ionic/cli)
Ionic Framework : ionic-angular 3.9.9
@ionic/app-scripts : 3.2.4

Cordova:

Cordova CLI : 9.0.0 ([email protected])
Cordova Platforms : android 8.1.0, ios 5.1.1
Cordova Plugins : cordova-plugin-ionic-keyboard 2.2.0, cordova-plugin-ionic-webview 5.0.0, (and 23 other plugins)

Utility:

cordova-res : not installed
native-run : 1.0.0

System:

ios-deploy : 1.10.0
ios-sim : 8.0.2
NodeJS : v12.16.2 (/Users/joaolourenco/.nvm/versions/node/v12.16.2/bin/node)
npm : 6.14.4
OS : macOS Catalina
Xcode : Xcode 11.5 Build version 11E608c
`

angular packages
with - "typescript": "2.6.2"

image

support angular 6

helps to avoid those warnings

$ npm i @trademe/ng-defer-load
npm WARN @trademe/[email protected] requires a peer of @angular/common@^5.2.5 but none is installed. You must install peer dependencies yourself.
npm WARN @trademe/[email protected] requires a peer of @angular/core@^5.2.5 but none is installed. You must install peer dependencies yourself.
npm WARN @trademe/[email protected] requires a peer of @angular/platform-browser@^5.2.5 but none is installed. You must install peer dependencies yourself.
npm WARN @trademe/[email protected] requires a peer of rxjs@^5.5.6 but none is installed. You must install peer dependencies yourself.

deferLoad not working in Child Components

I did not try with the app.module, but I followed the example link pretty closely and this is the only difference I could find.

When deferLoad is used in a child component, it will load all images that are presently in the initial viewport but fail to load any images on new images that come to the viewport thereafter.

Angular 8 production build error

Getting this error when I am building the app for production on angular 8. Seems to be working fine on ng serve
image
Any help on this. TIA

Feature Request - Release this plugin as ES2015 module

When compiling Angular project with latest version of Angular CLI it throws below warning:

mytest.module.ts depends on @trademe/ng-defer-load. CommonJS or AMD dependencies can cause optimization bailouts.

Google advises against using CommonJS modules because it can impact the tree-shaking of application as explained here https://web.dev/commonjs-larger-bundles/

I would therefore request you to please release this plugin as es2015 module.

Thank you

Doesn't load until scroll stops iPhone

On iPhone the images don't load until the scroll stops, is there a way to set it up so that the images load as they come into view even while stills scrolling ?

Expression change after it was checked error in Safari and IE

I am using version 2 for an angular 6 project, as the latest version show dependency error when installing. The directive works when following the instruction in read me.

However, expression change after it was checked error occurs in Safari 11 and IE 11 but not in Chrome or Firefox. I noticed a similar ticket was posted here and closed without any comments.

Being a new developer, I wonder why the expression change after it was checked error only happens in Safari and IE. It would appreciated if someone could advice on this issue.

Does not work on mobile

Hi there,

I tested your package and it worked well untill I opened the web application on a mobile phone. Then it did no longer load the images...

I checked your demo on my phone and there it works. Any ideas how come? :)

I didn't set any options, just used it as described:

(deferLoad)="showMyElement=true">
    <my-element
       *ngIf=showMyElement>
      ...
    </my-element>

In the meantime I wrote my own Intersection Observer, I was just curious how come it does not work out of the box :)

Error in Angular 7 production build

Angular version: 7.2.15

Working well in the local. but getting this error, while generating production build. please check and let me know.
image

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.