乐趣区

关于javascript:JS性能优化2

从本文你将理解到

  • JSBench 的应用
  • 堆栈 JS 执行过程的介绍
  • 缩小层级判断
  • 缩小作用域链查找层级
  • 缩小数据读取次数(缓存)
  • 字面量与结构式
  • 缩小循环体中流动
  • 缩小申明及语句数(未频繁应用的能够不申明)
  • 采纳事件绑定(委托)

JSBench 应用

链接地址:https://jsbench.me/,ops 越大越好,每秒执行次数。因为浏览器多线程,尽可能一个标签页进行测试, 测试过程中不要切换线程,保持数据的准确性

图解堆栈中代码执行流程

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)

  1. 执行环境栈用于寄存咱们的执行上下文(ECStack 执行环境栈)
  2. 环境栈内的全局执行环境率先被压入栈(EC 全局 global 执行上下文)
  3. 代码执行时,EC 全局 VO 变量对象

    1. a=10 存在栈内存中
    2. foo= 函数, 因为是函数,会开拓一个指针为 AB1 的堆内存,并将指针 AB1 指向 foo(即 foo=AB1)
    3. 指针为 AB1 的堆中含有 function foo(b){...} name:foo length:1
  4. 继续执行,到 fn = foo(2) 时,会开拓一个函数 foo 的执行上下文 EC(foo)
  5. EC(foo) 初始化 this = window, 作用域链向外 <foo.AO,VO>,AO 变量对象

    1. arguments:{0:2}
    2. b = 2
    3. a = 2
    4. baz = 函数,因为是函数,会开拓一个指针为 AB2 的堆内存, 并将指针 AB2 指向 baz(即 baz=AB2)
    5. 指针为 AB2 的堆中含有 function baz(c){...} name:baz length:1
  6. 继续执行,到 fn(3) 时,会开拓一个函数 baz 的执行上下文 EC(baz)
  7. EC(baz) 初始化 this = window, 作用域链向外 <baz.AO,foo.AO,VO>,AO 变量对象,AO 变量对象

    1. arguments:{0:3}
    2. c = 3
    3. console.log(a+b+c)
  • 缩小判断层级

尽量减少 if..else.. 应用 return 代替

对于明确的条件分支倡议用 switch..case 代替 else if()..

else if 只适宜区间判断

function doSomething(part,chapter){const parts = ["ES2016","TOM","jack","React"]
  if(part){console.log("请确认模块信息")
    return;
  }

  if(!parts.includes(part)) return;
  
  console.log("属于以后课程")
  if(chapter <= 5) return;
  console.log("您须要提供 VIP 身份")
}
doSomething("ES2016",6)
  • 缩小作用域链查找层级

    var name = "zca"
    function foo(){
    name = "mcgee" // 这里的 name 在全局申明,这里只是赋值
    function baz(){
      var age = 38
      console.log(age)
      console.log(name)
    }
    baz()}
    foo()

    工夫更快的写法,(工夫换空间的形式)

外面又 var 了, 新申明会在内存开拓新空间,占内存。如果 name 数据量特地大,反而下面更好,(空间换工夫)

var name = "zca"
function foo(){
  var name = "mcgee"  // 这里的 name 属于 foo 内的
  function baz(){
    var age = 38
    console.log(age)
    console.log(name)
  }
  baz()}
foo()
  • 缩小数据读取次数

每次都会查找 ele 对象,将 ele 对象缓存

..html..
<div id="skip" class="skip"></div>

..js..

var oBox = document.getElementById("skip")

// function hasEle(ele,cls){
//   return ele.className == cls
// }

function hasEle(ele,cls){
  var clsname = ele.className
  return  clsname == cls
}
console.log(hasEle(oBox,'skip'))
  • 字面量与结构式

对于对象类型字面量模式略优于构造函数模式,对于根本类型字面量远优于构造函数式

通过函数式创建对象

let tests = ()=>{let objs = new Object()
  objs.name="mcgee"
  objs.age=18
  return objs
}

通过字面量创建对象

let tests = ()=>{
  let objs = {
    name:"mcgee",
    age:18
  }
  return objs
}

对于根本类型字面量远优于构造函数式

var str1 = "asdaasdsqwe"
var str2 = new String("asdaasdsqwe") // 相当于调用函数,多做一些事,扩容更好一些
  • 缩小循环体流动

循环体内代码越多,执行的越多,效率越慢

将循环体内固定值或者反复的提取进去,

循环形式的抉择 for while

var test = ()=>{var arr = ["mcgee",18,"我为前端而活"]
  var i
  for(i=0;i<arr.length;i++){console.log(arr[i])
  }
}
var test = ()=>{var arr = ["mcgee",18,"我为前端而活"]
  var i,len=arr.length // 固定值缓存
  for(i=0;i<len;i++){console.log(arr[i])
  }
}
var test = ()=>{var arr = ["mcgee",18,"我为前端而活"]
  var len=arr.length
  while(len--){ // 减到 0 就停掉了 更快
    console.log(arr[len])
  }
}

缩小申明及语句数

这与缓存仿佛并不违反,频繁调用的缓存进步运行效率,而非频繁调用或固定值尽量少用申明

<div id="box" style="width:100px;height:100px;"></div>

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))

又例如

var test = ()=>{
  var name="sd"
  var age = 18
  var str = "55asdada11111"
  return name+age+str
}

// 形式更快(词法剖析,语法分析,语法转换,代码生成)var test = ()=>{
  var name="sd",
      age = 18,
      str = "55asdada11111"
  return name+age+str
}

采纳事件委托

利用 js 元素冒泡的机制,把本来须要去绑定的响应事件的子元素去委托给父元素

<ul id="ul">
  <li>mcgee</li>
  <li>18</li>
  <li>"woaixx"</li>
</ul>

var list = document.querySelectorAll("li")

function showTxt(ev){
  var obj = ev.target
  if(obj.nodeName.toLowerCase() === 'li')
  {console.log(obj.innerHTML)
  }
}

// for(let item of list){
//   item.onclick = showTxt
// }

var oUl = document.getElementById("ul")
oUl.addEventListener("click",showTxt,true)
退出移动版