Home  >  Article  >  Web Front-end  >  Use simple image preloading components to improve the user experience of html5 mobile pages _html5 tutorial skills

Use simple image preloading components to improve the user experience of html5 mobile pages _html5 tutorial skills

WBOY
WBOYOriginal
2016-05-16 15:51:471247browse

When working on h5 mobile pages, I believe you must have encountered a situation where the page has been opened, but the images inside have not been loaded. Although this problem does not affect the function of the page, it is not conducive to the user experience. Regardless of the network speed, there are many ways to solve this problem: the most basic is to optimize performance from aspects such as http request merging, cache management, image compression, etc.; the other is to pre-process all images used in the page. In the loading process, when the user opens the page, the first screen is not displayed immediately. Instead, the resource loading effect is displayed first, and then the main content of the page is displayed after the loading is completed. This can solve the problem. Although this loading effect takes up the user's browsing time, we can make it more beautiful and interesting, so it will not affect the user experience. This article implements this idea and provides a very simple image preloading component. It is simple to implement and not weak in function. It should be of reference value to you when making mobile pages.
Effect:

1. Implementation ideas

The img tag in HTML and background-imag in CSS will trigger the browser to load the related image. However, if the image has already been loaded, the browser will directly use the loaded image, thus It can be rendered on the page instantly. Through javascript, create Image objects, and then set the src attribute of these objects to the address of the image to be loaded, which can also trigger the browser to load the image. You can use this to realize the image preloading function: first use those related to the page. Hide the elements of the image, then use js to load the image, wait until all images are loaded, and then display the hidden elements. However, this is just a basic implementation idea. To complete a preloading component with a more robust function, there are still three problems:
1) Progress problem
Since preloading is done at the same time, a preloading component must also be done. The effect is that the loading progress needs to be notified to the external context in real time. There are two ways to implement progress. The first is the loaded data size/total data size, and the second is the number of loaded files/total number of files. In the browser, it is unrealistic to use the first method. , there is no native way to do it, so we can only use the second method.
2) The problem of image loading failure
For example, if there are 4 images, 50% of them have been loaded, and an error occurs when loading the third image. Should the progress be fed back to 75%? The answer is: yes. If this is not done, the progress will never reach 100%, and the main content of the page will have no chance to be displayed. Although the image loading may fail, it has nothing to do with the loader. Maybe the image itself does not exist? This means that image loading failure should not affect the functionality of the loader.
3) The problem of image loading timeout
The image cannot be loaded for too long, otherwise the user will stay in the loading effect and cannot see the main content, and the user's waiting time will be extended uncontrollably, resulting in a decline in user experience. This will It goes against the original intention of the loader. Therefore, a loading timeout should be set for each image. If the loading is not completed after the timeout of all images, the loading should be actively abandoned, the external context should be notified that the loading is complete, and the main content should be displayed.
Based on the above requirements, the implementation provided in this article is:

JavaScript CodeCopy content to clipboard
  1. (function () {    
  2. function isArray(obj) {    
  3. return Object.prototype.toString.call(obj) === '[object Array]';    
  4. }    
  5. /**
  6. * @param imgList List of image addresses to load, ['aa/asd.png','aa/xxx.png']
  7. * @param callback The callback after each image is successfully loaded, and the "total number of images loaded/total number of images to be loaded" is passed in to indicate the progress
  8. * @param timeout The timeout for loading each image, the default is 5s
  9. */    
  10. var loader = function (imgList, callback, timeout) {    
  11. timeout = timeout || 5000;    
  12. imgList = isArray(imgList) && imgList || [];    
  13. callback = typeof(callback) === 'function' && callback;    
  14. var total = imgList.length,    
  15. loaded = 0,    
  16. imgages = [],    
  17. _on = function () {    
  18. loaded < total && ( loaded, callback && callback(loaded / total));    
  19. };    
  20. if (!total) {    
  21. return callback && callback(1);    
  22. }    
  23. for (var i = 0; i < total; i ) {    
  24. imgages[i] = new Image();    
  25. imgages[i].onload = imgages[i].onerror = _on;    
  26. imgages[i].src = imgList[i];    
  27. }    
  28. /**
  29. * If there are still pictures that have not been loaded within the timeout * total time range (the judgment condition is loaded < total), notify the external environment that all pictures have been loaded
  30. * The purpose is to avoid users waiting too long
  31. */    
  32. setTimeout(function () {    
  33. loaded < total && (loaded = total, callback && callback(loaded / total));    
  34. }, timeout * total);    
  35. };
  36. "function" === typeof define && define.cmd ? define(function () {
  37. return loader
  38. }) : window.imgLoader = loader;
  39. })();

Usage (corresponding to test.html in the code):

XML/HTML CodeCopy content to clipboard
  1. <script src="../js/ imgLoader.js">script> 
  2. <script> 
  3. imgLoader(['../img/page1.jpg', '../img/page2.jpg', '../img/page3.jpg'], function(percentage){
  4. console.log(percentage)
  5. });
  6. script> 

Run result:


2. Demo description
The effect given at the beginning of this article, the corresponding page is index.html, there are two issues that need to be explained about this effect :
1) It uses the sliding screen idea introduced in the previous blog Hammer.js carousel principle to implement a simple sliding screen function, and wraps some of its logic in swipe.js, A global variable Swipe is provided to the outside world. This module has an init method so that the sliding screen related functions can be initialized externally by calling Swipe.init(). Originally, this init method was not provided. The sliding screen will be initialized after the js is loaded. Function, with this init method, the sliding screen logic can be delayed until the loading is completed to initialize. index.html references a total of 5 js:

XML/HTML CodeCopy content to clipboard
  1. <script src="js/zepto.js">script>    
  2. <script src="js/transition.js">script>    
  3. <script src="js/hammer.js">script>    
  4. <script src="js/imgLoader.js">script>    
  5. <script src="js/swipe.js">script>   

其中imgLoader.js就是前面介绍图片加载器的实现,前三个js都是为最后一个swipe.js服务的,感兴趣的可以继续我的博客利用轮播原理结合hammer.js实现简洁的滑屏功能了解相关内容。不过滑屏不是本文的重点,不了解swipe.js不会影响理解本文的内容~
2)虽然我在demo中用到了3张比较大的图片,但是由于在本地环境,加载速度还是非常快,所以一开始的时候,很难看到预加载的效果,最后只能想办法在每个进度回调之前做一下延迟,这才可以看到前面gif图片一开始的那个loading效果,实现方式是:

XML/HTML Code复制内容到剪贴板
  1. //模拟加载慢的效果    
  2. var callbacks = [];    
  3. imgLoader(['img/page1.jpg', 'img/page2.jpg', 'img/page3.jpg'], function (percentage) {    
  4. var i = callbacks.length;    
  5. callbacks.push(function(){    
  6. setTimeout(function(){    
  7. var percentT = percentage * 100;    
  8. $('#loader__info').html('Loading '   (parseInt(percentT))   '%');    
  9. $('#loader__progress')[0].style.width = percentT   '%';    
  10. if (percentage == 1) {    
  11. setTimeout(function(){    
  12. $('#loader').remove();    
  13. Swipe.init();    
  14. }, 600);    
  15. }    
  16. callbacks[i   1] && callbacks[i   1]();    
  17. },600);    
  18. });    
  19. if(percentage == 1) {    
  20. callbacks[0]();    
  21. }    
  22. });   

在真实环境,最好还是不要刻意去加这种延迟,没必要为了让用户看到一个好看有趣的加载效果,就浪费它不必要的等待时间,所以真实环境还是应该用下面的代码:

XML/HTML Code复制内容到剪贴板
  1. imgLoader(['img/page1.jpg', 'img/page2.jpg', 'img/page3.jpg'], function (percentage) {    
  2. var percentT = percentage * 100;    
  3. $('#loader__info').html('Loading '   (parseInt(percentT))   '%');    
  4. $('#loader__progress')[0].style.width = percentT   '%';    
  5. if (percentage == 1) {    
  6. $('#loader').remove();    
  7. Swipe.init();    
  8. }    
  9. });   

3. Notes
Preloading is a relatively common implementation effect, but when using it, there are some issues that need to be paid attention to:
1) What Use
when the page is large. Generally, you should consider using it if the page size exceeds 3M. ​​The page contains pictures with a relatively large amount of data. You can consider using it when the mobile phone test can clearly show that the loading is slow.
2) Try to use sprite images
3) When implementing the loading effect, try not to use images. Even if you want to use them, you should use very small images, otherwise the loading effect will be stuck there and it will be meaningless.
4. Summary
This article mainly introduces a simple image preloader, which can be applied to the development of h5 mobile pages. Under its ideas, If necessary, you can also modify it and use it to load other types of resources, such as audio or video files. After all, these types of DOM objects also provide properties and callbacks similar to Image objects. Contrary to the preloading method, there is also a technology of lazy loading of images. There are already relatively easy-to-use jquery plug-ins on the Internet, but it is still worth learning more about its ideas and implementation points. I will do it when I have time. Research research. At the same time, thank you all for your continued support of the Script House website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn