目录

cacheAs 与 visible

编码示例

优化 DrawCall 与 Canvas

CacheAs 静态缓存优化


优化 Sprite 的常用方式如下:

1)尽量减少不必要的层次嵌套,减少Sprite数量

2)非可见区域的对象尽量从显示列表移除或者设置 visible=false

3)对于容器内有大量静态内容或者不经常变化的内容(比如按钮),可以对整个容器设置cacheAs属性,能大量减少 Sprite的数量,显著提高性能。如果有动态内容,最好和静态内容分开,以便只缓存静态内容。

4)Panel内,会针对panel区域外的直接子对象(子对象的子对象判断不了)进行不渲染处理,超出panel区域的子对象是不产生消耗的。

本文主要介绍使用 visible 与 cacheAs ,这两个属性都来自 laya.display.Sprite 类。

cacheAs 与 visible

/**
 * <p>指定显示对象是否缓存为静态图像,cacheAs时,子对象发生变化,会自动重新缓存,同时也可以手动调用reCache方法更新缓存。</p>
 * <p>建议把不经常变化的“复杂内容”缓存为静态图像,能极大提高渲染性能。cacheAs有"none","normal"和"bitmap"三个值可选。
 * <li>默认为"none",不做任何缓存。</li>
 * <li>当值为"normal"时,canvas模式下进行画布缓存,webgl模式下进行命令缓存。</li>
 * <li>当值为"bitmap"时,canvas模式下进行依然是画布缓存,webgl模式下使用renderTarget缓存。</li></p>
 * <p>webgl下renderTarget缓存模式缺点:会额外创建renderTarget对象,增加内存开销,缓存面积有最大2048限制,不断重绘时会增加CPU开销。优点:大幅减少drawcall,渲染性能最高。
 * webgl下命令缓存模式缺点:只会减少节点遍历及命令组织,不会减少drawcall数,性能中等。优点:没有额外内存开销,无需renderTarget支持。</p>
 */
cacheAs: string;

/**表示是否可见,默认为true。如果设置不可见,节点将不被渲染。*/
visible: boolean;

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

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

编码示例

class MyButton {constructor() {Laya.init(1136, 640, Laya.WebGL);//初始化引擎,不支持 WebGL自动切换为CanvasLaya.Stat.show(0, 0);/**显示性能面板 */this.btn_width = 150;//按钮的宽度this.btn_height = 40;//按钮的高度//使用引擎默认提供的按钮组件Laya.loader.load("res/atlas/comp.atlas", Laya.Handler.create(this, this.createButton));}/**创建 按钮 */createButton() {for (var i = 0; i < 5; i++) {for (var j = 0; j < 5; j++) {var btn = new Laya.Button("comp/button.png");//创建一个 Button 实例,使用引擎默认提供的按钮组件btn.label = "媛媛" + (i + 1) + "" + (j + 1);//按钮上显示的文本内容btn.labelSize = 20;//按钮文本标签的字体大小btn.width = this.btn_width;//设置按钮的宽度btn.height = this.btn_height;//设置按钮的高度btn.pos(i * this.btn_width + ((i + 1) * 20), (j * this.btn_height) + ((j + 1) * 10));//按钮显示的位置Laya.stage.addChild(btn);//将Button添加到舞台上//将整个舞台设置缓存为静态图像,cacheAs="normal"时,canvas模式下进行画布缓存,webgl模式下进行命令缓存//注意 cacheAs 静态缓存的是容器Laya.stage.cacheAs = "normal";//为按钮注册单击事件,同时将 button 传递过去,这样单击触发的时候在回调函数中好做处理btn.on(Laya.Event.CLICK, this, this.clickButton, [btn]);}}}//按钮点击之后的回调函数clickButton(button) {console.log("当前点击:" + button.label);//将所有按钮先设置为可见for (var i = 0; i < Laya.stage.numChildren; i++) {/**visible:表示是否可见,默认为true。如果设置不可见,节点将不被渲染 */Laya.stage.getChildAt(i).visible = true;}button.visible = false;//再将当前点击的按钮设置为不可见}
}
new MyButton();//运行本类

未设置 Laya.stage.cacheAs = "normal"; 静态缓存时结果如下,左上角可以看到此时 Sprite 的数量。

设置了 Laya.stage.cacheAs = "normal"; 静态缓存时结果如下,可以看到此时 Sprite 的数量显著减少。

优化 DrawCall 与 Canvas

优化 DrawCall :

  1. 对复杂静态内容设置cacheAs,能大量减少DrawCall,使用好cacheAs是游戏优化的关键。

  2. 尽量保证同图集的图片渲染顺序是挨着的,如果不同图集交叉渲染,会增加DrawCall数量。

  3. 尽量保证同一个面板中的所有资源用一个图集,这样能减少提交批次。

优化 Canvas:

在对Canvas优化时,我们需要注意,在以下场合不要使用cacheAs:

  1. 对象非常简单,比如一个字或者一个图片,设置cacheAs=”bitmap”不但不提高性能,反而会损失性能。
  2. 容器内有经常变化的内容,比如容器内有一个动画或者倒计时,如果再对这个容器设置cacheAs=”bitmap”,会损失性能。

可以通过查看Canvas统计信息的第一个值,判断是否一直在刷新Canvas缓存。

CacheAs 静态缓存优化

1、当cacheAs 属性值为 ”normal”时,Canvas 下进行画布缓存,webgl 模式下进行命令缓存。该模式性能优化中等,它能减少每帧渲染的节点数,但不会减少 DrawCall 数和 Shader数。

2、当cacheAs属性值为“bitmap”模式时,Sprite节点数、DrawCall、Shader 数都会下降。Canvas下依然是画布缓存,在webgl模式下使用renderTarget缓存,相当于缓存成静态位图提交显卡渲染。这里需要注意的是,webGL下renderTarget缓存模式有2048大小限制,超出2048会额外增加内存开销。另外,不断重绘时开销也比较大,但是会减少drawcall,渲染性能最高。

3、对于一些大型的游戏,节点数超过了50的UI不在少数,采用cacheAs缓存技术以后,渲染性能会提高很多倍。

如何选择缓存优化:

1、当使用bitmap位图缓存模式后,在CurMem内存数值上有所增加,由之前的17.22M增加到了18.27M,因为缓存位图时消耗了部分内存,但只要UI的宽高不是很大,增加的内存也不会太大。

2、最需要注意的是UI是否会频繁的刷新,如果很频繁,CPU的损耗会很大,因为缓存位图时子对象一旦发生改变,那么引擎会自动重新缓存位图,缓存位图的过程会消耗CPU。此时选择使用cacheAs的normal还是bitmap模式,或者不使用cacheAs,都需要对内存的增加与CPU消耗作为重点考量因素。

低端机型的配置因素:

1、项目中通常会考虑到手机配置,大多数情况是游戏适应的机型越多越好,游戏测试员也会用高中低端配置的手机去测试,然后提供优化建议。那么在使用cacheAs的时候,也需要参考手机的内存、CPU大小。

2、对于一些低端机来说,CPU与内存不高,如果为了提高渲染性能使用了cacheAs,有可能就会出现问题。这时开发者们就需要做取舍了,选择要性能还是要游戏机型的广度,或者取中。如果选择适应更多的低端机型,那么需要反复去测试,是否使用cacheAs,还要对比normal与bitmap模式哪种更适合,在优化性能的情况下尽量减少CPU和内存损耗。

如下情况下不能使用cacheAs:

1、当对象非常简单时,比如一个字或者一个图片,设置cacheAs不但不提高性能,反而会损失性能。

2、容器内有经常变化的内容,比如容器内有一个动画或者倒计时,如果再对这个容器设置cacheAs,会损失性能。

3、可以通过查看性能统计面板中的Canvas统计信息第一个值,如果一直在变化,说明一直在重绘,在这种情况下不能使用cacheAs。

如上所示,当标签处于动态的时候,不适宜为父容器 Sprite 设置 cacheAs,创建完成后再为父容器设置 cacheAs,代码如下:

class MyClass {constructor() {Laya.init(1136, 640, Laya.WebGL);//初始化引擎,不支持 WebGL自动切换为CanvasLaya.Stat.show(0, 0);/**显示性能面板 */this.setup();//设置标签的颜色数组this.dataColor = ["#A57676", "#007ACC", "#A0E272", "#09263B", "#FF3228", "#48C1AD", "#2789C9"];}setup() {//设置一个精灵,用于后面添加label,最后将精灵设置 cacheAsvar sp = new Laya.Sprite();Laya.stage.addChild(sp);var count = 0;//创建标签时计数Laya.timer.loop(20, this, function () {var label_info = this.createLabel();//创建标签//设置标签的坐标label_info.x = Math.round(Math.random() * Laya.stage.width - label_info.width);label_info.y = Math.round(Math.random() * Laya.stage.height - label_info.height);//随机设置标签颜色label_info.color = this.dataColor[Math.round(Math.random() * 7)];sp.addChild(label_info);//将标签添加到精灵中if (++count >= 1000) {//当创建标签个数超过1000个时,清除定时器不再创建Laya.timer.clearAll(this);/**将整个精灵缓存为图片,注意是为 精灵设置,而不是具体的标签*/sp.cacheAs = "bitmap";}});}//创建一个标签createLabel() {var text = Math.round(Math.random() * 100);var label_info = new Laya.Label(text);label_info.fontSize = 20;label_info.color = "#fff";return label_info;}
}
new MyClass();//运行本类

https://layaair.ldc.layabox.com/demo2/?language=ch&category=2d&group=Sprite&name=Cache

LayaAir cacheAs 缓存与 visible 隐藏相关推荐

  1. FineUI Grid 缓存列显示隐藏状态

    当列表字段过多时,需要隐藏掉一些,但是再次打开页面又显示出来了,FineUI没有提供缓存功能,那么自己动手,打开[ext-part2.js]找到 "if (Ext.grid.column.R ...

  2. picacg本地缓存目录_picacg隐藏模式在哪?picacg怎么进隐藏?

    picacg,每日更新超快,各类漫画看不停,让你可以在这里以最高权限观看喜欢的漫画资源,非常便捷,非常高效.南无picacg隐藏模式在哪?picacg怎么进隐藏?小编在这里为大家带来介绍. ​ 软件介 ...

  3. arm linux arp 支持,当ARP缓存为空 - RL-ARM 实时库用户指南

    ARP协议模块缓存所有接收的IP地址到一个内部缓冲器,它存储着IP地址和以太网地址(MAC). 当应用程序启动时,ARP 缓存缓冲器通常是空的.ARP模块还不知道来自于应用程序的第一个UDP数据包的目 ...

  4. 哔哩哔哩服务器在哪个文件夹,哔哩哔哩缓存在哪个文件夹 具体操作步骤

    我们在手机b站中缓存了视频,如果想要找到源文件,就必须要在手机的内部存储中去寻找,实际上,手机b站缓存的视频隐藏的很深,其查看路径为:文件管理/本地/内部存储/android/data/tv.danm ...

  5. FLEX中的组件隐藏显示是否占用位置的问题

    控制显示/隐藏组件的属性: 1.display 隐藏不占用位置,页面上的元素重新排列 2.visible 隐藏占用位置,即使隐藏也能看到空出的位置 3.includeInLayout 隐藏不占用位置. ...

  6. Android SurfaceView隐藏显示问题

    近日在搞一个直播项目,用SurfaceView显示直播远端画面,但是有一个需求就是加一个按钮,可以显示隐藏SurfaceView. <FrameLayoutandroid:id="@+ ...

  7. Android总结(基础篇)-骚人文客

    目录 Android总结 Android四大组件 Activity生命周期 添加网络权限 Intent Bundle--回转值跳转 显性意图 隐性意图 AndroidManifest.xml修改 然后 ...

  8. ExcelJS 使用帮助文档

    ExcelJS 使用帮助文档 个人备忘,原文地址:https://github.com/exceljs/exceljs/blob/master/README_zh.md 安装 npm install ...

  9. CH12-综合项目—仿美团外卖

    文章目录 目标 一.项目分析 目标 项目概述 开发环境 模块说明 二.效果展示 目标 店铺界面 店铺详情界面 店铺详情界面 确认清空购物车的对话框 菜品详情界面 订单界面和支付界面 三.服务器数据准备 ...

  10. Oracle性能优化-1-索引

    1.索引的基本概念 访问表的数据时,有两种方式,通过全表扫描找到这一行,或者通过ROWID找到该数据.当需要检索的数据所占表数据5%及一下的时候,考虑创建索引.使用索引要防止数据分散在多个块中. 不是 ...

最新文章

  1. Openstack组件实现原理 — Keystone认证功能
  2. 如何使用YUM列出包的内容?
  3. mfc 制作不同的文档模板mdi不同的子窗体_制作ACK集群自定义节点镜像的正确姿势...
  4. python网络爬虫基础知识_Python网络爬虫基础知识
  5. mac 键盘映射优化配置
  6. 什么叫白户,白户能贷款吗?
  7. 【更名通知】将以个人名义继续更新维护
  8. 左右伸缩_OPPO概念机将至!横向卷轴+左右伸缩,你期待吗
  9. 【reproject_inter】fits头文件的映射(1,改变fits文件的数据范围,2,对坐标系进行投影转换)
  10. 小米随身wifi没有网络显示无服务器,小米wifi怎么用 小米随身wifi无法上网怎么办...
  11. IT行业职位分为六大类
  12. 【转】C#调用Windows图片和传真查看器打开图片
  13. 手把手教你做项目多线程篇——基础知识详解
  14. opensuse12.2 KDE 使用环境配置
  15. zool网关多个组件配置路由
  16. IAR报错could not find the following source file
  17. Google谷歌拼音自动升级小秘密(解迷谷歌拼音输入法自动升级)
  18. 数分笔记整理21 - 数据处理项目 - 城市餐饮店铺选址分析 电商打折套路解析
  19. GOF设计模式之组合设计模式(结构型模式) ✨ 每日积累
  20. 前端通过url链接下载文件

热门文章

  1. EXECUTE IMMEDIATE oracle介绍
  2. MFC 中获取各种类指针的方法
  3. mysql node 可视化_使用Prometheus进行Substrate节点可视化监控
  4. 拓端tecdat|如何从xml文件创建R语言数据框dataframe
  5. 拓端tecdat|Excel实例:数组公式和函数
  6. Java read failed_android-获取java.io.IOException:读取失败,套接...
  7. python自动化接口测试excel脚本_python+requests+excel 实现接口自动化测试
  8. 免校准的电量计量芯片_电能计量芯片应用心得之选型篇
  9. 深度学习常用的数据集,包括各种数据跟图像数据
  10. 神经网络的Dropout的理解