Laya3d 内存优化

销毁元素

var  sp =  new  Sprite();
sp.destroy();

禁止回调垃圾回收

Laya.loader.load(urls, Handler.create( this , onAssetLoaded), Handler.create( this , onLoading,  null ,  false ));

资源卸载

var  assets = [];
assets.push( "res/apes/monkey0.png" );
assets.push( "res/apes/monkey1.png" );
assets.push( "res/apes/monkey2.png" );
assets.push( "res/apes/monkey3.png" );
  
Laya.loader.load(assets, Handler.create( this , onAssetsLoaded));
  
function  onAssetsLoaded()
{
     for ( var  i =  0 , len = assets.length; i < len; ++i)
     {
         var  asset = assets[i];
         console.log(Laya.loader.getRes(asset));
         Laya.loader.clearRes(asset);
         console.log(Laya.loader.getRes(asset));
     }
}

ColorFiter在Canvas渲染下需要计算每个像素点,而在WebGL下的GPU消耗可以忽略不计。
最佳的做法是,尽可能使用图像创作工具创建的位图来模拟滤镜。避免在运行时中创建动态位图,可以帮助减少CPU或GPU负载。特别是一张应用了滤镜并且不会在修改的图像。

优化Sprite

  1. 尽量减少不必要的层次嵌套,减少Sprite数量。
  2. 非可见区域的对象尽量从显示列表移除或者设置visible=false。
  3. 对于容器内有大量静态内容或者不经常变化的内容(比如按钮),可以对整个容器设置cacheAs属性,能大量减少Sprite的数量,显著提高性能。如果有动态内容,最好和静态内容分开,以便只缓存静态内容。
  4. Panel内,会针对panel区域外的直接子对象(子对象的子对象判断不了)进行不渲染处理,超出panel区域的子对象是不产生消耗的。

cacheAs

设置cacheAs可将显示对象缓存为静态图像,当cacheAs时,子对象发生变化,会自动重新缓存,同时也可以手动调用reCache方法更新缓存。 建议把不经常变化的复杂内容,缓存为静态图像,能极大提高渲染性能,cacheAs有"none","normal"和"bitmap"三个值可选。

  1. 默认为"none",不做任何缓存。
  2. 当值为"normal"时,Canvas下进行画布缓存,webgl模式下进行命令缓存。
  3. 当值为"bitmap"时,Canvas下进行依然是画布缓存,webGL模式下使用renderTarget缓存。这里需要注意的是,webGL下renderTarget缓存模式有2048大小限制,超出2048会额外增加内存开销。另外,不断重绘时开销也比较大,但是会减少drawcall,渲染性能最高。 webGL下命令缓存模式只会减少节点遍历及命令组织,不会减少drawcall,性能中等。

设置cacheAs后,还可以设置staticCache=true以阻止自动更新缓存,同时可以手动调用reCache方法更新缓存。

cacheAs主要通过两方面提升性能。一是减少节点遍历和顶点计算;二是减少drawCall。善用cacheAs将是引擎优化性能的利器。

文本

//后面只是更新文字内容,使用changeText能提高性能
text.changeText( "text changed." );

Text.changeText会直接修改绘图指令中该文本绘制的最后一条指令,这种前面的绘图指令依旧存在的行为会导致changeText只使用于以下情况:
· 文本始终只有一行。
· 文本的样式始终不变(颜色、粗细、斜体、对齐等等)。

减少动态属性查找

JavaScript中任何对象都是动态的,你可以任意地添加属性。然而,在大量的属性里查找某属性可能很耗时。如果需要频繁使用某个属性值,可以使用局部变量来保存它:

function  foo(){
     var  prop = target.prop;
     // 使用prop
     process1(prop);
     process2(prop);
     process3(prop);
}

计时器

LayaAir提供两种计时器循环来执行代码块。

  1. Laya.timer.frameLoop执行频率依赖于帧频率,可通过Stat.FPS查看当前帧频。
  2. Laya.timer.loop执行频率依赖于参数指定时间。
Laya.timer.frameLoop( 1 ,  this , animateFrameRateBased);
Laya.stage.on( "click" ,  this , dispose);
function  dispose() {
     Laya.timer.clear( this , animateFrameRateBased);
}

获取显示对象边界

第一种

var  sp =  new  Sprite();
sp.graphics.drawRect( 0 ,  0 ,  100 ,  100 ,  "#FF0000" );
var  bounds = sp.getGraphicBounds();
Laya.stage.addChild(sp);

第二种, 自动尺寸

var  sp =  new  Sprite();
sp.autoSize =  true ;
sp.graphics.drawRect( 0 ,  0 ,  100 ,  100 ,  "#FF0000" );
Laya.stage.addChild(sp);

加载图片后获得尺寸

var  sp =  new  Sprite();
sp.loadImage( "res/apes/monkey2.png" ,  0 ,  0 ,  0 ,  0 , Handler.create( this ,  function (){
     console.log(sp.width, sp.height);
}));
Laya.stage.addChild(sp);

直接设置

Laya.loader.load( "res/apes/monkey2.png" , Handler.create( this ,  function ()
{
     var  texture = Laya.loader.getRes( "res/apes/monkey2.png" );
     var  sp =  new  Sprite();
     sp.graphics.drawTexture(texture,  0 ,  0 );
     sp.size(texture.width, texture.height);
     Laya.stage.addChild(sp);
}));

帧频 fps

帧频有三种模式,
Stage.FRAME_SLOW维持FPS在30;
Stage.FRAME_FAST维持FPS在60;
Stage.FRAME_MOUSE则选择性维持FPS在30或60帧。

Laya.init(Browser.width, Browser.height);
Stat.show();
Laya.stage.frameRate = Stage.FRAME_SLOW;
  
var  sp =  new  Sprite();
sp.graphics.drawCircle( 0 ,  0 ,  20 ,  "#990000" );
Laya.stage.addChild(sp);
  
Laya.stage.on(Event.MOUSE_MOVE,  this ,  function (){
     sp.pos(Laya.stage.mouseX, Laya.stage.mouseY);
});
  • 延迟调用
var rotation=0,
scale=1,
position=0;
function setRotation(value)
{
  rotation=value;
  Laya.timer.callLater(this, update);
}
function setScale(value)
{
  scale = value;
  Laya.timer.callLater(this, update);
}
function setPosition(value)
{
    position = value;
    Laya.timer.callLater(this, update);
}
function update()
{
    console.log('rotation: ' + rotation + '\tscale: ' + scale + '\tposition: ' + position);
}

其它优化策略

1、减少粒子的使用数量
由于粒子属于矢量绘制,大量使用粒子对CPU压力大,在移动平台Canvas模式下,尽量不用粒子;
WebGL模式下可以采用GPU运算,能减轻CPU压力,但也要尽量控制,减少使用量。

2、Canvas模式尽量减少旋转,缩放,alpha等属性的使用
在Canvas模式下,尽量减少旋转,缩放,alpha等属性的使用,这些属性会对性能产生消耗。
如要使用,建议在WebGL模式下使用;

3、不要在Timer的循环里创建对象及复杂计算
由于Timer的loop()frameLoop()方法里会不断的循环执行,当创建对象及复杂计算时,会导致大量的性能消耗出现在循环里,因此,尽可能不要在循环里创建对象及复杂计算。

4、尽量少用autoSize与getBounds
autoSize()getBounds()需要大量计算,对性能的影响较大,尽量少用。

5、被try catch的函数执行会变得非常慢
项目中尽量减少try catch的使用,被try catch的函数执行会变得非常慢。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,080评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,422评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,630评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,554评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,662评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,856评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,014评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,752评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,212评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,541评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,687评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,347评论 4 331
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,973评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,777评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,006评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,406评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,576评论 2 349

推荐阅读更多精彩内容