关于 Cocos Creator 在 Chrome 控制台性能调试·指东不指南(略讲)

:smile: :smile:
希望 Cocos 越来越好

各位大佬如果也有独门调试的Debug技巧,欢迎来这分享一下呀, :grinning: :grinning:,
后续如果有新内容,会继续更新到这个帖子里面 :grinning:

量很多,给大佬点赞

1赞

:rofl:好长的文章啊,大佬太用心了

1赞

这么长的讲解,不收藏就说不过去了

1赞

补充个内容,刚刚一直在回忆,
原来是想补充这个内容,忙了一下子就整忘了,现在补充下::=>

Cocos 浏览器预览页面的 控制台黑科技 (简写版)

1. 控制台日志输出(Ctrl+L可以快速清除日志记录)

  • console.log :普通信息
  • console.info :提示类信息
  • console.error :错误信息
  • console.warn :警示信息
console.log('祝愿 Cocos越来越好 ~');
console.info('祝愿 Cocos越来越好 ~');
console.warn('祝愿 Cocos越来越好 ~');
console.error('祝愿 Cocos越来越好 ~');

2. 控制台输出的日志点击后,可以直接跳转到对应代码


3. 再配合 console.groupconsole.groupEnd ,可以将这种分类管理的思想发挥到极致

console.group("app.foo");
console.log("来自 Cocos 1 模块的信息...");
console.groupEnd();
console.group("app.bar");
console.log("来自  Cocos2 模块的信息...");
console.groupEnd();

3.1 如下图::=>

4. 关于 console.log , Chrome 提供了这么一个API:第一个参数可以包含一些格式化的指令比如 %c

//注意要%c放在第一个位置
//console.log的第二个参数里面就是CSS的样式表,但是控制台支持的有限
console.log('%c祝愿 Cocos越来越好 ~', 'background-image:-webkit-gradient( linear, left top, right top, color-stop(0, #f22), color-stop(0.15, #f2f), color-stop(0.3, #22f), color-stop(0.45, #2ff), color-stop(0.6, #2f2),color-stop(0.75, #2f2), color-stop(0.9, #ff2), color-stop(1, #f22) );color:transparent;-webkit-background-clip: text;font-size:5em;');

console.log('祝愿 Cocos越来越好 ~ %c', 'background-image:-webkit-gradient( linear, left top, right top, color-stop(0, #f22), color-stop(0.15, #f2f), color-stop(0.3, #22f), color-stop(0.45, #2ff), color-stop(0.6, #2f2),color-stop(0.75, #2f2), color-stop(0.9, #ff2), color-stop(1, #f22) );color:transparent;-webkit-background-clip: text;font-size:5em;');

console.log('%c祝愿 Cocos越来越好 ~', 'color:purple;font-size:5em;');

4.1 举例截图::=>(这不是很赞?)

5. console.table 直接以表格的形式将数据输出

let testData=[{
    'cocos2.4.1':"2D",
    'cocos3.4.2':"3D",
    'cocos2.4.2':"2D",
    'cocos3.4.1':"3D",
}];
console.table(testData);

5.1 如下图::=>

6. 条件判断输出日志 console.assert

当你想代码满足某些条件时才输出信息到 控制台
那么你大可不必写 if 或者三元表达式(let a=3>3?(true):(false))来达到目的,
cosole.assert 便是这样场景下一种很好的工具,
它会先对传入的表达式进行断言,只有表达式为假时才输出相应信息到 控制台

var isDebug=false;
console.assert(isDebug,'开发中的log信息。。。');

var isDebug=!false;
console.assert(isDebug,'开发中的log信息。。。');

var isDebug=!!false;
console.assert(isDebug,'开发中的log2信息。。。');

6.1 如下图::=>

7. 计数日志 console.count

统计某段代码执行了多少次时也大可不必自己去写相关逻辑,
控制台内置的 console.count 可以很地胜任这样的任务。

function cocosFoo(){
	//其他函数逻辑。。。
	console.count('foo 被执行的次数::=>');
}
cocosFoo();
cocosFoo();
cocosFoo();

7.1 如下图::=>

image

8. 数据树形输出 console.dir

将DOM结点以JavaScript对象的形式输出到 控制台,
直接将该DOM结点以DOM树的结构进行输出,
与在元素审查时看到的结构是一致的。不同的展现形式,同样的优雅

let testData=[{
    'cocos2.4.1':"2D",
    'cocos3.4.2':"3D",
    'cocos2.4.2':"2D",
    'cocos3.4.1':"3D",
}];
console.dir(document.body);
console.log(document.body);
console.dir(testData);

8.1 如下图::=>

9. 函数执行时间计算输出 console.time & console.timeEnd

需要考量一段代码执行的耗时情况时,可以用 console.timeconsole.timeEnd 来做此事

console.time("Cocos Array initialize");
var array= new Array(10000000);
for (var i = array.length - 1; i >= 0; i--) {
    array[i] = new Object();
};
console.timeEnd("Cocos Array initialize");

9.1 如下图::=>

image

10. 查看CPU使用相关的信息 console.profile & console.timeLime

当想要查看CPU使用相关的信息时,
可以使用 console.profile 配合 console.profileEnd 来完成这个需求。
这一功能可以通过UI界面来完成,
Chrome 开发者工具里面有个tab便是 Profile

与此类似的功能还有 console.timeLine 配合 console.timeLineEnd ,
它的作用是开始记录一段时间轴,
同样可以通过 Chrome 开发者工具里的 Timeline 标签来进行相应操作。

console.profile("Cocos Array initialize");
var array= new Array(1000);
for (var i = array.length - 1; i >= 0; i--) {
    array[i] = new Object();
};
console.profileEnd("Cocos Array initialize");

10.1 如下图::=>

image

11. 堆栈跟踪相关的调试可以使用 console.trace

堆栈跟踪相关的调试可以使用 console.trace
这个同样可以通过UI界面完成。当代码被打断点后,
可以在 Call Stack 面板中查看相关堆栈信息。
上面介绍的都是挂在 window.console 这个对象下面的方法,
统称为Console API,接下来的这些方法确切地说应该叫命令,
Chrome 内置提供,在 控制台 中使用的,他们统称为Command Line API

console.time("Cocos Array initialize");
var array= new Array(3);
for (var i = array.length - 1; i >= 0; i--) {
    array[i] = new Object();
    console.trace(i);
};
console.timeEnd("Cocos Array initialize");

11.1 如下图::=>

12. 控制台自带的内容:: $

Chrome控制台 里,$用处是蛮多且方便的
$_ 命令返回最近一次表达式执行的结果,$0~$4则代表了最近5个你选择过的DOM节点,
功能跟按向上的方向键再回车是一样的,但它可以做为一个变量使用在你接下来的表达式中:

2+2//回车,再
$_+1//回车得5

12.1 如下图::=>

image

13. 复制控制台的数据结构 copy

//通过此命令可以将在控制台获取到的内容复制到剪贴板
//其它类似数据也行,但有时候不支持(可能被其它代码覆盖了)
copy(document.body)

13.1 如下图::=>

14. 对象操作 keys & values

前者返回传入对象所有属性名组成的数据,后者返回所有属性值组成的数组

let testData2=[{
    'cocos2.4.1':"2D",
    'cocos3.4.2':"3D",
    'cocos2.4.2':"2D",
    'cocos3.4.1':"3D",
}];
let kk=keys(testData2[0]);
let vv=values(testData2[0]);
console.log(kk,vv);
//不一样的log日志输出:::=>
console.log("输出对象内容::=>",[kk,vv]);

14.1 如下图::=>

15. monitor & unmonitor

monitor(function),它接收一个函数名作为参数,
比如 function a ,每次 a 被执行了,
都会在 控制台 输出一条信息,里面包含了函数的名称 a 及执行时所传入的参数。

而unmonitor(function)便是用来停止这一监听。

function sayCocos(name){
	alert('hello,'+name);
}
monitor(sayCocos);
sayCocos('Cocos welcome you!');
unmonitor(sayCocos);
sayCocos('Cocos welcome you!');

15.1 如下图::=>

16. debug & undebug

debug同样也是接收一个函数名作为参数。当该函数执行时自动断下来以供调试,
类似于在该函数的入口处打了个断点,可以通过debugger来做到,
同时也可以通过在 Chrome 开发者工具里找到相应源码然后手动打断点。
undebug 则是解除该断点。

function sayCocos(name){
    debugger;
    //console.debug("testDebug");
	console.log('hello,'+name);
};

16.1 如下图, debugger 代码断点调试更好用::=>

image

17. console.clear(); 用代码清空日志

console.clear() ==> 直接清空控制台所有的日志

// 用代码清空日志
console.clear();

17.1 如下图, 清除效果::=>

5赞

牛逼 看着感觉自己成长了、不少

1赞

666,奈何自己没文化,一句666行天下。

1赞

收藏收藏,肯定有用

1赞

单凭大佬截图数量,给大佬递茶,递烟,递茅台,大佬辛苦了。

2赞

上班摸鱼算啥

置顶两个月,以表敬意

1赞

:grinning: :grinning:
感谢大大的关注和鼓励

:rofl:,有点失眠,就来补充点内容吧::=>
1.之前补充的控制台的整合写法(筛选的几种),稍微优雅一点? :slightly_smiling_face: :grin:
2. 白玉无冰 大佬的=> 一种入侵式的日志大法

// 注意: TS 开发环境
// const { ccclass, property, executeInEditMode, playOnFocus, menu } = cc._decorator;

// @ccclass
// @executeInEditMode
// @playOnFocus
export class clog {
    constructor() {
        // super();
    };
    //  * @param logType  日志类型
    // ```js
    // // example
    // cl.log('hello,cocos');
    // ```
    /**
     * !#en Log a DEBUG level message.
     * !#zh 输出 DEBUG 级别的信息。
     * @param logStrings  普通信息
     * @param cssStyle  样式
     * @example
     * import { cl } from "./com_console_new";
     * cl.log('hello,cocos', 'color:red;font-size:20px;');
    */
    //  export function log(...logStrings: string | any[], cssStyle: string = 'color:purple;font-size:5em;'): void {
    // log(logStrings: string | any[], cssStyle: string = 'color:purple;font-size:5em;'): void {
    log(logStrings: string | any[], cssStyle: string = ''): void {
        if (CC_EDITOR) {
            Editor.log(["log=>", logStrings], cssStyle);
        } else {
            if (cssStyle.length <= 0) {
                console.log(logStrings);
            } else {
                console.log('%c' + logStrings, cssStyle);
            };
        };
    };
    /**
     * !#en Log a DEBUG level message.
     * !#zh 输出 DEBUG 级别的信息。
     * @param logStrings 树形结构输出日志
     * @example
     * import { cl } from "./com_console_new";
     * cl.dir('hello,cocos');
    */
    dir(logStrings: string | any[]): void {
        if (CC_EDITOR) {
            Editor.log(["dir=>", logStrings]);
        } else {
            console.dir(logStrings);
        };
    };
    /**
     * !#en Log a DEBUG level message.
     * !#zh 输出 DEBUG 级别的信息。
     * @param logStrings 提示类信息
     * @example
     * import { cl } from "./com_console_new";
     * cl.info('hello,cocos');
    */
    info(logStrings: string | any[]): void {
        if (CC_EDITOR) {
            Editor.log(["info=>", logStrings]);
        } else {
            console.info(logStrings);
        };
    };
    /**
     * !#en Log a DEBUG level message.
     * !#zh 输出 DEBUG 级别的信息。
     * @param logStrings 错误类信息,爆红
     * @example
     * import { cl } from "./com_console_new";
     * cl.error('hello,cocos');
    */
    error(logStrings: string | any[]): void {
        if (CC_EDITOR) {
            Editor.log(["error=>", logStrings]);
        } else {
            console.error(logStrings);
        };
    };
    /**
     * !#en Log a DEBUG level message.
     * !#zh 输出 DEBUG 级别的信息。
     * @param logStrings 警告类信息
     * @example
     * import { cl } from "./com_console_new";
     * cl.warn('hello,cocos');
    */
    warn(logStrings: string | any[]): void {
        if (CC_EDITOR) {
            Editor.log(["warn=>", logStrings]);
        } else {
            console.warn(logStrings);
        };
    };
    /**
     * !#en Log a DEBUG level message.
     * !#zh 输出 DEBUG 级别的信息。
     * @param logStrings 表格样式结构输出日志
     * @example
     * import { cl } from "./com_console_new";
     * cl.table({hello:'hello,cocos',to:'world'});
    */
    table(logStrings: string | any[]): void {
        if (CC_EDITOR) {
            Editor.log(["table=>", logStrings]);
        } else {
            console.table(logStrings);
        };
    };
    /**
     * !#en Log a DEBUG level message.
     * !#zh 输出 DEBUG 级别的信息。
     * @param logStrings 分组结构输出日志
     * @example
     * import { cl } from "./com_console_new";
     * cl.group('hello,cocos');
    */
    // group(logStrings: string|any[]): void {
    group(logStrings: string): void {
        if (CC_EDITOR) {
            Editor.log(["group=>", logStrings]);
        } else {
            console.group(logStrings);
        };
    };
    /**
     * !#en Log a DEBUG level message.
     * !#zh 输出 DEBUG 级别的信息。
     * @param logStrings 分组结构End输出日志
     * @example
     * import { cl } from "./com_console_new";
     * cl.groupEnd();
    */
    groupEnd(): void {
        if (CC_EDITOR) {
            Editor.log("groupEnd");
        } else {
            console.groupEnd();
        };
    };
    /**
     * !#en Log a DEBUG level message.
     * !#zh 输出 DEBUG 级别的信息。
     * @param logStrings 开始记录时间日志
     * @example
     * import { cl } from "./com_console_new";
     * cl.time('hello,cocos');
    */
    // time(logStrings: string | any[]): void {
    time(logStrings: string): void {
        if (CC_EDITOR) {
            Editor.log(["time=>", logStrings]);
        } else {
            console.time(logStrings);
        };
    };
    /**
     * !#en Log a DEBUG level message.
     * !#zh 输出 DEBUG 级别的信息。
     * @param logStrings 时间日志结束
     * @example
     * import { cl } from "./com_console_new";
     * cl.timeEnd('hello,cocos');
    */
    timeEnd(logStrings: string): void {
        if (CC_EDITOR) {
            Editor.log(["timeEnd=>", logStrings]);
        } else {
            console.timeEnd(logStrings);
        };
    };
    /**
     * !#en Log a DEBUG level message.
     * !#zh 输出 DEBUG 级别的信息。
     * @param logStrings 堆栈跟踪调试日志
     * @example
     * import { cl } from "./com_console_new";
     * cl.trace('hello,cocos');
    */
    trace(logStrings: string | any[] | any): void {
        if (CC_EDITOR) {
            Editor.log(["trace=>", logStrings]);
        } else {
            console.trace(logStrings);
        };
    };
    /**
     * !#en Log a DEBUG level message.
     * !#zh 输出 DEBUG 级别的信息。
     * @param logStrings 记录代码执行次数日志
     * @example
     * import { cl } from "./com_console_new";
     * cl.count('hello,cocos');
    */
    count(logStrings: string): void {
        if (CC_EDITOR) {
            Editor.log(["count=>", logStrings]);
        } else {
            console.count(logStrings);
        };
    };

    /**
     * !#en Log a DEBUG level message.
     * !#zh 输出 DEBUG 级别的信息。
     * @param isShowBool 是否输出日志
     * @param logStrings 条件判断输出日志
     * @example
     * import { cl } from "./com_console_new";
     * cl.assert(true,'hello,cocos');
    */
    assert(isShowBool: boolean = true, logStrings: string | any[]): void {
        if (CC_EDITOR) {
            Editor.log(["assert=>", isShowBool, logStrings]);
        } else {
            console.assert(isShowBool, logStrings);
        };
    };
    /**
     * !#en Log a DEBUG level message.
     * !#zh 直接清空控制台的所有的日志
     * @example
     * import { cl } from "./com_console_new";
     * cl.clear();
    */
    clear(): void {
        if (CC_EDITOR) {
            Editor.log("clear");
        } else {
            console.clear();
        };
    };
    /**
     * !#en Log a DEBUG level message.
     * !#zh 一种入侵式的日志大法 
     * 参考::=>白玉无冰=>http://lamyoung.com/javascript/2020/12/30/log/
     * @param target 注意!如果有 update || lateUpdate 方法,会一直输出这个日志!!!请谨慎使用!!!
     * @example
     ```js
      import { cl } from "./com_console_new";
      // &#64; == @
      &#64;cl.logClassFunc();
      &#64;ccclass
     ```
     */
    logClassFunc(): any {
        return function (target: any) {
            const className = target.prototype.constructor?.name || 'No Name';
            const propNames = Object.getOwnPropertyNames(target.prototype);
            for (let i = 0; i < propNames.length; ++i) {
                const prop = propNames[i];
                if (prop !== 'constructor') {
                    const desc = Object.getOwnPropertyDescriptor(target.prototype, prop);
                    const func = desc && desc.value;
                    if (typeof func === 'function') {
                        let oldFunc = (func as Function);
                        target.prototype[prop] = function () {
                            console.log(`[${className}] [${prop}] Begin`, ...arguments);
                            const ret = oldFunc.call(this, ...arguments);
                            console.log(`[${className}] [${prop}] End`);
                            return ret;
                        }
                    }
                }
            }
        }
    };
};
// export function logClassFunc() {
//     return function (target: any) {
//         const className = target.prototype.constructor?.name || 'No Name';
//         const propNames = Object.getOwnPropertyNames(target.prototype);
//         for (let i = 0; i < propNames.length; ++i) {
//             const prop = propNames[i];
//             if (prop !== 'constructor') {
//                 const desc = Object.getOwnPropertyDescriptor(target.prototype, prop);
//                 const func = desc && desc.value;
//                 if (typeof func === 'function') {
//                     let oldFunc = (func as Function);
//                     target.prototype[prop] = function () {
//                         console.log(`[${className}] [${prop}] Begin`, ...arguments);
//                         const ret = oldFunc.call(this, ...arguments);
//                         console.log(`[${className}] [${prop}] End`);
//                         return ret;
//                     }
//                 }
//             }
//         }
//     }
// };
export let cl = new clog();

大佬这叫「略讲」,是我格局小了,给大佬递茶 :rofl: :rofl: :rofl:

1赞

大佬控制台玩得溜啊!

1赞

帖子收下,膝盖给你

1赞

续补 Console ::=>

1. 此处可以用鼠标拖动位置, 也可以在更多工具里面打开更多内容



2. 日志过滤和筛选(两种=侧边栏+所有级别)


3. 清空所有的日志内容 ( Ctrl+L )

4. 保留日志内容(刷新页面时不会被清除掉)

5. 筛选器筛选想看的日志信息

6. 快捷键查找日志(比较常用,方便+显眼) (Ctrl+F)


7. 补充一个和 Console 无关的内容 Vscode 编辑器的

7.0 前提用的是 Ts 做开发

7.1 在 Vscode 里面快速修改变量名 (默认快捷键)

选中变量名后按下 F2 ,输入新名字, Enter 回车

7.2 在 Vscode 里面多选+快速竖着多选 (默认快捷键)

Alt 多选+配合鼠标左键
Shift+Alt 快速竖着多选+配合鼠标左键
Ctrl+d 快速选中同名的内容+配合鼠标左键
Ctrl + Enter 可以从代码中换行 (这里不做演示)

7.3 在 Vscode 里面快速跳转代码 (默认快捷键)

Ctrl + 配合鼠标左键


F12 好像更方便一点点
F12跳转代码

8. 再补充一个论坛文章内容过多,如何启用浏览器自带的搜索功能?

快捷键 Ctrl+L 到 Ctrl+F

习惯了用 Chrome 自带的搜索, 论坛的 Ctrl+F 用不太习惯,偶然发现了这个地方,
而且可以在禁用 F12 控制台工具的页面也能打开

8.1 先 Ctrl+L (或者用鼠标左键) 选中地址栏,然后再 Ctrl+F ,就出来了,自由搜索

大佬666,先mark一下

1赞