高性能JavaScript笔记 javascript 文件加载速度 良好的编码习惯 使用高性能的变量或属性值读取方式 高效的DOM操作

  1. 延迟加载JavaScript文件,把script引用放在body底部,让页面其他元素先解析 - 放在head中文件夹在会阻塞页面元素渲染
  2. 使用成熟框架按需加载(异步)- headjs, requirejs, labjs

良好的编码习惯

  1. 缓存计算结果 - 如果计算耗时且计算结果不会改变
  2. 少用for-in循环(性能差) - 改用for循环
  3. 谨慎使用eval
  4. 数组应保存单一类型的数据
  5. 正确使用内存回收
    1. 不使用delete销毁- 影响浏览器引擎优化
    2. 遵从浏览器回收垃圾的原则编写对象
      • 尽量不使用全局变量 -全局变量再页面的整个生命周期不会被回收
      • 确保解除已经不需要的事件监听, 如那些要移出的dom对象上绑定的事件
      • 不要在闭包中返回外部不需要的对象

使用高性能的变量或属性值读取方式

tip

  • 作用域: 变量或函数的作用范围
  • JavaScript没有块级作用域(与c# java不同)- 大括号不会形成单独作用域
  • 最大作用域,全局作用域
  • 最小作用域是函数 - 函数内定义的变量,函数 只能在函数内部使用, 可以使用外部函数的变量或者函数
  • 因为函数嵌套定义,会形成作用域包含关系 - 作用域链。
    1. 函数被调用时,作用域链被出示化
    2. 使用变量时,会顺着作用域链从底向高层查找,知道找到变量的定义或者没找到,定义为undefined
    3. 如果频繁调用外层作用域的变量会影响性能- 如果函数内部多次调用外层作用域的变量,可以先把变量缓存起来。
  • 对象原型链上检索对象属性或方法会影响性能(与作用域类似)
    1. 把属性值缓存在局部变量中,提高读取对象的性能

高效的DOM操作

浏览器渲染的原理

1. 浏览器解析HTML文档构建DOM树
2. 浏览器解析CSS产生CSS规则树
3. JavaScript代码可能会修改生成的dom树和css规则树
4. 浏览器根据dom树和css规则树构建渲染树 
    - css根据选择器匹配html元素
    - 渲染树包括,元素的大小,边距,等样式。
    - 渲染树不包含隐藏元素以head等不可见元素
5. 浏览器根据元素的坐标和大小来计算每个元素的位置,绘制这些元素到页面上

dom操作性能损耗最大的两个因素

- 浏览器重绘(repaint): 页面某些部分重新绘制,颜色,背景色的修改 但元素位置和尺寸没有改变
- 重排(reflow):元素的位置或尺寸发生了改变,浏览器需要重新技术渲染树,会导致渲染树一部分或全部发生变化
- 重排的性能更低

导致重绘或重排的dom操作

- 增删改dom元素
- 页面初始化的渲染
- 移动dom元素
- 修改css,改变元素尺寸
- 元素内容改变,撑大尺寸
- 浏览器尺寸改变
- 浏览器窗口滚动

最佳实践

1. 合并多次的dom操作为单次dom操作
2. 把dom元素离线或隐藏后修改 - 对脱离了页面布局留的dom元素的操作不会导致性能问题
    1. 使用文档片段
var fragment = document.createDocumentFragment();
//大量基于fragment 的dom操作
document.getElementById('').appendChild(fragment);
    2. 通过设置dom元素的display样式为none来隐藏元素
var myElement = document.getElementById('');
myElement.style.display = 'none';
//基于myElement的dom操作
//...
myElement.style.display = 'block';
    3. 克隆DOM元素到内存中