销毁元素
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
- 尽量减少不必要的层次嵌套,减少Sprite数量。
- 非可见区域的对象尽量从显示列表移除或者设置visible=false。
- 对于容器内有大量静态内容或者不经常变化的内容(比如按钮),可以对整个容器设置cacheAs属性,能大量减少Sprite的数量,显著提高性能。如果有动态内容,最好和静态内容分开,以便只缓存静态内容。
- Panel内,会针对panel区域外的直接子对象(子对象的子对象判断不了)进行不渲染处理,超出panel区域的子对象是不产生消耗的。
cacheAs
设置cacheAs可将显示对象缓存为静态图像,当cacheAs时,子对象发生变化,会自动重新缓存,同时也可以手动调用reCache方法更新缓存。 建议把不经常变化的复杂内容,缓存为静态图像,能极大提高渲染性能,cacheAs有"none","normal"和"bitmap"三个值可选。
- 默认为"none",不做任何缓存。
- 当值为"normal"时,Canvas下进行画布缓存,webgl模式下进行命令缓存。
- 当值为"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提供两种计时器循环来执行代码块。
- Laya.timer.frameLoop执行频率依赖于帧频率,可通过Stat.FPS查看当前帧频。
- 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
的函数执行会变得非常慢。