JS性能优化2

404NotFound
• 阅读 895

从本文你将了解到

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

JS性能优化2

  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)
点赞
收藏
评论区
推荐文章
Dax Dax
4年前
前端性能优化
前端性能优化1、减少资源的请求次数和大小压缩合并js和css文件,减少http请求次数和请求资源的大小;在项目中使用webpackglup等打包编译工具2、尽量使用字体图标或者svg图标代替传统的png(jpg)图渲染更快,减少代码体积,且放大不会出现变形等3、使用图片懒加载目的是减少页面第一次加载的http请求次数,实现思路:
徐小夕 徐小夕
4年前
如何用不到200行代码写一款属于自己的js类库
前言JavaScript的核心是支持面向对象的,同时它也提供了强大灵活的OOP语言能力。本文将使用面向对象的方式,来教大家用原生js写出一个类似jQuery这样的类库。我们将会学到如下知识点:闭包:减少变量污染,缩短变量查找范围自执行函数在对象中的运用extend的实现原理如何实现跨浏览器的事件监听原型链与继承接下来我会对类库
LinMeng LinMeng
2年前
Vue3学习笔记---Vue3带来了什么
1.性能的提升打包大小减少了41%初次渲染快55%,更新渲染快133%内存减少54%...2.源码的升级使用Proxy代替defineProperty实现响应式重写虚拟DOM的实现和TreeShaking(是一个通常用于描述移除JavaScript上下文中的未引用代码(deadcode)行为的术语,它依赖于ES2015中的import和ex
如果一个Activity启动比较慢,需要优化,你觉得可以从哪些方面入手?
打开一个app的时候速度比较慢,等一会才能看到UI,有很多种原因,下面是我根据这些个情况做出的多种优化,记录一下。1、采用动态布局:先是优化了布局,减少层级嵌套,使用merge优化等等。但发现加载xml布局还是慢了点,于是改为动态布局,布局的时间减少了好几倍。2、利用MessageQueue.IdleHandler()回调按照activity的生命周期
Souleigh ✨ Souleigh ✨
4年前
前端性能优化 - 雅虎军规
无论是在工作中,还是在面试中,web前端性能的优化都是很重要的,那么我们进行优化需要从哪些方面入手呢?可以遵循雅虎的前端优化35条军规,这样对于优化有一个比较清晰的方向.35条军规1.尽量减少HTTP请求个数——须权衡2.使用CDN(内容分发网络)3.为文件头指定Expires或CacheControl,使内容具有缓存性。4.避免空的
Stella981 Stella981
3年前
React 入门及学习笔记
React构建用户界面的JavaScript库,主要用于构建UI界面。Instagram,2013年开源。特点:1.声明式的设计2.高效,采用虚拟DOM来实现DOM的渲染,最大限度的减少DOM的操作。3.灵活,跟其他库灵活搭配使用。4.JSX,俗称JS里面写HTML,JavaScript语法的扩展。5.组件化,模
Stella981 Stella981
3年前
Creator优化心得:减少脚本文件的大小
星期2是公众号更新的一个时间点,Shawn这几天情事太多,眼看就快要过12点了,公众号教程看来今天黄呀!但是不发晚上睡不着呀,看来我是中了得到罗胖的毒“死磕自己”,一定要把公众号给发了。还好之前留着大神Colin的一些文章,还没在公众号上推送过,我立马读了一下,任然有不少收获,现将这篇文章分享给大家,在此感谢Colin!!(https://o
Wesley13 Wesley13
3年前
MySQL大数据高并发处理之
接上一章的内容,我们来谈一下MySQL中的查询优化技术。保证在实现功能的基础上,尽量减少对数据库的访问次数(可以用缓存保存查询结果,减少查询次数);通过搜索参数,尽量减少对表的访问行数,最小化结果集,从而减轻网络负担;能够分开的操作尽量分开处理,提高每次的响应速度;在数据窗口使用SQL时,尽量把使用的索引放在选择的首列;算法的结构尽量简单;在查询时,不要过多
Wesley13 Wesley13
3年前
MongoDB学习笔记_5_索引
索引概念建立指定键值及所在文档中的存储位置对照关系清单。使用索引可以方便我们快速查找,减少遍历次数,提高效率。操作创建索引db.collection_name.ensureIndex()功能:创建索引参数:提供索引的类别选项
融云IM即时通讯 融云IM即时通讯
8个月前
融云IM干货丨uni-app 在性能上如何优化?
uniapp性能优化可以从以下几个方面进行:使用生产环境构建:确保在部署到生产环境之前,使用Uniapp的生产构建版本,它会进行代码压缩和性能优化。避免不必要的数据绑定:减少使用不必要的双向绑定和计算属性,尽量直接使用props传递数据。虚拟列表渲染:对于
融云IM即时通讯 融云IM即时通讯
8个月前
融云IM干货丨如何优化插件以减少内存占用?
为了优化插件以减少内存占用,以下是一些具体的策略和方法:1.代码瓶颈优化:重写热点函数,采用更高效的算法和数据结构,减少不必要的计算和内存分配。2.资源瓶颈处理:实现分批处理和惰性加载机制,减少对内存和CPU的即时需求。3.插件加载优化:重构插件架构,使用