原文地址:点击打开链接
as3 URLLoader加载很大的资源时,提前将资源切割成N个文件,能有效保持Flash Player的帧频不受影响,实验数据如下:
【原始资源大小为331M】实验一:
如果直接加载该资源,基本上会有10s+的卡顿时间,这段时间内flash不会更新屏幕,给用户造成极差体验。
实验二:
把资源切割成3000份,平均每份100多KB,然后队列加载,完全不会影响帧频,但是加载完成需要110多秒。
实验三:
把资源切割成1000份,平均每份300多KB,然后队列加载,完全不会影响帧频,且加载完成只需要30多秒。
实验四:
把资源切割成800份,平均每份420多KB,然后队列加载,在开始的1秒以内,会显著影响到帧频,加载完成用了26秒
实验五:
把资源切割成600份,平均每份560多KB,然后队列加载,在开始的1秒左右,会显著影响到帧频,然而加载完成仅用了20秒。
根据如上实验数据,我对于URLLoader(或者说flash以二进制方式加载文件)的工作机制,是这样理解的:
当第一次调用URLLoader的load方法时,flash avm与操作系统通信,调用底层IO API,由于第一次调用的时候,系统需要初始化一些IO相关的数据,比如计算需要加载的文件大小、开辟缓冲区什么、线程切换什么的,此阶段耗时大小主要与即将打开的文件大小有关,CPU只有在系统初始化完成以后才能返回到Flash avm,于是这个阶段可能会造成flash player卡屏(文件越大越明显)。
结合上面的实际数据,我进一步假设:
当使用URLLoader进行加载时,flash player是否会卡住,与将要加载文件的大小关系最大!为什么呢?因为,我认为Flash Player的URLLoader的工作机制是这样的:
调用load之后,Flash Player首先向操作系统请求文件的大小,操作系统计算文件的大小【耗时】,之后返回结果给Flash Player,Flash Player根据文件的大小,向操作系统指定所要开辟的缓冲区大小,操作系统开辟缓冲区【耗时】之后,与Flash Player的通信通道正式建立,如果Flash Player没有显式断开这个通道,那么这个通道会一直存在(可能会被avm回收),于是,之后的过程是这样的:系统读取文件,直到缓冲区满,就发生一次系统与Flash Player的通信(数据从系统传到Flash Player),然后重复这个过程,直到读取完毕。
综上,我得出一个公式,
URLLoader加载一个文件所需的时长 【loadTime】
与文件大小 【fileSize】
与IO缓冲区大小 【buffSize】
与系统第一次初始化IO相关耗时大小 【initIOTime】
以及Flash Player帧频 【fps】
以及Flash Player与系统底层每一次通信所需的常量时间【T】
的关系为:
【loadTime】 = 【initIOTime】 + (【fileSize】/【buffSize】) * 【T】
【FPS】 = 1 / 【initIOTime】
根据实验现象我们得知,initIOTime越大,在刚开始加载的时候,flashplayer可能会卡屏,甚至会严重的卡住不动,这应该会给用户造成非常不好的体验。
在页游开发中,如果只为了获得一个流畅的帧频,那么建议把每个素材文件的尺寸控制在300KB以下,并辅以正确的队列加载。
但是这样会使总的加载时间较长。
再结合公式【loadTime】 = 【initIOTime】 + (【fileSize】/【buffSize】) * 【T】
我们知道【initIOTime】是一个几乎不会影响帧频的数值(一旦影响,就是顿卡,我们要避免这样的情况),同时【T】是一个常量,所以,我断定:
【当加载的文件越大】,【initIOTime】的值就会越大,几乎没有上限,甚至可能会导致死机;同时【fileSize】/【buffSize】的比值会越小,但是有下限。
【加载的文件越小】,【initIOTime的值会越小,但是有下限】,【fileSize】/【buffSize】的比值会越大(即发生在flash与系统的通信次数会越多),,因为每一次系统与Flash Player的通信只会传送少量数据,所以如果通信趟数过多,且超过某个阈值,那么每一帧上都可能会发生N次Flash Player与系统的通信,从整体来看(而非肉眼),这会影响Flash Player的帧频。
结论:我认为,在页游开发中,保持单个素材文件尺寸在500多KB以下,这样既不会导致flash顿卡,又能显著节约加载时间。
PS:以上结论只是个人揣测,但依据是具体实验数据,不喜勿喷
![](http://bbs.9ria.com/static/image/smiley/default/smile.gif)
而后,我再次做了实验,这次是用URLLoader加载远程服务器上面几百兆大小的文件,但是并没有造成顿卡,这应该是由于本地加载与远程加载时,走的IO通道不一样,当本地加载时,走的是系统原生的IO接口,远程加载时,由于通信协议封装了原生的IO接口,会自动选择缓冲区的大小(这时缓冲区一般很小),于是用户感觉不到卡。