• js本身的优化
    • 内存管理

      • 内存:由可读写单元组成,表示一片可操作空间
      • 管理:人为的去操作一片空间的申请,使用和释放
      • 内存管理:开发者主动申请,使用和释放空间
      • 管理流程:申请—使用—释放
        • 申请内存空间
        • 使用内存空间
        • 释放内存空间
          1. //申请
          2. //js没有申请的api,申明的时候自动申请
          3. let obj = {}
          4. //使用
          5. obj.name = ''
          6. //释放
          7. //没有释放的api,采用间接方式 设置为Null
          8. obj = null
    • 垃圾回收和常见GC算法

      • 垃圾回收
        • js中内存管理是自动的
        • 对象不再被引用时是垃圾
        • 对象不能从根上访问到时是垃圾
        • 将查找空间的路都破坏掉
      • 可达对象
        • 可以访问到的对象就是可达
          • 引用
          • 作用域链
        • 标准限值从根出发能够被找到
          • 根可以在js中理解为全局变量对象
      • 引用与可达
        • 引用
          • let obj = {name:’xm’} 小明对象空间被Obj引用。全局对象上可以被找到 可达
          • let ali = obj 小明对象空间又被引用了
      • GC算法
        • 垃圾回收机制
        • 可以找到内存中的垃圾,并释放和回收空间
          • 垃圾
            • 程序中不再需要使用的对象
            • 程序中不能再访问到的对象
        • 算法就是工作时查找和回收所遵循的规则
        • 常见的GC算法
          • 引用计数
            • 设置引用数,判断当前引用数是否为0
              • 引用数为0立即回收
              • 引用计数器
              • 引用关系改变时修改引用数字
            • 优点
              • 可以即时回收垃圾对象
              • 最大程度减少程序卡顿时间
            • 缺点
              • 无法回收循环引用的对象
              • 时间开销大,资源消耗较大
                • 时刻监控着当前对象的引用数值
          • 标记清除
            • 分标记和清除两个阶段
            • 遍历所有对象找到活动对象并标记 可达对象
            • 遍历所有对象清除没有标记对象 同时清除所有上次的标记
            • 回收相应空间
            • 优点
              • 解决对象循环引用的回收
            • 缺点
              • 地址不连续,造成空间碎片化
          • 标记整理
            • 标记清除的增强
              • 标记阶段一样
              • 清除阶段会先执行整理,移动对象位置,地址上产生连续
    • V8引擎的垃圾回收
      • V8是一款主流的JavaSctipt执行引擎
        • 速度快
        • 采用即时编译
        • V8内存设置上限 64位不超过1.5G 32位不超过800M
      • 垃圾回收策略
        • 采用分代回收思想
          • 内存分为新生代,老生带
          • 针对不同对象采用不同算法
        • 分代回收
          • 新生代存储区
            • 新生代指的是存活时间较短的对象 比如局部作用域
            • 小空间用于存储新生代对象(32M / 16M)
            • 采用 复制算法和标记整理
              • 新生代区也分为两个等大小空间
              • 使用空间为From 空闲空间为To
              • 活动对象存储于From
              • 标记整理后将活动对象拷贝至 To
                • 拷贝过程中可能出现晋升
                  • 晋升:将新生代对象移动至老生代
                  • 一轮GC还存活的新生代
                  • To空间的使用率超过25%
              • 然后将From和To交换空间完成释放
          • 老生代存储区
            • 老生代对象存储在右侧老生代区域,1.4G / 700M
            • 老生代对象存活时间较长的对象。比如全局对象 闭包
            • 采用 标记清除,标记整理,增量标记算法
              • 首先采用标记清除完成垃圾空间回收
              • 采用标记整理进行空间优化
                • 在新生代晋升的时候如果空间不足触发标记整理
              • 采用增量标记进行效率优化
                • 实现垃圾回收和程序执行交替运行
          • 对比
            • 使用空间换时间
            • 老生代不适合复制算法

        • 空间复制
        • 标记清除
        • 标记整理
        • 标记增量
    • Performance工具
      • GC目的实现内存空间的良性循环
      • 良性循环的基石是合理使用
      • 时刻关注才能确定是否合理
      • Performance提供多种监控方式
      • 使用步骤
        • 1.打开浏览器输入目标地址
        • 2.开发人员工具面板,选择性能
        • 开启录制功能,访问具体界面
        • 执行用户行为,一段时间后停止录制
        • 分析界面中记录的内存信息
    • 内存问题的外在表现
      • 页面出现延迟加载或经常性暂停
      • 页面持续性出现糟糕性能
      • 页面的性能随时间延长越来越差
    • 监控内存的几种方式
      • 内存泄漏:内存使用持续升高
      • 内存膨胀:在多数设备上都存在性能问题
      • 频繁的垃圾回收:通过内存变化图进行分析
      • 方式:
        • 浏览器任务管理器
          • 以数值的形式内存的变化
          • shift + esc调出
        • Timeline时序图记录
        • 堆快照查找分离DOM
          • Memory工具
          • 界面元素存活在dom树上
          • 垃圾对象时的DOM节点
          • 分离状态的DOM节点
            • 筛选deta
        • 判断是否存在频繁的垃圾回收
          • GC工作室应用程序世停止的
          • 频繁且过长的GC会导致应用假死
          • 用户使用卡顿
          • 方式
            • timeline中频繁的上升下降
            • 任务管理器中数据频繁的增加减小
    • 代码优化实例
      • 精准测试
        • 经过大量的执行样本进行数据统计和分析
        • 基于Benchmark.js jsperf 完成
    1. 慎用全局变量
      1. 全局变量定义在全局执行上下文 是所有作用域链的顶端
      2. 一直存在于上下文执行栈,知道程序退出
      3. 如果某个局部作用域出现了同名变量则会遮蔽或污染全局
    2. 缓存全局变量
      1. 将无法避免使用的全局变量缓存到局部
        1. let 去赋值
    3. 通过原型新增方法
      1. 在原型对象上新增实例对象需要的方法
    4. 避开闭包陷阱
      1. 闭包使用不当很容易内存泄漏
      2. 不要为了闭包而闭包
      3. 在闭包的时候将引用关系通过某种手段消除
    5. 避免属性访问方法使用
      1. js不需要属性的访问方法,所有属性都是外部可见的
      2. 使用属性访问方法只会增加一次重定义,没有访问控制力
    6. For循环优化
      1. 将length定义一下
    7. 采用最优的循环方式
      1. forEach>for > for in
    8. 文档碎片优化节点添加
      1. createDocumentFragment
      2. 节点添加必然会有回流和重绘
    9. 克隆节点优化操作
      1. 有相同的元素存在使用cloneNode 而不是新创建
    10. 直接量替换new Object
      1. 数组的话直接 =[1,2,3] 而不是new Array