JavaScript 性能优化2 学习笔记

文章内容输出来源:拉勾大前端高薪训练营

1、性能测试工具 JSBench 使用

网址:https://jsbench.me/ 常用的 JSperf 已经停止维护了

  • Setup HTML 想初始化的dom
  • Setup JS 前置统一的js代码
  • Test Case 添加测试用例,具体的测试代码(一般两个)
  • Teardown JS 后置统一的js代码
    (每秒的次数 越大越好)

性能测试细节:尽可能开一个标签页、当前的进程不要关掉、多次执行

2、堆栈中代码执行流程

  • 首先堆内存中创建执行环境栈,执行环境栈中存放不同的执行上下文
  • 代码从上往下之下,先创建全局上下文,
  • 基本数据类型值存在栈内存中,由JS主线程管理,
    引用类型存放在堆内存中,一般由GC回收处理
  • 每当遇到函数执行,重新生成执行上下文进栈,
    代码执行完,由是否产生闭包决定我们当前的上下文中引用的堆要不要被释放掉
let a = 10;
function foo(b){
    let a = 2;
    function baz(c){
        console.log(a+b+c);
    }
    return baz;
}
let fn = foo(2);
fn(3);
ECStack 执行环境栈:
    EC(baz执行上下文)
        this = window
        
        AO:
            arguments:{0: 3}
            c = 3
            console.log(a + b + c)
            3 + 2 + 1 = 7
    EC(foo执行上下文)  
        this = window  
         // foo.ao代表自己的作用域
        AO: 
            arguments:{0: 2}
            a = 2
            baz = AB2 [[scope]] foo.AO
    
    EC(全局执行上下文)
        VO: 
            a = 10 (字面量直接存在栈中)
            foo = AB1 [[scope]] VO
            fn = AB2
堆内存:  AB1
    function foo(b){...}
    name: foo
    length: 1

堆内存:  AB2
    function baz(c){...}
    name: baz
    length: 1

3、减少判断层级

function doSomething(part, chapter){
    const parts = ['ES2016', '工程化', 'Vue', 'React', 'Node'];
    if(part){
        if(parts.includes(part)){
            console.log('属于当前课程')
            if(chapter > 5){
                console.log('您需要提供VIP身份')
            }
        }
    }else{
        console.log('请确定模块信息')
    }
}
doSomething('ES2016', 6);

//优化后
function doSomething(part, chapter){
    const parts = ['ES2016', '工程化', 'Vue', 'React', 'Node'];
    if(!part){
        console.log('请确定模块信息');
        return
    }
    if(!parts.includes(part)) return
    console.log('属于当前课程')
    if(chapter > 5){
        console.log('您需要提供VIP身份')
    }
}

4、减少作用域链查找层级

避免全局查找
全局查找相关

  • 目标变量不存在于当前作用内,通过作用域链向上查找
  • 减少全局查找降低实践消耗
  • 减少不必要的全局变量定义
  • 全局变量数据局部化
var name = 'zce';
function foo(){
    //name = 'zce666'; //这里的name 是属于全局的
    
    //优化
    var name = 'zce666';
    function baz(){
        var age = 18;
        console.log(age);
        console.log(name)
    }
    baz();
}
foo();
//快建立在内存空间消耗上

5、减少数据读取次数

//html


var oBox = document.getElementById('skip');
function hasEle(ele, cls){
    return ele.className == cls;
}
console.log(hasEle(oBox, 'skip'));

//优化
function hasEle(ele, cls){
    var className = ele.className 
    return className == cls;
}
//快建立在内存空间消耗上

6、字面量与构造式

用字面量比构造式执行效率高

var test = () => {
    let obj = new Object();
    obj.name = 'sz';
    obg.age = 18;
    return obj;
}
console.log(test());

//字面量
var test = () => {
    let obj = {
        name: 'sz',
        age: 18
    }
    return obj;
}
console.log(test());

//示例二
var str1 = '你好呀'; //字符串
var str2 = new String('你好呀'); //对象
console.log(str1);
console.log(str2);

7、减少循环体中活动

避免循环引用

  • 全局引用指多个对象间存在互相引用
  • 采用字面量替换New操作
  • setTimeout 替换 setInterval
  • 采用事件委托
  • 合并循环变量和条件
var test = () => {
  var i
  var arr = ['zce', 18, '你好呀'];
  for(i = 0; i < arr.length; i++){
    console.log(arr[i])
  }
}
test();

//优化后
var test = () => {
  var i
  var arr = ['zce', 18, '你好呀'];
  var len = arr.length;
  for(i = 0; i < len; i++){
    console.log(arr[i])
  }
}
//再优化
var test = () => {
  var arr = ['zce', 18, '你好呀'];
  var len = arr.length;
  while(len--){
    console.log(arr[len]);
  }
}

8、减少声明及语句数

//html
var oBox = document.getElementById('box'); var test = (ele) => { let w = ele.offsetWidth; let h = ele.offsetHeight return w * h; } //优化后 var test = (ele) => { return ele.offsetWidth * ele.offsetHeight; } console.log(test(oBox)); //示例2 var test = () => { var name = 'zc'; var age = 18; return name + age; } var test = () => { var name = 'sc', age = 18; return name + age; } console.log(test())

9、采用事件委托

子元素的事件 委托给 父元素来完成

//html
  • ZC
  • 18
var list = document.querySelectorAll('li'); function showTxt(ev){ console.log(ev.target.innerHTML); } for(let item of list){ item.onclick = showTxt; } //优化 var oUl = document.getElementById('ul'); oUl.addEventListener('click', showTxt, true); function showTxt(ev){ var obj = ev.target; if(obj.nodeName.toLowerCase() === 'li'){ console.log(obj.innerHTML); } }

你可能感兴趣的:(JavaScript 性能优化2 学习笔记)