美文网首页
JS高性能 from《高性能Javascript》

JS高性能 from《高性能Javascript》

作者: monvhh | 来源:发表于2018-10-29 20:52 被阅读0次

    总结此书中提到的,写代码需注意,或者可优化的点。
    可能不全面。欢迎讨论

    加载和执行

    Javascript下载和执行
    由于浏览器只有一个UI线程,Javascript执行会阻塞UI渲染

    1 script标签尽量放在body底部,以减少对整个页面下载的影响。
    2 合并多个Javascript文件,减少http请求
    3 无阻塞脚本:页面下载完成之后再下载Javascript文件

    • 延迟脚本: <script defer>,指明本元素所含的脚本不会修改DOM。在onload事件触发前执行

    部分浏览器不支持

    • 动态脚本元素:document.createElement("script"),然后appendTo head中

    加载顺序很重要

    • XMLHttpRequest脚本注入:通过xhr下载Javascript文件,然后appentTo body中
    • 研究webpack:压缩,懒加载,等等其他策略

    4 CDN

    数据存取

    数据的读取:字面量、本地变量、数组元素、对象成员
    1 尽量使用局部变量,如果引用了非局部变量,则在局部缓存该变量,比如var doc=document
    2 No eval、new Function这种动态作用域
    3 字面量/局部变量的存取速度 > 数组/对象成员的 存取速度
    4 嵌套成员 嵌套越深,耗时越多。location.hrefwindow.location.href性能更优

    DOM编程

    1 JS操作DOM,天生就慢,尽量避免
    2 innerHTML vs createElement:差不多,推荐innerHTML
    3 克隆DOM element.cloneNode() 略优于 document.createElement()
    4 遍历一个HTML collections 比遍历一个数组还要耗时。所以

    document.getElementsByName() 等等方式返回的dom节点的类数组对象

    • 可以先拷贝到数组中再遍历
    • 局部变量,先缓存

    5 元素节点: children 优于 childNodes,因为nodes包括注释、空格等等
    6 选择器:大量组合查询时,querySelectorAll优于getElementBy...
    7 最小化重绘和重排

    • 合并样式更新,比如利用添加移除class
    • 批量修改dom

    (1)元素脱离文档流: 隐藏/ 创建dom framgment/ clone
    (2) 应用元素改变
    (3)将改变后的元素带回文档中: 显示/ append/ innerHTML

    8 缓存布局信息,不要频繁获取元素高宽度等信息
    9 减少hover,耗费大量CPU计算
    10 事件委托:利用冒泡,因为

    事件绑定 占用处理时间
    浏览器跟踪每个事件处理器,占内存

    算法和流程控制

    循环

    1 No for-in
    2 减少查找次数:比如缓存length
    3 使用倒序,因为终止条件非0为真,而正序时<length,比较是两次,先判断大小,再判断真假。
    4 减少迭代次数:“Duff's Device’”

    while(i){
      process(items[i--]);
      process(items[i--]);
      process(items[i--]);
      process(items[i--]);
      ...
    }
    

    5 基于函数的迭代(eg.Array.forEach)不如loops(eg.for

    条件语句

    1 条件多时用switch(vs if-else
    2 最可能出现条件放在最前面
    3 使用嵌套if-else,而不是链式

    像二分法一样,逐步缩小范围
    4 大量离散值,使用查找表,即对象或数组,明确的对应关系
    连续分块的,可能3更合适

    递归

    1 堆栈溢出一般都是因为不正确的终止条件
    2 优化为尾递归,因为es6有尾递归优化
    3 递归 改为 迭代实现
    4 缓存遍历中的结果,避免重复遍历

    字符串和正则表达式

    字符串

    1 str = str + "one" + "two"优于str+="one";str+="two";优于str+="one"+"two"

    第一种最优的原因是浏览器内存分配的优化,不一定所有浏览器都适用
    部分浏览器可能会在编译期就对"one"+"two"进行合并了。

    2 数组项合并Array.join()耗时大于字符串拼接

    IE7反之

    3 string.concat+ +=耗时多

    正则表达式

    1 具体化,能多具体写多具体,减少匹配失败成本和回溯
    2 原子组,Javascript中可以用预查 (?=)
    3 尽量避免嵌套量词:减少回溯
    4 确保正则表达式的两个部分不能对字符串的相同部分进行匹配:减少回溯
    5 以简单、必须的字元开始
    6 字元互斥,同4
    7 减少分支数量,缩小分支范围:比如red|raw -> r(?:ed|aw)
    8 使用非捕获组:捕获组消耗时间和内存来记录反向引用,不需要反向引用的就可以避免
    9 补充8,只捕获感兴趣的文本以减少后处理
    10 暴露必须的字元,同1
    11 合适的量词,减少回溯
    12 将正则表达式赋值给变量并重用它们:主要是防止循环体重重复编译正则表达式
    13 拆分复杂正则表达式
    14 能简单通过字符串的方法实现就不要用正则
    15 去除首尾空白的例子,非常经典具体,最后混合使用字符串方法和正则达到性能最优

    快速响应用户界面

    解决脚本执行阻塞用户界面更新
    记录耗时,针对性的解决

    1 使用定时器让出时间片段:需要限制定时器数量,否则性能更差
    2 分割任务
    3 web worker

    Ajax

    1 利用Beacons,无需response。

    new image().src=url+'?'+params.join('&') ,google、百度 analysis好像都是这么做的

    2 缓存:客户端和服务端

    3 合并请求,减少请求数

    其他

    1 使用Object Array 直接量
    2 避免重复工作
    3 LazyLoading
    4 条件预加载,调用更快。与3正相反,适用不同的场景
    5 位操作性能更优,比如取模可以用位操作
    6 原生方法 性能更优

    相关文章

      网友评论

          本文标题:JS高性能 from《高性能Javascript》

          本文链接:https://www.haomeiwen.com/subject/bblitqtx.html