ionic入门教程第十五课-ionic性能优化之图片延时加载

25 篇文章 0 订阅

ionic入门教程第十五课-ionic性能优化之图片延时加载

周五的时候有个朋友让我写一个关于图片延时加载的教程,

直到今天才有空编辑,这阶段真的是很忙,公众号都变成僵尸号了。

实在是对不起大家。

有人喜欢我的教程,可能我总习惯了用比较简单容易理解的方式去描述这些东西。

别的就不多说了,大家遇到什么问题。

可以直接联系我,不是一句话两句话能讲清楚的问题,我都会抽空写一个教程的。

现在还欠着一个问题没回复:按需加载所有的文件。之前教程里面只写了按需加载controller文件。

这个现在有一个方案,我们公司自己的产品正在使用,正在开发中。效果和性能要等个一两周的测试之后才能知道。

要是方案测试通过了,我就把方案分享给大家。

接着进入今天的主题。

图片延时加载,为什么要延时加载图片呢?

大家都都知道在较长的列表页绘制时会使得应用程序变得卡顿。不仅在界面之内的图片需要绘制,在页面之外的图片也要绘制,如果一次请求的图片数量较少,看不出有什么性能问题,但是当图片较多且较大时,达到一定的量级,那么就会影响程序的性能了。使用延时加载图片,当你滚动到相应的子项时,该子项的图片才开始加载。这样子实现,当前可视区域的图片显示正常,而可视区域之外的图片却不加载,在一定程度上能够加快页面的绘制,对于ionic的应用长列表页应该算是一个比较常见的部件了。所以在ionic项目中使用图片延时加载技术是一个不错的选择。

根据需求分析,我们能够理解,首先延时加载图片就是一开始不加载,而在滚动容器之后,按条件开始加载图片,条件就是该图片在可视区域内。

所以首先我们要给图片所在容器绑定一个滚动事件,当视图滚动时抛出加载图片的事件。



这个demo是我上次不知道写那个教程之后的Demo,懒得新建一个项目,大家关注我截图的这些地方就好了。

这里就是把这个外层承载的容器定义为lazy-scroll,用于在指令里面绑上事件。

事件也很好理解,就是绑定滚动事件,然后抛出一个lazyScrollEvent事件。



接着我们实现按条件加载图片,当图片在现实区域之内。

给对象绑上监听事件


这里有几个地方可以关注的。一个是isInView()条件用来判断对象是否在屏幕可视区域内。一个就是这个监听事件的返回对象被存储为deregistration,然后在处理加载图片之后被重新执行了绑定。其实做过web端通信的应该了解,web是需要保活机制确定事件的活性。然而这里并没有什么作用,当图片加载完成之后,并不需要再次执行加载。但是会有一个问题,可能加载是失败的时候,再次进入视图可以再次加载。


判断是否在屏幕的可视区域之内的方法,有点类似编写游戏时常使用到的碰撞检测。

------------------------------------------略------------------------

额。有工作了。没时间写了,将就看吧。

---------------------------------------略--------------------------------

然后用法很简单,把ng-src替换成image-lazy-src就可以了,记得给他们的承载容器加上lazy-scroll

我这里是直接把文件放在app.js里面了。大家可以根据自己的文件加载规范把文件分离出来。

[javascript]  view plain  copy
  1. app.directive('lazyScroll', ['$rootScope''$timeout',  
  2.      function($rootScope, $timeout) {  
  3.        return {  
  4.          restrict: 'A',  
  5.          link: function ($scope, $element) {  
  6.            var scrollTimeoutId = 0;  
  7.            $scope.invoke = function () {  
  8.              $rootScope.$broadcast('lazyScrollEvent');  
  9.            };  
  10.            $element.bind('scroll'function () {  
  11.              $timeout.cancel(scrollTimeoutId);  
  12.              scrollTimeoutId = $timeout($scope.invoke, 0);  
  13.            });  
  14.          }  
  15.        };  
  16.      }])  
然后是

[javascript]  view plain  copy
  1. app.directive('imageLazySrc', ['$document''$timeout''$ionicScrollDelegate''$compile',  
  2.       function ($document, $timeout, $ionicScrollDelegate, $compile) {  
  3.         return {  
  4.           restrict: 'A',  
  5.           scope: {  
  6.             lazyScrollResize: "@lazyScrollResize",  
  7.             imageLazyBackgroundImage: "@imageLazyBackgroundImage"  
  8.           },  
  9.           link: function ($scope, $element, $attributes) {  
  10.             if (!$attributes.imageLazyDistanceFromBottomToLoad) {  
  11.               $attributes.imageLazyDistanceFromBottomToLoad = 0;  
  12.             }  
  13.             if (!$attributes.imageLazyDistanceFromRightToLoad) {  
  14.               $attributes.imageLazyDistanceFromRightToLoad = 0;  
  15.             }  
  16.             if ($attributes.imageLazyLoader) {  
  17.               var loader = $compile('<div class="image-loader-container"><ion-spinner class="image-loader" icon="' + $attributes.imageLazyLoader + '"></ion-spinner></div>')($scope);  
  18.               $element.after(loader);  
  19.             }  
  20.             var deregistration = $scope.$on('lazyScrollEvent'function () {  
  21.                 //console.log('scroll');  
  22.                 if (isInView()) {  
  23.                   loadImage();  
  24.                   deregistration();  
  25.                 }  
  26.               }  
  27.             );  
  28.             function loadImage() {  
  29.               $element.bind("load"function (e) {  
  30.                 if ($attributes.imageLazyLoader) {  
  31.                   loader.remove();  
  32.                 }  
  33.                 if ($scope.lazyScrollResize == "true") {  
  34.                   //Call the resize to recalculate the size of the screen  
  35.                   $ionicScrollDelegate.resize();  
  36.                 }  
  37.               });  
  38.               if ($scope.imageLazyBackgroundImage == "true") {  
  39.                 var bgImg = new Image();  
  40.                 bgImg.onload = function () {  
  41.                   if ($attributes.imageLazyLoader) {  
  42.                     loader.remove();  
  43.                   }  
  44.                   $element[0].style.backgroundImage = 'url(' + $attributes.imageLazySrc + ')'// set style attribute on element (it will load image)  
  45.                   if ($scope.lazyScrollResize == "true") {  
  46.                     //Call the resize to recalculate the size of the screen  
  47.                     $ionicScrollDelegate.resize();  
  48.                   }  
  49.                 };  
  50.                 bgImg.src = $attributes.imageLazySrc;  
  51.               } else {  
  52.                 $element[0].src = $attributes.imageLazySrc; // set src attribute on element (it will load image)  
  53.               }  
  54.             }  
  55.             function isInView() {  
  56.               var clientHeight = $document[0].documentElement.clientHeight;  
  57.               var clientWidth = $document[0].documentElement.clientWidth;  
  58.               var imageRect = $element[0].getBoundingClientRect();  
  59.               return (imageRect.top >= 0 && imageRect.top <= clientHeight + parseInt($attributes.imageLazyDistanceFromBottomToLoad))  
  60.                 && (imageRect.left >= 0 && imageRect.left <= clientWidth + parseInt($attributes.imageLazyDistanceFromRightToLoad));  
  61.             }  
  62.             $element.on('$destroy'function () {  
  63.               deregistration();  
  64.             });  
  65.             $timeout(function () {  
  66.               if (isInView()) {  
  67.                 loadImage();  
  68.                 deregistration();  
  69.               }  
  70.             }, 500);  
  71.           }  
  72.         };  
  73.       }]);  

还有其他问题的直接小窗问我吧!本来想说的明白点的,这边工作催的紧。。。

项目Demo地址:http://pan.baidu.com/s/1eSM4te6
 
 
--- 转自:http://blog.csdn.net/onil_chen/article/category/6113346 ---
 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值