以前、画像の「遅延読み込み」に関する記事を書きましたが、週末にファイルを整理していたときに、おそらく以前に書いたコードを見直して、最適化できる箇所がたくさんあることに気づきました。
この記事は主に、以前の記事 「JavaScript ウォーターフォール フロー画像の遅延読み込みの例」を組み合わせて、画像の「遅延読み込み」に関する知識を見ていきます。
画像の「遅延読み込み」の目的:
必要に応じて画像を読み込みます。つまり、表示する必要があるときに画像を読み込んで、1 回限りの読み込みによるネットワーク帯域幅のオーバーヘッドを削減します。
まずコードの一部を見てみましょう:
var conf = { 'loadfirst': true, 'loadimg': true }; for (var item in conf) { if (item in co) { conf.item = co.item; } }
ここでは主にユーザー設定とデフォルト設定の結合を実現したいと考えています。このようなコードを書くのはあまり洗練されていません。コードは次のとおりです。
_this.setting = { "mobileHeight": 0, //扩展屏幕的高度,使第一屏加载个数可配置 "loadNum": 1 //滚动时,当前节点之后加载个数 }; $.extend(_this.setting, _this.getSetting());
mobileHeight はデフォルトのクライアントの高さです。値が大きいほど、最初の画面に読み込まれる画像が増えます。
loadNum 現在のノードが画面に表示される場合、現在のノード以降の複数のノードを一度にロードできるため、画像のロード速度が向上します。
私のコードは以前は次のように書かれていました:
_this.loadFirstScreen = function() { if (conf.loadfirst) { lazyNode.each(function(i) { currentNodeTop = $(this).offset().top; //这里的800就是上面提到的mobileHeight if (currentNodeTop < mobileHeight + 800) { _this.replaceImgSrc($(this)); } }); } }; _this.loadImg = function() { if (conf.loadimg) { $(window).on('scroll', function() { var imgLazyList = $('[node-type=imglazy]', node); //这里的5就是上面提到的loadNum for (var i = 0; i < 5; i++) { _this.replaceImgSrc(imgLazyList.eq(i)); } }); } };
loadFirstSrceen: function() { // 加载首屏 var _this = this; var currentNodeTop; var imgNodeList = _this.imgNode; $(imgNodeList).each(function() { currentNodeTop = $(this).offset().top; if (currentNodeTop < _this.mobileHeight() + _this.setting.mobileHeight) { _this.replaceImgSrc($(this)); } }); }, scrollLoadImg: function() { //滚动的时候加载图片 var _this = this; var currentNodeTop; var scrollTop = $('body').scrollTop(); var imgLazyList = $('[node-type=imglazy]'); $(imgLazyList).each(function() { currentNodeTop = $(this).offset().top; if (currentNodeTop - scrollTop < _this.mobileHeight()) { //加载当前节点后的规定个数节点 for (var i = 0, len = _this.setting.loadNum; i < len; i++) { _this.replaceImgSrc($(imgLazyList).eq(i)); } return false; } }); }
;(function($) { var LoadImgLazy = function(imgNode) { var _this = this; _this.imgNode = imgNode; _this.setting = { "mobileHeight": 0, //扩展屏幕的高度,使第一屏加载个数可配置 "loadNum": 1 //滚动时,当前节点之后加载个数 }; $.extend(_this.setting, _this.getSetting()); _this.loadFirstSrceen(); $(window).on('scroll', function() { _this.scrollLoadImg(); }); }; LoadImgLazy.prototype = { mobileHeight: function() { return $(window).height(); }, loadFirstSrceen: function() { // 加载首屏 var _this = this; var currentNodeTop; var imgNodeList = _this.imgNode; $(imgNodeList).each(function() { currentNodeTop = $(this).offset().top; if (currentNodeTop < _this.mobileHeight() + _this.setting.mobileHeight) { _this.replaceImgSrc($(this)); } }); }, scrollLoadImg: function() { //滚动的时候加载图片 var _this = this; var currentNodeTop; var scrollTop = $('body').scrollTop(); var imgLazyList = $('[node-type=imglazy]'); $(imgLazyList).each(function() { currentNodeTop = $(this).offset().top; if (currentNodeTop - scrollTop < _this.mobileHeight()) { //加载当前节点后的规定个数节点 for (var i = 0, len = _this.setting.loadNum; i < len; i++) { _this.replaceImgSrc($(imgLazyList).eq(i)); } return false; } }); }, replaceImgSrc: function(loadImgNode) { //动态替换图片 var srcValue; var imgDataSrc; var _this = this; var imgUrlList = $(loadImgNode).find('img[data-lazysrc]'); if (imgUrlList.length > 0) { imgUrlList.each(function(i) { imgDataSrc = $(this).attr('data-lazysrc'); srcValue = $(this).attr('src'); if (srcValue === '#') { if (imgDataSrc) { $(this).attr('src', imgDataSrc); $(this).removeAttr('data-lazysrc'); } } }); //移除已经运行过懒加载节点的node-type 对性能提升 $(loadImgNode).removeAttr('node-type'); } }, getSetting: function() { var userSetting = $('[lazy-setting]').attr('lazy-setting'); if (userSetting && userSetting !== '') { return $.parseJSON(userSetting); } else { return {}; } }, destory: function() { //销毁方法区 $(window).off('scroll'); } }; LoadImgLazy.init = function(imgNode) { new this(imgNode); }; window.LoadImgLazy = LoadImgLazy; })(Zepto);