h5 モバイル ページで作業しているとき、ページは開いているが、内部の画像が読み込まれていないという状況に遭遇したことがあると思います。この問題はページの機能には影響しませんが、ページの動作には影響しません。ユーザー体験。ネットワーク速度に関係なく、この問題を解決するには多くの方法があります。最も基本的な方法は、http リクエストのマージ、キャッシュ管理、画像圧縮などの側面からパフォーマンスを最適化することです。もう 1 つは、使用されるすべての画像を前処理することです。ページの読み込みプロセスでは、ユーザーがページを開いたときに最初の画面が表示されず、最初にリソース読み込みエフェクトが表示され、読み込みが完了した後にページのメイン コンテンツが表示されます。これで問題は解決できます。この読み込み効果はユーザーの閲覧時間を消費しますが、それをより美しく興味深いものにすることができるため、ユーザー エクスペリエンスには影響しません。この記事では、このアイデアを実装し、実装が簡単で機能も貧弱ではない非常にシンプルな画像プリロード コンポーネントを提供します。モバイル ページを作成する際には参考になるはずです。
効果:
1. 実装アイデア
HTMLのimgタグとCSSのbackground-imagは、ブラウザに関連画像をロードさせますが、この画像が画像がロードされると、ブラウザはロードされた画像を直接使用して、ページ上に即座にレンダリングできるようになります。 JavaScript を使用して Image オブジェクトを作成し、これらのオブジェクトの src 属性をロードする画像のアドレスに設定します。これにより、ブラウザが画像をロードするようにトリガーすることもできます。これを使用して、画像のプリロード機能を実現します。最初に使用します。ページ上の関連情報を非表示にし、js を使用して画像をロードし、すべての画像がロードされるまで待ってから、非表示の要素を表示します。ただし、これは単なる基本的な実装アイデアであり、より堅牢な機能を備えたプリロード コンポーネントを完成させるには、まだ次の 3 つの問題があります:
1) 進捗の問題
プリロードするため、プリロード効果も同時に実行する必要があります。読み込みの進行状況を外部コンテキストにリアルタイムで通知します。進捗には 2 つの実装方法があり、1 つはロードされたデータ サイズ / 総データ サイズ、もう 1 つはロードされたファイル数 / 総ファイル数です。最初の方法を使用するのは現実的ではありません。はネイティブな方法ではないため、2 番目の方法のみを使用できます。
2) 画像読み込み失敗問題
例えば、画像が4枚あり、そのうちの50%が読み込まれ、3枚目の画像を読み込むときにエラーが発生する場合、進捗を75%にフィードバックする必要があるでしょうか。答えは「はい」です。これを行わないと、進行状況が 100% に達することはなく、ページのメイン コンテンツが表示されなくなります。画像の読み込みが失敗する可能性がありますが、画像自体は失敗する可能性があります。存在しない?これは、イメージの読み込みの失敗がローダーの機能に影響を与えないことを意味します。
3) 画像読み込みタイムアウトの問題
画像を長時間読み込むことができません。そうしないと、ユーザーは読み込み中のままになり、メインコンテンツが表示されなくなり、ユーザーの待ち時間が制御不能に延長され、結果として、画像の読み込み速度が低下します。ユーザー エクスペリエンスが低下し、ローダーの本来の意図に反します。したがって、すべての画像のタイムアウト後に読み込みが完了していない場合は、読み込みタイムアウトを画像ごとに設定する必要があり、読み込みを積極的に中止し、読み込みが完了したことを外部コンテキストに通知し、メイン コンテンツに通知する必要があります。表示される。
上記の要件に基づいて、この記事で提供される実装は次のとおりです:
JavaScript コード内容をクリップボードにコピー
(function () { function isArray(obj) { return Object.prototype.toString.call(obj) === '[object Array]'; } /** * @param imgList 要加载的图片地址列表,['aa/asd.png','aa/xxx.png'] * @param callback 每成功加载一个图片之后的回调,并传入“已加载的图片总数/要加载的图片总数”表示进度 * @param timeout 每个图片加载的超时时间,默认为5s */ var loader = function (imgList, callback, timeout) { timeout = timeout || 5000; imgList = isArray(imgList) && imgList || []; callback = typeof(callback) === 'function' && callback; var total = imgList.length, loaded = 0, imgages = [], _on = function () { loaded < total && (++loaded, callback && callback(loaded / total)); }; if (!total) { return callback && callback(1); } for (var i = 0; i < total; i++) { imgages[i] = new Image(); imgages[i].onload = imgages[i].onerror = _on; imgages[i].src = imgList[i]; } /** * 如果timeout * total时间范围内,仍有图片未加载出来(判断条件是loaded < total),通知外部环境所有图片均已加载 * 目的是避免用户等待时间过长 */ setTimeout(function () { loaded < total && (loaded = total, callback && callback(loaded / total)); }, timeout * total); }; "function" === typeof define && define.cmd ? define(function () { return loader }) : window.imgLoader = loader; })();
使用方法 (コード内の test.html に対応):
XML/HTML コードコンテンツをクリップボードにコピー
<script src="../js/imgLoader.js"></script> <script> imgLoader(['../img/page1.jpg', '../img/page2.jpg', '../img/page3.jpg'], function(percentage){ console.log(percentage) }); </script>
実行結果:
2. demo说明
本文开篇给出的效果,对应的页面是index.html,关于这个效果还有两个问题需要说明:
1)它用了之前这篇博客Hammer.js+轮播原理实现简洁的滑屏功能介绍的滑屏思路,并把它的一些逻辑包装在了swipe.js,对外提供了一个全局变量Swipe,这个模块有一个init的方法,以便外部通过调用Swipe.init()就能初始化滑屏相关的功能,原来没有提供这个init方法,在js加载完毕就会初始化滑屏功能,有了这个init方法就可以把滑屏的逻辑延迟到加载完毕的时候去初始化。index.html一共引用了5个js:
XML/HTML Code复制内容到剪贴板
<script src="js/zepto.js"></script> <script src="js/transition.js"></script> <script src="js/hammer.js"></script> <script src="js/imgLoader.js"></script> <script src="js/swipe.js"></script>
其中imgLoader.js就是前面介绍图片加载器的实现,前三个js都是为最后一个swipe.js服务的,感兴趣的可以继续我的博客利用轮播原理结合hammer.js实现简洁的滑屏功能了解相关内容。不过滑屏不是本文的重点,不了解swipe.js不会影响理解本文的内容~
2)虽然我在demo中用到了3张比较大的图片,但是由于在本地环境,加载速度还是非常快,所以一开始的时候,很难看到预加载的效果,最后只能想办法在每个进度回调之前做一下延迟,这才可以看到前面gif图片一开始的那个loading效果,实现方式是:
XML/HTML Code复制内容到剪贴板
//模拟加载慢的效果 var callbacks = []; imgLoader(['img/page1.jpg', 'img/page2.jpg', 'img/page3.jpg'], function (percentage) { var i = callbacks.length; callbacks.push(function(){ setTimeout(function(){ var percentT = percentage * 100; $('#loader__info').html('Loading ' + (parseInt(percentT)) + '%'); $('#loader__progress')[0].style.width = percentT + '%'; if (percentage == 1) { setTimeout(function(){ $('#loader').remove(); Swipe.init(); }, 600); } callbacks[i + 1] && callbacks[i + 1](); },600); }); if(percentage == 1) { callbacks[0](); } });
在真实环境,最好还是不要刻意去加这种延迟,没必要为了让用户看到一个好看有趣的加载效果,就浪费它不必要的等待时间,所以真实环境还是应该用下面的代码:
XML/HTML Code复制内容到剪贴板
imgLoader(['img/page1.jpg', 'img/page2.jpg', 'img/page3.jpg'], function (percentage) { var percentT = percentage * 100; $('#loader__info').html('Loading ' + (parseInt(percentT)) + '%'); $('#loader__progress')[0].style.width = percentT + '%'; if (percentage == 1) { $('#loader').remove(); Swipe.init(); } });
3. 注意事项
预加载是一种比较常见的实现效果,但是在使用的时候,有些问题需要注意:
1)什么时候用
页面大的时候用,一般页面大小超过3M就该考虑使用;页面内包含数据量比较大的图片,在手机端测试能够明显看到加载缓慢的时候,可以考虑使用。
2)尽量使用sprite图片
3)加载效果实现的时候,尽量不用图片,即使要用也应该用很小的图片,否则加载效果卡在那就没有意义了。
4. 总结
本文主要介绍了一个简单的图片预加载器,可应用于h5移动页面的开发当中,在它的思路之下,如果有必要的话,还可以对它进行一些改造,用它来加载其它类型的资源,比如音频或者视频文件,毕竟这些类型的DOM对象也都有提供类似Image对象的属性和回调。与预加载的方式相反的,还有一种图片懒加载的技术,现在网上已经有比较好用的jquery插件了,不过还是很值的去深入了解下它的思路跟实现要点,等我有时间去研究研究。同时感谢大家一直以来对PHP中文网的支持!
更多利用简洁的图片预加载组件提升html5移动页面的用户体验 相关文章请关注PHP中文网!