js 高性能

Tags
javascriptv8
Created
Dec 31, 2015 4:36 PM

https://romgrk.com/posts/optimizing-javascript

  • 比较数字
  • 使用相同形状
  • 数组方法会先复制,多次循环,不像 rust 会被优化
  • 间接访问
  • 避免缓存未命中
  • 避免大对象
  • 使用 eval 避免动态对象
  • 字符串 // 链接字符串使用指针
  • 使用专门的代码处理
  • 数据结构

https://github.com/thlorenz/v8-perf

https://github.com/vhf/v8-bailout-reasons

作用域也叫变量对象

使用位操作符提高性能,所以有些量为2,4,8,16这样的二进制111....

Object实例通常会共享隐类,因此当我们访问或者设置某个实例的未预定义变量值的时候会创建一个隐类。 // 最好在初始化的时候创建将要使用的属性 // V8 的实现

尽可能地多用Numbers与Booleans类型,因为他们与其他类似于字符串等原始类型相比性能表现更好。使用字符串类型可能会带来额外的垃圾回收消耗。

JIT 编译器能够找出你的代码中被执行次数最多的部分,将你的代码分割成多个小的代码块能够有助于编译器在编译时将这些代码块转化为内联格式然后增加执行速度。

对浏览器来说,一个标识符(变量)所在的位置越深,它的读写速度也就越慢(性能开销越大)

把如 window、document、undefined 等顶层作用域对象传入该密封的作用域中,可以让浏览器只检索当层作用域既能正确取得对应的顶层对象,减少了层层向上检索对象的性能花销

with改变this值,如果对象是动态的(如函数的参数),不方便阅读和排错。浏览器不能在JIT(即时编译)时优化。

try/catch /yield   不能被JIT 优化 // You could try { test() } catch

避免多次读取同一个对象属性,可以暂存到变量

JS引擎与DOM引擎是分开的,导致脚本对DOM树的访问很耗性能

滚动过程复用dom,避免节点过多和重排(translate做滚动动画///)。

document.querySelectorAll 的原生DOM方法来获取元素列表,仅返回一个 NodeList 而非实时集合,在遍历节点时可以比较放心地使用该方法。

Memoization 算法,实际上属于一种代理模式,把每次的计算缓存起来,下次则绕过计算直接到缓存中取

在每次调用字符串的属性方法时,后台总会在这之前默默地先做一件事——执行 s1=new String('some text')

常规我们应当尽可能减少正则的回溯(采用试错思想),从而提升匹配性能:

  • 尽量少用贪婪匹配
  • 尽量让匹配失败早点结束
  • 减少条件分支,具化两次
  • 捕获组会消耗时间和内存来记录反向引用
  • 只匹配感兴趣的内容避免后续处理
  • 复杂的搜索问题需要条件逻辑,拆分可能更高效

少操作arguments/rest对象,arguments的属性与参数绑定// function a (a) {console.log(arguments); arguments[0] = 1; console.log(a)}

在for in 中不要使用非局部变量。

不要写复杂属性的对象字面量,如: {__proto__: 3}; // __proto__ 的自有正常属性要使用计算属性定义

SuperMade with Super