用vue-cli搭建项目图片预加载的问题

用vue-cli搭建项目图片预加载的问题

十一月 10, 2017

因为现在项目做的东西都是小游戏,游戏和普通web应用有一个很重要的环节就是预加载,在游戏开始之前必须把所有图片等静态资源都加载到本地,等到游戏中真正要用到资源的时候可以直接从缓存中拿,而不是用到的时候再去后端拿,达到优化游戏体验的目的。

但是最近用vue开发小游戏的时候遇到了一个很坑爹的问题,就是原来的那一套预加载方式不生效,loading页面已经加载过一遍的图片在游戏中真正用到的时候还会再请求。所以针对这个问题,和别人讨论和写demo重现尝试过后发现了问题所在和想了一套解决方案。写下记录,防止以后忘记。

原来的写法

原来有问题的写法是参照旧时普通单页面游戏的写法,所有游戏都在同一个路径下,由js控制显示不同div来实现页面切换,本质上就是一个页面。所以

new Image().src = '//24haowan.com/preload.png'

这种写法,图片是会缓存在当前页面。

而这种写法在用vue搭建的项目里就不太好用了。切换到其他组建之后,预加载的图片已经找不到了,浏览器还是会向后台发起请求。尽管第二次服务器返回的是304,但是还是会有延迟,达不到图片秒加载的效果。

最终,写demo重现了以上问题,总结出了以下规律:

在组建A中使用new Image().src = 'resource'的方式加载图片,组建B中使用<img :src="require('resource')">的方式加载图片,然后

  1. 从组建A跳转到组建B,会加载两次图片
  2. 从组建B跳转到组建A,只会加载一次图片

所以可以初步得出结论:

使用new Image().src = 'resource'方式加载图片不会被缓存。我简单猜测,在组建A中加载的图片没有被插入到html中,图片缓存始终是在js里,而组建切换之后,组建A销毁了js代码,导致缓存的图片被清理掉。

解决办法

解决办法本质上就是不让预加载的图片被清理掉。

把预加载的图片存到全局变量

和phaser的思路一样,把new Image()得到的dom对象都存在一个对象中,在真正用到的时候,把需要的图片dom对象插入到合适的地方。

优点:真正的复用对象,理论性能最高
缺点:

  1. 好像vue的v-html方法不能直接插入一个dom对象。
  2. 如果把图片放到背景里怎么操作?

把预加载的图片插入到html里。

把所有的图片路径放入一个数组,v-for一遍都插入html里。

用一个img标签循环加载图片资源

用一个隐藏的img标签,循环加载图片资源路径,缺点是难以实现多张图片异步加载。