Browse > Home » FLEX » flex 客户端缓存 module swf

flex 客户端缓存 module swf

八月 22nd, 2009 Leave a comment

flex或者flash客户端的缓存,并不是指浏览器的缓存,浏览器的缓存在一定时间后会过期,先作此声明。
使用flex或者flash开发出来的网站最大的问题就是swf文件过大,国内网速有限,导致加载时间过长,这样会丢失很多潜在的客户。
flex使用RSL技术,可以解决框架的缓存与共享,很大程度的解决了加载问题。但是如果项目过大,还是会导致加载时间很长这个问题。我使用了SharedObject进行客户端的SWF与Module的缓存,并进行版本控制。在服务器端做一个配置文件,客户端若有缓存过数据,则进行版本控制,达到客户端数据与服务器端数据保持一样。
例子:
假设现在有个Application的项目,生成的Application.swf文件是2028K,客户端的下载速度是100k/s,则差不多需要使用20秒的时间。现在将Application中的部分源码抽出来,使用Module机制,变成Application.swf 428K,Module1.swf 1000K,Module2.swf 600K。不使用缓存的话,完整的加载完Application还是需要差不多20秒时间,若使用缓存,将Module1.swf与Module2.swf缓存在客户端,则只需要加载Application.swf的428K,差不多4秒时间,加上Moduel的读取2秒时间,最多也就6-7秒时间。效率很明显。而且还可以缓存其他的乱七八糟的东西,例如皮肤.swf,图片资源.swf等等.如果有跳转页面的话,还可以将Application.swf也进行缓存。
问题:
如果遇到客户端不允许缓存,则跳过缓存,无碍程序的加载和运行。
如果一个用户,多次的打开本网站,说明对本网站有了一定的兴趣,在多次被询问是否允许缓存后,点击允许的可能性也加 大。
当用户能够清楚的了解到缓存的好处时,允许缓存,一.可以加速用户体验,二.可以降低服务器压力,三.可以降低服务器带宽的使用。
文章最后有一个Demo供下载测试使用,源代码暂时打包成SWC,未开放出来。
下面将解释一下如何使用WarmC.swc:
配置文件’Cache_config.xml’

        <data id="moduleOne" version="beta01"/>
	<data id="moduleTwo" version="beta01"/>
	<data id="mySwf" version="beta01"/>

*当然,配置文件的路径,和名字可以由你任取,但需要在版本控制时指定路径,下面将介绍如何启动版本控制
*id属性,标记这个缓存的名字,将会在全局使用,包括缓存的SharedObject名称,以及版本控制,下面读取缓存时将会使用到这个id
*version版本控制,随你起名称。但是为了确保不会与以前的版本混淆,推荐最好还是使用递增的版本名称
首先必须在缓存的使用之前先启动版本控制,需要导入以下包:

import WarmC.Cache.LocationDataProxy;

然后启动版本控制:

LocationDataProxy.getInstance().CacheReBuild(0.5);

CacheReBuild(size:int,configUrl:String)方法使用说明:
* size参数,指定缓存的总大小,单位为兆(M),不填则默认为1M即运行到这个地方时,就会判断客户端的SharedObject 允许缓存大小,再提示用户修改缓存最大值设置如果你需要缓存的数据较大,则可对应取下面的值
size<=0 不提示,或者默认客户端的100Kb
0 1<=size<10 缓存10Mb以内的数据
10<=size 缓存无限大的数据
例如:你需要缓存的文件总大小为700K,你可以设置size=0.7,这样子,就会在启动版本控制的是很对用户进行询问,而且保证用户同意缓存以后不会再次询问
* configUrl,是指配置文件XML地址,默认是在根目录'Cache_config.xml',必须指定,并且配置文件格式必须与Demo格式一致
* 当配置文件正确无误时,版本控制启动成功,会读取服务器端配置,与客户端缓存进行版本比较。版本不同的话,将客户端缓存删除。如果版本控制启动失败,会导致客户端的缓存与服务器端的缓存无法同步。
设置缓存人性化功能

LocationDataProxy.getInstance().Warm_Human(true);

Warm_Human(bool:Boolean)说明:
* FlashPlayer的SharedObject,在使用超过客户端的设置大小后,就会提示用户,并征求其意见,是否同意网站的缓存
* 如果,在系统需要缓存多个数据时,而且用户拒绝了缓存,系统将会在每次需要写入SharedObject时,都进行询问是否允许缓存,这样的用户体验十分糟糕。
*当设置Warm_Huma为true时,在第一次提示用户是否允许程序缓存改大小后,如果用户拒绝了,以后的缓存将不会再提示,也不会再在客户端缓存,直到用户再次运行此程序( :grin: ,虽然是有点烦人,但嫌麻烦,多数人不会在意那几M的空间,而点了允许)
* false,不管用户是否拒绝,每次需要增大缓存区大小时,都会提示用户
* 不使用该方法,默认为true。所以这个方法很少用到。
确保版本控制启动成功后,可以进行module加载,先导入以下包:

import WarmC.Cache.ModuleCacheProxy;

加载module

ModuleCacheProxy.getInstance().load("moduleOne","ModuleOne.swf",onProgress,onReady);
function onProgress(bytesLoaded:uint,bytesTotal:uint):void{
	trace(">加载ModuleOne:"+bytesLoaded+"/"+bytesTotal);
}
function onReady(data:Object):void{
	trace(">ModuleOne 加载完成!");
	Application.application.addChild(data as UIComponent);
}

* load(name:String,url:String,onProgress:Function,onReady:Function)说明:
* name,指的是Module在配置文件Cache_config文件中的ID,此处必须与配置文件一致。用于版本控制,以及
客户端的缓存文件名,通过name获取SharedObject
* url,指的是Module的Swf文件路径,Demo的Module文件均在根目录,所以直接指定名称
* onProgress,指加载Module时的进度回调方法,传回两个参数,bytesLoaded与bytesTotal,若需要显示进度条,则这个方法是必备的。如果缓存不存在,则bytesLoaded与bytesTotal会是从服务器端加载数据的值;
如果缓存已经存在,则该方法只调用一次,而且两个回传参数均是100
* onReady,指加载完成后的回调方法,传回一个UIComponent类型的参数data
* 代理器使用了饿汉单例模式,检测module是否已经缓存在客户端。
* 如果已经缓存在客户端,则直接读取
* 否则,从服务器端加载,显示,再缓存到客户端,打上版本。
加载SWF(非module),需导入以下包:

import WarmC.Cache.SwfCacheProxy;

加载SWF:

SwfCacheProxy.getInstance().load("mySwf","test.swf",onProgress,onReady);
function onProgress(bytesLoaded:uint,bytesTotal:uint):void{
	trace(">加载SWF:"+bytesLoaded+"/"+bytesTotal);
}
function onReady(data:Object):void{
	trace(">SWF 加载完成!");
	var load:Loader = new Loader()
	load.loadBytes( data as ByteArray );
	var uic:UIComponent=new UIComponent();
	uic.addChild(load); 
	Application.application.addChild(uic);
}

* load(name:String,url:String,onProgress:Function,onReady:Function)说明:
*属性作用与ModuleCacheProxy一样
*唯一不同点,onReady方法的回传参数为一个ByteArray,需要自己进行包装目前使用起来就是这样。你可以使用SwfCacheProxy来缓存皮肤Style.swf,游戏插件,图片资源等等Swf数据。
在例子中,有个“加载Module 2”:

private function loadModule2():void{
	ModuleCacheProxy.getInstance().load("moduleTwo","ModuleTwo.swf",onProgress,onReady);
	ModuleCacheProxy.getInstance().load("moduleTwo","ModuleTwo.swf",onProgress,onReady);
	function onProgress(bytesLoaded:uint,bytesTotal:uint):void{
		trace(">加载ModuleTwo:"+bytesLoaded+"/"+bytesTotal);
	}
	function onReady(data:Object):void{
		trace(">ModuleTwo 加载完成!");
        	Application.application.addChild(data as UIComponent);
	}
}

细心点,你就会发现,moduleTwo.swf使用ModuleCacheProxy加载了两次。嗯,这是为了演示一下,如果在一个swf还未加载完毕,再将他加载一遍,就会被拒绝。如果你想一次性将一个SWF加载多次(也可以说Copy多个Swf),将会遭到拒绝,你可以一个一个慢慢加载,在onReady方法里面加载。或者根本可以不用使用加载,直接使用复制,如何复制,自己去google啦。
这样可以避免一点,加载缓存时很卡。 :cry:
另外,做人得厚道点。别什么东西都往人家C盘上面塞。 :evil:
罗嗦了这么多,看Demo吧。flex 客户端缓存 module swf 如果发现什么Bug的话,欢迎留言…

转载请注明: 出自 FlexHome
原文链接:http://flex.desizen.com/flex-client-cache/

Related Posts

46 条评论 »
  1. ydjin (2009/08/24) Reply to this comment

    没有细看,但我觉得 有点小题大作了
    读配置文件是会有失败事件的,都不成功怎么办?
    其实你完全可以给你项目定一个版本号的,public static const myVersion:String=’0.05′;//客户端版本
    然后在加载模块的时候这样 module.swf?version=”+Param.myVersion
    至于主应用程序 可以看看这篇文章
    http://ydjin.com/blog/read.php?10

  2. warmC (2009/08/24) Reply to this comment

    @ydjin: 呵呵,ydjin果然是没有细看.我这个和你的缓存是不同的两码事。你是为了避免出现IE缓存和服务器端数据改变的冲突。而我这个是特意将Module缓存在客户端,而非在IE缓存,IE缓存会过期。这样客户端打开网站的时候,直接从本地缓存读取数据,而不用再加载(对于大型项目,或者过M的游戏,这是一段刻骨铭心的过程)。 :grin:

  3. HeptaFish (2009/08/25) Reply to this comment

    还是有些问题吧 shareobject最大的存储只有10MB 而且超过一定大小player会弹出提示 不是所有用户都愿意点击同意的

  4. warmC (2009/08/25) Reply to this comment

    @HeptaFish:嗯,这个确实是个逃避不了的问题。应该是心理战。如果用户对你的网站感兴趣,他在你的多次提示后(多次,指的是多次打开网站),难免会点击允许。而且看你怎么诱导用户,关键一点需要提及,这个缓存的好处,是对浏览者有好处,而不是对开发商有好处。另外,纠正一下,sharedobject的最大存储是无限制。 :grin:

  5. isLand (2009/09/12) Reply to this comment

    小弟有其他一些问题想交流一下! 我看到很多人都在说如果as写的好的话是不存在内存泄露的问题的! 那么我想请问一下,在写as的时候有没有一些关于规范性的文件,,这个规范性的文件就是as写的时候参照的一个文档,以用来避免内存的泄露!
    我的qq号:605408781

  6. warmC (2009/09/13) Reply to this comment

    官方的 Flex SDK的编码规范, 也有一个叫 Adobe Flex Coding Guidelines的。不过非Adobe官方文档。你可以google一下。内存泄露、GC的解决方法网上也众说云云。

  7. zfj004588 (2009/11/01) Reply to this comment

    内存泄露、GC的解决方法,如你(warmC )所说的众说云云,你这个办法确实不错。什么时候能把源码放出来研究一下。

  8. joel (2009/11/02) Reply to this comment

    @zfj004588:文中有demo

  9. skywalker (2009/11/04) Reply to this comment

    如果缓存在客户端的话代码的安全性不就不好了?很容易被反编译然后hack,这种情况怎么解决呢?

  10. warmC (2009/11/04) Reply to this comment

    这种情况的话,跟swf缓存在浏览器缓存,然后反编译的情况差不多。但是有一点写入到SharedObject里面的数据是以SharedObject的格式。这都是同属Flash的弊端啦……

  11. SS (2009/11/30) Reply to this comment

    拜读了大师的文章,也不知道如何缓存模块哦,可以明白点说下吗?感激不尽

  12. warmC (2009/11/30) Reply to this comment

    下载个Demo看看吧,将模块缓存成SharededObject,然后再序列化加载。

  13. SS (2009/12/01) Reply to this comment

    谢谢提示,我应该会弄出来了。您这个方法是现在主流的游戏缓存方式吗?

  14. warmC (2009/12/01) Reply to this comment

    不敢这么说。现在的游戏很多都是使用浏览器缓存,sharedObject缓存一些游戏数据。

  15. mcx (2009/12/29) Reply to this comment

    我想请问一下 按照你所说的方法缓存之后 会影响系统的性能吗

  16. warmC (2009/12/30) Reply to this comment

    @mcx: 如果Module体积过大,在加载的时候有点卡。其他的性能问题,我暂时还没发现。如果你发现了什么问题,欢迎交流…

  17. ylw (2010/03/11) Reply to this comment

    我想请问一下SwfCacheProxy.getInstance().load(“mySwf”,”test.swf”,onProgress,onReady);
    能调用myswf里面的代码吗(如果里面有的话)

  18. ylw (2010/03/11) Reply to this comment

    今天问的那个问题搞定了,呵呵,是不是问的有点傻把帖删了?

  19. warmC (2010/03/12) Reply to this comment

    没删。调用的话和平时加载没啥两样吧?不知你是怎么解决的!

  20. joel (2010/03/12) Reply to this comment

    @ylw:没有删,只是因为你第一次留言,没有通过审核而已.

  21. cs (2010/06/18) Reply to this comment

    能够解释一下,SWC中的如下代码是什么意思吗?先谢过
    import VersionModle.as$2.*;
    import MySharedObject.as$0.*;

  22. vincent_guo (2010/08/16) Reply to this comment

    WarmC.Cache.LocationDataProxy
    这几个包是博主自己写的吗?看不到代码~

  23. warmC (2010/08/21) Reply to this comment

    是的。回头放上来!

  24. 为雨漂泊 (2010/09/03) Reply to this comment

    楼主,拜托了,赶快公开的源码吧,千恩万谢啊

  25. 为雨漂泊 (2010/09/03) Reply to this comment

    :cry: 焦急等待中…….

  26. Neway (2010/10/11) Reply to this comment

    求SWC源码。。

  27. 3d (2010/10/14) Reply to this comment

    新手问下,现在flex本身在加载的时候是不是有自己的自动加载缓存技术(非人为主动缓存),但是flex好像自己不支持html的object吧,比如一个播放器啊,什么的,在他缓存后,我打开项目再刷新IE,IE就崩溃了,我怀疑是缓存的问题,能不能让她自己在加载的时候不使用缓存技术。谢谢

  28. warmC (2010/10/15) Reply to this comment

    你说的是浏览器的缓存吧。如果有需要,可以对html页面设置不进行任何缓存。相关信息,可以Google一下。

  29. warmC (2010/10/15) Reply to this comment

    正准备重新写一下,放上来

  30. dnvlnl (2010/10/20) Reply to this comment

    关注一下。

  31. 小耀 (2010/11/10) Reply to this comment

    当我们浏览过新浪,腾迅,网易等门户网站以后
    断线的时侯我们在浏览器中输入它们的主页网址
    仍然可以看到它们在本地存储的页面而不是显示该页无法显示的页面
    请问是这是如何实现的,谢谢!

  32. mouse20 (2010/11/11) Reply to this comment

    期待SWC源码中。。。。

  33. joel (2010/11/13) Reply to this comment

    @小耀:你说的那个应该叫”脱机工作”,和flex没关系.

  34. forking (2010/12/13) Reply to this comment

    这个包只提供加载module,没有unload module功能.

  35. 工作 (2010/12/20) Reply to this comment

    等待WarmC.swc开源。。。hurry

  36. wdl (2011/03/24) Reply to this comment

    请问下为什么我测试的时候moduleTwo改变了 可是显示的时候没有更新过来啊?
    把版本设成always的时候是每次刷新页面都会把之前缓存的版本重新删掉 那样可以更新过来, 不是可以自动更新然后打版本号的么? 咋不管用呢?

  37. wdl (2011/03/24) Reply to this comment

    :| :???:

  38. vinson (2011/04/10) Reply to this comment

    加载JNF2Module:5257667/5257667

    onProgress执行完了

    onReady function 就不执行了

    不知道什么原因
    求解啊 谢谢

  39. 工作啊 (2011/04/26) Reply to this comment

    想看源码啊

  40. NANA (2011/06/02) Reply to this comment

    为什么下载不了呢?是不是因为用的是教育网?我对这个蛮感兴趣的~有下载下来的可以发到我邮箱一份吗?houhongying24@gmail.com,十分感谢!!

  41. hello_kim (2011/06/03) Reply to this comment

    期待源码。 :roll:

  42. flex (2011/07/18) Reply to this comment

    用了你的缓冲,远程调用时候出现错误,提示远程调用服务端函数时提示调用不到函数。请问是怎么回事啊?

  43. flex4 (2011/10/07) Reply to this comment

    为什么从本地下载swf时.显示不出来. 还有.我用的flex 4

  44. Edison (2011/10/10) Reply to this comment

    服务器:
    Server version: Apache/2.2.17 (Ubuntu)
    Server built: Feb 22 2011 18:33:02

    系统:
    Linux userver 2.6.38-11-generic-pae #48-Ubuntu SMP Fri Jul 29 20:51:21 UTC 2011 i686 i686 i386 GNU/Linux

    监控工具:
    Fiddler2 2.3.64

    浏览器:
    IE 8

    操作步骤:
    假设之前从未访问过目标网页
    1. 操作:请求嵌入SWF的目标网页
    响应:在Fiddler2中看到http请求的状态为200
    2. 操作:刷新浏览器
    响应:在Fiddler2中看到http请求的状态为304
    3. 操作:刷新浏览器
    响应:在Fiddler2中看到http请求的状态为304或者cache
    4. 操作:在ubuntu中touch 目标网页中所嵌入的SWF文件
    5. 操作:刷新浏览器
    响应: 在Fiddler2中看到http请求的状态为200
    6. 操作:刷新浏览器
    响应:在Fiddler2中看到http请求的状态为304
    7. 操作:刷新浏览器
    响应:在Fiddler2中看到http请求的状态为304或者cache

    这个实验说明,如果SWF文件的创建日期被修改了,IE会自动去下载最新的SWF文件。否则,IE会使用缓存中的SWF文件,因此,理论上是不需要管理SWF缓存的。

  45. Pony (2011/10/11) Reply to this comment

    用了你的缓冲,感觉效果还是不错的,但是有一个问题,当我第一次调用的时候没有问题,页面也能正常显示,但是第二次调用就会出现:*** 正在加载中,如需二次加载,请稍后……,请问这是什么问题呢?

  46. Trainers (2011/12/03) Reply to this comment

    博主很牛x

Leave a Reply

emoticons