Images lazy loading with Ionic and AngularJS

When dealing with remote images in a mobile application, lazy loading is always a good idea. I faced recently some performance problems and I wanted to share my solution.

The context:
I’m working on a Ionic mobile client for the Lychee photo management tool. Ionic is an open source front-end SDK for developing hybrid apps. Lychee is a self-hosted photo-management tool written in PHP.

The problem:
The app pulls from the Lychee API all the photos (of one album) without any pagination; so for several albums, which contain hundreds of photos, the time needed to load them is infinitely too long.

The solution:
In fact we have at least two solutions, to avoid loading all the photos at the same time:

  1. Don’t make the controller inject all the photos in the view at the same.
  2. Inject all the photos and make AngularJS and his magic two way binding show (and load) only the photos needed.

I chose the second one. Now let’s see what I did.
The controller:
www/js/album.js

// Controllers module
angular.module('lychee.controllers', ['lychee.services'])

// Album controller
.controller('AlbumCtrl', function($scope, $api) {
  $scope.album        = {};

  $scope.refresh = function() {
    $api.getAlbum(my_album_id, function(err, album) {
      if (!err)
        $scope.album = album;
    });
  };

  $scope.refresh();
});

This is a simple controller where I ask my $api service (no need to describe it here) to fetch a single album.

The albums fetched are like this:

{
  "photos": [
      {
          "title": "Photo title",
          "url": "https://..."
      }
  ]
}

The view:
www/templates/album.html

<ion-slide-box>
    <ion-slide ng-repeat="slide in album.photos track by $index">
        <ion-scroll direction="xy">



<div class="item item-image">



<div style="background-image: url({{slide.url}});"></div>



            </div>



        </ion-scroll>
    </ion-slide>
</ion-slide-box>

This is a simple view where I use a Ionic slide box to display the photos provided by the controller.
The problem with this solution is that all the photos are included in the page at the same time.

Now, let’s make some lazy loading…

For that, we’ll use the AngularJS ngIf directive.

Instead of laoding all of the ion-scroll elements at the same time, we’ll tell AngularJS to check a boolean function:

<ion-slide-box>
    <ion-slide ng-repeat="slide in album.photos track by $index">
        <ion-scroll direction="xy" ng-if="mustBeVisible($index)">



<div class="item item-image">



<div style="background-image: url({{slide.url}});"></div>



            </div>



        </ion-scroll>
    </ion-slide>
</ion-slide-box>

Pay attention to the ng-if=”mustBeVisible($index)” attribute of the ion-scroll tag. We tell AngularJS to check if this ion-scroll tag must be present in the DOM depending on the result of the mustBeVisible function. And of course, this method will be implemented in our controller:

// Controllers module
angular.module('lychee.controllers', ['lychee.services'])

// Album controller
.controller('AlbumCtrl', function($scope, $api, $ionicSlideBoxDelegate) {
  $scope.album        = {};

  $scope.refresh = function() {
    $api.getAlbum(my_album_id, function(err, album) {
      if (!err)
        $scope.album = album;

    });
  };

  $scope.mustBeVisible = function(index) {
    return Math.abs($ionicSlideBoxDelegate.currentIndex() - index) <= 5;
  }

  $scope.refresh();
});

This method checks if the distance between the current slide and the one being checked is less or equal to 5: in other words, when a slide is visible, the 5 previous and the 5 next photos are also loaded. And, even when we show the next or the previous slide, everything is updated 😉

This really improved my app performances and now I can easliy visualize an album containing several hundreds of photos.

The source code of the full app is available on Github.

Ionic mobile app for Lychee
https://github.com/b-alidra/ionic-lychee
0 forks.
2 stars.
1 open issues.
Recent commits:

Feel free to leave any comment or suggestion.

2 thoughts on “Images lazy loading with Ionic and AngularJS”

    1. Hi, I haven’t yet switched to Ionic 2, so I’m afraid I can not help you.
      I’ll share a new post as soon as I switch, but let me know if you find something interesting before.

Leave a Reply