微信长时间不操作后点击会卡很久

测试结果出来了,看上面第二个图 这个函数花费了653.9ms的时间

1赞

我大概晓得原因了,因为我们游戏会产生大量的可点击物体,我看了一下源码:

_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的时候,才会遍历操作,并且清空,那么如果一段时间不点击屏幕,会造成这里的节点越来越多,于是造成卡顿

而且这里有两重循环,暂时没完全理清这块逻辑,不知道应该怎么优化

1赞

等5,6分钟的话卡顿就更明显,不过加入监听的节点也并没有非常多啊,顶多100,150个,所以不是很理解这个性能消耗为何如此巨大

这块我们会排查一下,感谢反馈。另外请问下这个问题是 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的节点只入数组一次,从而解决了这个问题

经过多次测试,发现问题已经得到了解决

2赞

附上修改后的源码 所有 _dirtyNodeMap相关的部分是为了修复这个问题而新增的代码
CCEventManager.js.zip (9.6 KB)

PS: 这个bug其实不仅会引发卡顿 还容易造成内存紧张,因为我们的游戏角色会经常移动,导致zIndex几乎每帧都会改变

1赞

确实有这个问题我也是2.0.9SP1,熄屏后再点亮,游戏就卡住了,过一会就正常了。

熄屏 是另外一个问题哈 也需要你改一下源码

怎么改?

https://forum.cocos.com/t/2-1-0-2-0-7-iphone-6s-ios-9-3/73031

我们这边 2.0.10 修复完后,好像还是会卡顿,能给个 demo 吗?
修复方法 https://github.com/cocos-creator/engine/pull/4209

如果屏蔽 preserveDrawingBuffer,是否能解决这个问题?
如果能解决,会不会遇到切换场景的过程中黑屏一下的问题?
如果不能解决,能给个 demo 吗?
抱歉之前我们内部信息同步不够及时,以为这个问题已经修复了。

相关代码 https://github.com/cocos-creator/engine/pull/4537

屏蔽preserveDrawingBuffer 能解决这个问题 微信版本暂时没有遇到黑屏一下的问题

但是我们的IOS版本,闪屏页过后会短暂黑屏【进入第一个场景前和IOS闪屏页之间的短暂黑屏】,比较恼火

1赞

收到,我们再试一下

目前遇到同样的问题,ios下自动息屏后再返回会卡死好久,安卓就不会。
测试了论坛里网友发的游戏都会这样。

前面给出解决方案啦,我们下个版本也会修复这个问题~

2.1.0 经过测试并没有解决哈

我们只能先尝试再次把 preserveDrawingBuffer 注释掉

屏蔽 preserveDrawingBuffe 可以解决
遇到切换场景的过程中黑屏一下是必现的, 例如会的进入游戏的首个场景就会