测试结果出来了,看上面第二个图 这个函数花费了653.9ms的时间
我大概晓得原因了,因为我们游戏会产生大量的可点击物体,我看了一下源码:
_setDirtyForNode: function (node) {
// Mark the node dirty only when there is an event listener associated with it.
if (this._nodeListenersMap[node._id] !== undefined) {
this._dirtyNodes.push(node);
这个函数会将加入监听的节点做一个标记 并且放入this._dirtyNodes
但是这个this._dirtyNodes 里的操作是在touch的时候,才会遍历操作,并且清空,那么如果一段时间不点击屏幕,会造成这里的节点越来越多,于是造成卡顿
而且这里有两重循环,暂时没完全理清这块逻辑,不知道应该怎么优化
这块我们会排查一下,感谢反馈。另外请问下这个问题是 2.0.9 新增的吗?方便提供一个 demo 吗?
嗯,我们正在努力做一个空项目能复现的demo 现在看来需要一些条件组合才会出现这个问题
哈喽,有 demo 了吗
抱歉来晚了,之前版本比较急,做demo时发现仅仅是生成大量带 touch linstener的节点无法复现卡顿的情况,于是临时去掉了屏幕常亮功能来降低这个bug的发生率,中间项目事情比较多这个问题就暂时搁置下来,但是还是会有不少人遇到这个问题。
今天晚上终于闲下来,感觉复现太瞎子摸象,于是仔细分析源码后得到了结论,进而问题得到了解决
这个问题发生的原因是node 改变zIndex 时 会调用_onSiblingIndexChanged, 继而把该节点的所有兄弟节点做污染标记
_onSiblingIndexChanged () {
// update rendering scene graph, sort them by arrivalOrder
var parent = this._parent;
var siblings = parent._children;
var i = 0, len = siblings.length, sibling;
for (; i < len; i++) {
sibling = siblings[i];
sibling._updateOrderOfArrival();
eventManager._setDirtyForNode(sibling);
}
parent._delaySort();
},
问题在于 CCEventManager 的 _setDirtyForNode 方法 :
if (this._nodeListenersMap[node._id] !== undefined) {
this._dirtyNodes.push(node);
}
会把所有带监听事件的节点都加入_dirtyNodes ,而没有考虑重复问题,那么当场景里有比较多事件监听节点,并且他们不断发生zIndex变化时,可怕的事情就发生了,_dirtyNodes会被无限膨胀
于是在用户点击时 _updateDirtyFlagForSceneGraph 里会去遍历_dirtyNodes,因而引发了性能瓶颈。
我解决的办法是加入一个_dirtyNodeMap 相同node._id的节点只入数组一次,从而解决了这个问题
经过多次测试,发现问题已经得到了解决
附上修改后的源码 所有 _dirtyNodeMap相关的部分是为了修复这个问题而新增的代码
CCEventManager.js.zip (9.6 KB)
PS: 这个bug其实不仅会引发卡顿 还容易造成内存紧张,因为我们的游戏角色会经常移动,导致zIndex几乎每帧都会改变
确实有这个问题我也是2.0.9SP1,熄屏后再点亮,游戏就卡住了,过一会就正常了。
熄屏 是另外一个问题哈 也需要你改一下源码
怎么改?
如果屏蔽 preserveDrawingBuffer,是否能解决这个问题?
如果能解决,会不会遇到切换场景的过程中黑屏一下的问题?
如果不能解决,能给个 demo 吗?
抱歉之前我们内部信息同步不够及时,以为这个问题已经修复了。
屏蔽preserveDrawingBuffer 能解决这个问题 微信版本暂时没有遇到黑屏一下的问题
但是我们的IOS版本,闪屏页过后会短暂黑屏【进入第一个场景前和IOS闪屏页之间的短暂黑屏】,比较恼火
收到,我们再试一下
目前遇到同样的问题,ios下自动息屏后再返回会卡死好久,安卓就不会。
测试了论坛里网友发的游戏都会这样。
前面给出解决方案啦,我们下个版本也会修复这个问题~
2.1.0 经过测试并没有解决哈
我们只能先尝试再次把 preserveDrawingBuffer 注释掉
屏蔽 preserveDrawingBuffe 可以解决
遇到切换场景的过程中黑屏一下是必现的, 例如会的进入游戏的首个场景就会



