高性能javascript笔记
最近在学习这本书,简单做下笔记。书中很多概念可以让人耳目一新,平常写代码也经常用到,只是没注意的亚子。
对于javascript性能优化个人总结
1,javascript文件引入时候需要注意了,尽量放在body标签后面
2,使用循环时候注意了,注意减少循环次数,和执行一次循环的耗时,从而降低整体代码的执行时间
3,操作原生DOM时候比较耗时间,尽量减少DOM的操作,使用querySelector,querySelectorAll查询节点
4,操作dom元素或添加css样式时候容易引起页面重排,注意避免重排
5,ajax请求都要使用异步请求的,避免javascript线程卡顿
6,减少javascript文件请求量,合并多个小javascript文件
7,部署时候压缩javascript文件,css文件,减少数据体积
8,采用缓存的形式,包括服务端设置缓存,或者浏览器端缓存
9,使用预加载,延迟加载,减少多余的执行
10,。。。。。
javascript代码优化
1,浏览器主线程遇到script标签时候,会优先执行javascript代码,页面的下载和渲染都会停下来等待脚本执行完成。
2,<script>标签里defer属性和ajax属性的区别,defer加载完js文件之后不会直接执行,ajax加载完js文件之后会自动执行。
3,javascript文件引入方式对于减少javascript对性能的影响
(1)将javascript标签放在body标签底部
(2)合并脚本,将多个小js文件合并成一个文件,加载会快一些。
(3)使用<script>标签的defer属性
(4)使用动态创建的<script>元素来下载执行javascript文件
(5)用于ajax取下载javascript文件
4,函数作用域链,在内部属性[[Scope]]里面查看,它决定了哪些数据能被函数访问,一般会有很多全局对象。
函数的[[Scope]]对象5,执行环境,执行函数时候会创建一个执行环境(execution context)的内部对象,函数每次执行时对应的执行环境都是独一无二的,多次调用构造函数会创建多个执行环境。函数执行完毕,执行环境就会被销毁。
6,闭包为什么会影响性能?
由于闭包的[[Scope]]属性包含了与执行环境作用域链相同的对象的引用,函数调用结束之后,引用仍存于闭包的[[Scope]]属性中,无法被回收(销毁)
bb闭包函数[[Scopes]]仍存有aa的对象t7,对象有两种成员类型
实例成员:直接存在于函数的对象之中,可用hasOwnProperty()方法进行检测
原型成员:从对象原型继承而来,可用in进行检测
8,js数据存取的优化
(1)访问字面量和局部变量的数据最快,访问数组和对象比较慢
(2)避免使用with语句,eval()方法,他们会改变执行环境作用域链,try catch语句也会改变执行环境作用域
(3)属性或方法在原型链位置越深,访问速度越慢。
(4)把常用的对象,数组保存到局部变量中,有助于减少访问的时间
javascript对DOM操作的优化
1,javascript引擎和DOM引擎是独立实现的,DOM的实现和javasrcipt无关,因此用javascript去操作DOM比较耗性能,访问DOM的次数越多,代码运行速度越慢。
2,innerHTML方法比document.createElement(),document.createTextNode()要快一些
3,element.cloneNode()比document.createElement()要快
4,querySelectorAll(),querySelector()要比document.getElement(),document.getElementByTagName()要快,因为querySelectorAll()不会返回HTML集合。
5,重排:浏览器重新计算元素的几何属性,重新构建渲染树。重绘:浏览器将重新绘制需要绘制的部分元素。重排比重绘耗时更长,更影响性能。
6,重排发生的情况
(1)删除或添加可见的DOM元素
(2)元素位置改变
(3)元素尺寸的改变(包括:外边距,内边距,边框厚度,宽度,高度等属性的改变)
(4)内容的改变,例如文本改变
(5)页面渲染初始化
(6)浏览器窗口尺寸的改变
7,会触发重排的属性
offsetTop,offsetLeft,offsetWidth,offsetHeight,scrollTop,scrollLeft,scrollWidth,scrollHeight,clientTop,clientLeft,clientWidth,clientHeight
读这些属性时候,浏览器会执行渲染队列,触发重排
8,减少重绘和重排的方法
(1)合并样式,用class改变样式
(2)批量修改DOM
使元素脱离文档流的三种方式
a.将元素设置display属性为none,然后在操作元素,操作完成之后再将display属性设置为block
b,创建一个文档片段,document.createDocumentFragment()然后再插进节点中
c,使用cloneNode()拷贝节点,然后对副本进行操作,操作完成之后将副本代替旧的节点。
(3)缓存布局信息,取出布局对象赋值给局部变量
(4)让元素脱离动画流
使用绝对定位页面上的动画元素,使其脱离文档
(5)使用事件委托,减少事件的绑定
算法和流程控制
1,减少循环耗时的两个重要思路:(1)减少每次迭代处理的事务(就是减少处理事务的耗时)。(2)减少迭代的次数
2,颠倒数组的顺序有助于提高循环性能
3,优化循环的方案总结
(1)for,while,和do-while循环性能相当,forEach,map循环要慢很多,尽量使用js原生的循环写法比如do-while,for等
(2)for-in循环比较慢,用于遍历对象的健
(3)改善循环性能的最佳方式是减少每次迭代的运算量和减少循环迭代次数
(4)通常来说switch比if-else要快,判断条件很多情况下尽量使用switch,判断情况少情况下使用“?:”三目运算,和if-else运算
(5)浏览器调用栈大小限制了递归算法的执行次数,执行次数超过浏览器栈上限会造成栈溢出从而导致浏览器崩溃。遇到栈溢出错误,可以改进为迭代方法
其它
1,构件快速响应的用户界面需要注意的几点
(1)任何Javascript任务都不应当执行超过100毫秒。过长的运行时间会导致UI更新出现延迟,从而对用户体验产生负面影响。
(2)JavaScript运行期间,浏览器响应应用用户交互的行为存在差异。无论如何,Javascript长时间运行将导致用户体验变得混乱和脱节。
(3)定时器可以用来延迟执行代码(建议少用,多用异步函数async,或者promise,或者回调)
(4)对于大量计算可以使用多线程写法,使用Web Workers是h5特性,它运行在UI线程外部执行Javascript代码,从而避免锁定UI。
2,使用高性能的AJAX
(1)作为数据格式,纯文本和HTML只适用于特定场合,但它们可以节省客户端的CPU周期。XML被广泛应用且支持良好,但解析比较麻烦。json是轻量级的解析速度快。字符分隔的自定义格式十分轻量,但需要服务端编写特定的构造程序,由客户端解析。
(2)减少请求数量,可通过合并Javascript,css,文件
(3)缩短页面加载时间。
3,编写高效的Javascript代码
(1)通过避免使用eval()和Function()构造器来避免双重求值带来的性能消耗,同样避免给setTimeout()和setInterval()传递字符串做参数。
(2)尽量使用直接量创建对象和数组,直接量的创建和初始化比非直接量形式要快。
(3)避免做重复工作。比如需要检测浏览器时,可以使用条件预加载或延迟加载。
(4)在进行数学计算时,考虑使用直接操作数字的二进制形式的位运算。
(5)Javascript的原生方法总比你写的任何代码都要快,尽量使用原生方法。
4,构件和部署时候的优化
(1)合并javascript文件减少请求数量。
(2)压缩javascript代码,可以压缩成gzip格式。
(3)在服务端压缩javascript文件。
(4)设置正确的HTTP响应头来缓存javascript文件。
(5)浏览器端也可以做缓存,比如使用indexedDB数据库,webWorks等。
(6)使用CDN提供Javascript文件。
以上内容引用至《高性能javascript》