Zepto assets 模块的原理?

阅读 1030
收藏 29
2015-11-16
原文链接:segmentfault.com

这个要从mobile safari严格的资源占用限制说起;mobile safari要比桌面版的浏览器的资源占用限制严格的多:
developer.apple.com/library/saf…

其中一条相关的限制就是:**When Mobile Safari has loaded between 8 to 10 MB of image data it will simply stop displaying any more images. It might even crash.**

当Mobile Safari加载8-10M左右图像数据的时候,将会停止显示甚至Crash,比如下面的这种应用场景。

为了解决这个问题,我们就要回收掉这些图片资源。

想到的方法一:

var img = document.getElementById('previous');
img.parentNode.removeChild(img);

但是令人遗憾的是,出于某些原因,真正的图片数据根本没法释放,那应该怎么办呢?如果我们用一张非常小的图片替换掉原来的大图片,原来的图片数据是不是就会被清空掉?Let's Try。

能起作用的方法:

var img = document.getElementById('previous');
img.src = 'images/empty.gif';

这个方法貌似起作用了!我们用一张非常小的gif图片变更掉原先图片的src,原来的大图片得到释放了,黑科技万岁啊!但是.......故事显然还没有结束,目前为止,你还需要关注以下三件非常重要的事情:

  1. src替换法不会使得图片资源马上释放,垃圾回收机制将在相当长的一段时间后才能回收掉这些内存资源,因此,当你在使用场景里太快的添加img资源的时候,还是会发生讨厌的事情!

  2. Mobile Safari似乎不能再加载额外的图像资源,即使我们用了上面的黑科技回收掉了一部分或者全部的资源,除非重新加载整个页面来进行测试验证,这tm真是快把人逼疯了。

  3. 如果你想要在DOM中移除image元素,在变更src之前你还必须确保这个element没有被垃圾回收处理掉,不然老图片数据也有可能在这种情况下不得释放。

因此,终极的解决方案应该是:

var img = document.getElementById('previous');
img.parentNode.removeChild(img);
img.src = 'data:image/gif;base64,' + 
      'R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=';
window.timeout(function() {
img = null;
}, 60000);

这个故事的由来和贡献者来自于这个博客内容:www.fngtps.com/2010/mobile…,正是这个作者向zepto贡献了这个黑科技。
作者还测试了一下assets插件~

评论