Cocos Creator 2.1.1 性能优化 (二)

Cocos Creator 2.1.1 性能优化之分帧加载

一.原理

1.为什么要用分帧加载

如果一帧内执行了大量的同步耗时操作,会导致该帧出现卡顿。在低端设备上尤为明显。

2.如何优化

我们可以将原本在同一帧的操作,分散在之后的每一帧中完成,降低该帧的计算压力。

二、项目分析

1.cocos creator中不使用分帧加载的情况

假设我们需要在点击按钮的时候创建1000个预制体,并且获取该预制体上的脚本并赋值。

for (let i = 0; i < 1000; i++) {
    let temp = cc.instantiate(this.hello);
    temp.parent = this.content;
    temp.getComponent('test2').label.string = i;
}

为了让我们的实验效果更明显,在开始创建第一个预制体时播放一段加载动画,最后一个预制体创建完毕时关闭该动画。

this.mask.active = true;
this.animation.node.active = true;
this.animation.play();
for (let i = 0; i < 1000; i++) {
    let temp = cc.instantiate(this.hello);
    temp.parent = this.content;
    temp.getComponent('test2').label.string = i;
}
this.mask.active = false;
this.animation.stop();
this.animation.node.active = false;

完整代码

// Learn cc.Class:
//  - [Chinese] https://docs.cocos.com/creator/manual/zh/scripting/class.html
//  - [English] http://docs.cocos2d-x.org/creator/manual/en/scripting/class.html
// Learn Attribute:
//  - [Chinese] https://docs.cocos.com/creator/manual/zh/scripting/reference/attributes.html
//  - [English] http://docs.cocos2d-x.org/creator/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
//  - [Chinese] https://docs.cocos.com/creator/manual/zh/scripting/life-cycle-callbacks.html
//  - [English] https://www.cocos2d-x.org/docs/creator/manual/en/scripting/life-cycle-callbacks.html

cc.Class({
    extends: cc.Component,

    properties: {
        hello: cc.Prefab,
        content: cc.Node,
        mask: cc.Node,
        animation: cc.Animation,
    },

    // LIFE-CYCLE CALLBACKS:

    onLoad () {
        this.mask.active = false;
        this.animation.node.active = false;
    },

    click () {
        this.mask.active = true;
        this.animation.node.active = true;
        this.animation.play();
        for (let i = 0; i < 1000; i++) {
            let temp = cc.instantiate(this.hello);
            temp.parent = this.content;
            temp.getComponent('test2').label.string = i;
        }
        this.mask.active = false;
        this.animation.stop();
        this.animation.node.active = false;
    },

    start () {


    },
    // update (dt) {},
});

节点摆放:
图片摆放
效果展示:
一次性加载
从上图中可以看到我们预先制作的animation动画并未看到,并且点击按钮后卡了很久很影响体验。

2.使用分帧加载的情况

本示例中我们使用计时器的方法进行分帧加载,原理是将1000个for循环拆成一个一个的放进计时器中,每帧运行一次。

 /**
     * 
     * @param {string} name 给计时器分配一个name
     * @param {number} limit 每帧至少加载几个prefab
     * @param {number} max 最大加载的prefab数量
     * @param {function} cb 加载代码
     */
    //分帧加载
    _loadPrefabFrame (name, limit, max, cb) {
        let count = 0;
        this[name] = () => {
            if (count <= max) {
                for (let i = 0; i < limit; i++) {
                    count++;
                    cb && cb(count);
                    //关闭动画
                    if (count === max - 1) {
                        this.mask.active = false;
                        this.animation.stop();
                        this.animation.node.active = false;
                    }
                }
            }
        }
        this.schedule(this[name], 1 / cc.game.getFrameRate(), (max - 1) / limit, 0);
    },

完整代码

// Learn cc.Class:
//  - [Chinese] https://docs.cocos.com/creator/manual/zh/scripting/class.html
//  - [English] http://docs.cocos2d-x.org/creator/manual/en/scripting/class.html
// Learn Attribute:
//  - [Chinese] https://docs.cocos.com/creator/manual/zh/scripting/reference/attributes.html
//  - [English] http://docs.cocos2d-x.org/creator/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
//  - [Chinese] https://docs.cocos.com/creator/manual/zh/scripting/life-cycle-callbacks.html
//  - [English] https://www.cocos2d-x.org/docs/creator/manual/en/scripting/life-cycle-callbacks.html

cc.Class({
    extends: cc.Component,

    properties: {
        hello: cc.Prefab,
        content: cc.Node,
        mask: cc.Node,
        animation: cc.Animation,
    },

    // LIFE-CYCLE CALLBACKS:

    onLoad () {
        this.mask.active = false;
        this.animation.node.active = false;
    },

    click1 () {
        let cb = (i) => {
            let temp = cc.instantiate(this.hello);
            temp.parent = this.content;
            temp.getComponent('test2').label.string = i;
        }
        this.mask.active = true;
        this.animation.node.active = true;
        this.animation.play();
        this._loadPrefabFrame('test', 1, 1000, cb);
    },

    click () {
        this.mask.active = true;
        this.animation.node.active = true;
        this.animation.play();
        for (let i = 0; i < 1000; i++) {
            let temp = cc.instantiate(this.hello);
            temp.parent = this.content;
            temp.getComponent('test2').label.string = i;
        }
        this.mask.active = false;
        this.animation.stop();
        this.animation.node.active = false;
    },

    start () {


    },

    /**
     * 
     * @param {string} name 给计时器分配一个name
     * @param {number} limit 每帧至少加载几个prefab
     * @param {number} max 最大加载的prefab数量
     * @param {function} cb 加载代码
     */
    //分帧加载小实验
    _loadPrefabFrame (name, limit, max, cb) {
        let count = 0;
        this[name] = () => {
            if (count <= max) {
                for (let i = 0; i < limit; i++) {
                    count++;
                    cb && cb(count);
                    //关闭动画
                    if (count === max - 1) {
                        this.mask.active = false;
                        this.animation.stop();
                        this.animation.node.active = false;
                    }
                }
            }
        }
        this.schedule(this[name], 1 / cc.game.getFrameRate(), (max - 1) / limit, 0);
    },

    // update (dt) {},
});

效果展示
在这里插入图片描述
就结果而言比一次性加载效果好多了。但是分帧加载因为开启了计时器的缘故导致在加载少量prefab时所消耗的性能要大于一次性加载,所以应根据实际需求进行选择使用。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值