VUE

vue实现图片预加载

业务场景是这样的:在页面里有一个提醒文案,提醒文案里有个按钮,点击按钮会弹出示例弹窗,弹窗里上面有标题,中间一个比较大的图片,27kb;下面有个按钮。在苹果手机使用微信打开时,上面的标题和下面的按钮都先于图片加载出来。中间的按钮过了一会才渲染出来。

为此,我也懒得去找ui沟通能不能把图片弄小一点,正好试试图片预加载这个功能。

首先先说明下vue-cli的assetsstatic的两个文件的区别,因为这对你理解后面的解决办法会有所帮助

于是,在网上搜索到

  • assets:在项目编译的过程中会被webpack处理解析为模块依赖,只支持相对路径的形式,如< img src=”./logo.png”>和background:url(./logo.png),”./logo.png”是相对资源路径,将有webpack解析为模块依赖
  • static:在这个目录下文件不会被webpack处理,简单就是说存放第三方文件的地方,不会被webpack解析。他会直接被复制到最终的打包目录(默认是dist/static)下。必须使用绝对路径引用这些文件,这是通过config.js文件中的build.assetsPublic和build.assertsSubDirectory链接来确定的。任何放在static/中文件需要以绝对路径的形式引用:/static[filename]

1、实例化Image对象,添加src为需要预加载的图片路径

function preloadImg(url) {
    var img = new Image();
    img.src = url;
    if(img.complete) {
        //接下来可以使用图片了
        //do something here
    }
    else {
        img.onload = function() {
            //接下来可以使用图片了
            //do something here
        };
    }
}

起初试用了这种方法,但是发现vue里并不能跑进img.complete这个分支里,这是因为用webpack打包之后,在文件名后面会多一串hash值,导致找不到这个图片。需要将 img.src = url改成
img.src= require(’…/assets/img/pic@2x.png’)这样。

2、多图片预加载

    preload(){
          let count = 0;
          let imgs;
      	   imgs = [
              //用require的方式添加图片地址,直接添加图片地址的话,在build打包之后会查找不到图片,因为打包之后的图片名称会有一个加密的字符串
              require('../assets/img/pic@2x.png'),
              require('../assets/img/pic1@2x.png'),
            ]
          for (let img of imgs) {
            let image = new Image();
            image.src = img;
            let that = this;
            image.onload = () => {
              count++;
            };
          }
        },


使用这种方法把 preload这个函数在mounted时调用,第一次点击“示例”按钮时,图片确实没有出现比较慢出现的现象。但,再点击一次或者点击多几次,就又会出现慢出现的想象。我想这应该是图片在浏览器的缓存过期了。
于是,我又改变了一种方式,前面的方式是在弹窗mounted的时候进行预加载图片,这次,我在点击“示例”按钮的时候就进行预加载图片,并且每次点击都进行这个动作。经过这次调整,图片再也没有慢出现了。完美优化用户体验~~