性能优化1-列表渲染优化|社区征文

给大佬点赞!

大佬流弊,Mark一下

MARKK!

您好,我改了cocos2d-js-for-preview.js但是为什么运行起来没反应呢

你好。可能需要描述的更详细些我才好了解问题。
比如有没有按照流程修改其他内容?是否在浏览器运行?运行起来状态是什么?没有渲染任何东西?报错?或者其他之类的

已经成功处理了,一开始是改错地方了 :+1:

mark.

你好,使用这种方式,子节点修改opacity以及scale这种都会无效了是吗?

不会的,根据你的处理方式兼容原本的透明度计算就可以了。
比如上面的代码有提到,将透明度改为取渲染节点的父节点。
缩放我想,应该和这部分的代码没有关系,是出问题了吗?

我是后来在代码中动态修改透明度,会出现没反应,需要active变为false再变为true才有变化,然后有些子节点的scale缩放也会出现问题

子节点不渲染,然后导致父节点增加点击事件带缩放效果的时候,子节点没有缩放效果

我测试了一下,用代码修改透明度是没有问题的。可能需要检查一下你的相关逻辑。
不过缩放会有问题,父节点缩放的时候,子节点不会跟着缩放,这个部分我再研究一下源码。

我确认问题了。是由于改了渲染流程导致的。

  1. TRANSFORM(包含缩放)的更新是优先于CHILDREN的
  2. children的逻辑中,有一个变量(worldTransformFlag),当存在batcher.worldMatDirty时,变量值为true,此时子节点会执行_worldTransform。

原本的渲染流是parent->child。父节点执行_worldTransform函数的时候,会把batcher.worldMatDirty+1,等执行完所有后续渲染流之后,再-1。后续渲染流中包含了children,所以只要父节点执行了_worldTransform,子节点也会执行

修改之后的渲染流,一样是parent->child,但是,我们不是dfs了,父节点增加的worldMatDirty值,在渲染子节点的时候,已经扣掉了

确认问题后,一下子没想到好的解决办法。目前我的处理方式是,重写Node里的setScale函数,当节点是列表渲染节点时,遍历所有子节点,为他们增加_worldTransform渲染流程。例:

let func = cc.Node.prototype.setScale;

cc.Node.prototype.setScale = function () {

    func.call(this, ...arguments);

    if (this._isRenderListNode) {

        setChildWorldTransformDirty(this);

    }

}

let setChildWorldTransformDirty = function (node) {

    for (let child of node.children) {

        child._renderFlag |= cc.RenderFlow.FLAG_WORLD_TRANSFORM;

        setChildWorldTransformDirty(child);

    }

}

我这边测试是透明度有问题,我后来改成在改透明度时当前节点开启Children渲染,过一会再按层级渲染,只是active一变,当前节点透明度没问题,但是子节点不会透明

我目前的方式也是有属性改变时临时开起来子节点渲染,后续再关闭,按照层级渲染,我试一试这种方式

mark!!

Mark!!!

Mark!!!!!

我用了scrollView的滚动事件,监听content的滚动距离,列表就渲染可视区域的节点,来进行上下的替换,也可以达到draw call 优化的目的

这种也有部分优化,但是虚拟列表,不单单优化了渲染,还有加载时长等。这个可以按需选择的。