Skip to content

Latest commit

 

History

History
131 lines (96 loc) · 4.89 KB

File metadata and controls

131 lines (96 loc) · 4.89 KB
layout title
default
{"site.name"=>nil}

24最佳实践

可维护性

可理解性,直观性,可适应性,可扩展性

  • 做好注释
  • 变量初始化时给出他的类型。

松散耦合

代码要尽量做到解耦。

解耦的关键就是让他们尽量做好自己的事情。分工要明确。

  • js不要直接修改css的样式,用更改类名的形式可以降低耦合。
  • css里面也最好不要写expression那种东西
  • 应用逻辑与事件处理程序最好也能够解耦(比如将从事件中获取和应用逻辑拆分开)
  • 任何应用层面的程序都应该可以在不触发事件的情况下运行,这才是测试的可能性

编程实践

不负责创建或者维护某个对象,我们就不能对它们进行修改

  • 不要为实例或者原型添加属性和方法
  • 不要重新定义已经存在的方法
  • 避免全局变量

例如YUI就是单一的全局变量,是一个命名空间的概念

  • 避免与null进行比较
  • 将数据单独抽取出来作为常量,隔离逻辑与数据

性能

注意作用域

减少向上层作用域的查找过程,局部的函数或者变量肯定要比全局的开销要小一些。

避免使用with,因为with会建立自己的作用域链,延长了作用域链,肯定是会影响性能的。

选择正确的方法

时间复杂度上的优化

  • O(1):正常的常数和变量值,还有数组元素的访问也是O(1)
  • O(log n):二分查找
  • O(n):对象的属性获取(因为是个遍历的过程)
  • O(n2):每个值都得获取n次,插入排序

就是说尽量减少算法的复杂度,多使用局部变量来暂存住,然后如果能够使用数字化的数组位置来访问的话,就尽量用数字位置。

优化循环

  • 减值迭代:价值不大,感觉浏览器基本帮你做完了
  • 简化终止条件:每次循环都会操作,可以尽量减少O(n)的属性查找
  • 简化循环体:这也是废话了,执行最多的,所以要保证最大限度的优化
  • 使用后测试循环:一般的for和while都是前测试,而如果我们能够保证第一次的值肯定会有一个的话,可以改成后测试循环!!

展开循环

就是在循环次数确定时,消除掉循环换成多次调用函数往往更快。(原理是消除了建立循环和处理终止条件的额外开销)

//duff装置
function duff(array,callback){
  var iterations = Math.ceil(values.length/8);
  var left = values.length%8;
  var i = 0;
  if(left > 0){
    do{
      callback(array[left]);
    }while(--left>0)
    //--left的值就是操作结束的值
  }
  do{
    callback(i++);
    callback(i++);
    callback(i++);
    callback(i++);
    callback(i++);
    callback(i++);
    callback(i++);
    callback(i++);
  }while(--iterations>0)
}

这个已经是一个改良过的duff,最初版本的是通过switch写的,通过不写break来向下执行的。Duff的好处就是在大数据处理的时候减少了每次的判断的逻辑,还是很有意思的~

其实价值不是特别高

发现了个不错的网站,用来测试计算的性能:https://jsperf.com/

避免双重解释

比如下面的

eval('alert(3)');
var say = new Function('alert(4)');
setTimeout("alert(2)",1000)

这三种写法js都需要新建一个解释器来对字符串进行解析的,开销是很大的,尽量避免吧。

还有一些小的tip

  • 尽量用原生的方法,主要是Math的,因为这些事c/c++写的,速度更快
  • switch语句比一般的for的速度要快,而且case语句可以按照最可能到最不可能的顺序来写
  • 位运算符应该会更快一些

最小化语句数

  • 语句数其实也会影响执行的速度,我们在申明的时候可以将他们整合。
  • 迭代值可以使用++的形式来节省语句。
  • 使用数组和对象字面量的形式来书写是能够减少语句的

优化DOM操作

  • 最小化现场更新,就是createDocumentFragment来作为一个占位的,然后都append好了之后一次搞定就行。
  • 比这个更快地,使用innerHtml来改变,因为innerHtml是内部调用了内置的DOM调用,而不是基于JS的DOM调用。
  • 使用事件代理,这个比较常用,就是在祖先节点上绑定来节省绑定次数以及支持动态绑定
  • 合理使用HTMLCollection,因为文档上的查询开销很昂贵,合理使用

部署

我们的Js代码是没法直接放到线上的,因为注释,长变量名和空白其实都是没有价值的。

一般会进行一次js的验证,比如JSLint。

所以一般会进行压缩,比如YUICompressor,删除空白,注释,缩短变量名。

然后还会有HTTP的压缩,比如GZIP压缩。

Gzip其实是浏览器与http提供的,浏览器在发送request的时候会发一个Accept-Encoding:gzip,deflate之类,然后服务器就会返回按照它支持的压缩过的文本