前端优化的目的是什么 ?javascript
1. 从用户角度而言,优化可以让页面加载得更快、对用户的操做响应得更及时,可以给用户提供更为友好的体验。html
2. 从服务商角度而言,优化可以减小页面请求数、或者减少请求所占带宽,可以节省可观的资源。前端
1、页面级优化
1. 减小 HTTP请求数java
(1). 从设计实现层面简化页面正则表达式
1. Javascript
(1). DOM
DOM操做应该是脚本中最耗性能的一类操做,例如增长、修改、删除 DOM元素或者对 DOM集合进行操做。若是脚本中包含了大量的 DOM操做则须要注意如下几点:
a. HTML Collection(HTML收集器,返回的是一个数组内容信息)
在脚本中 document.images、document.forms 、getElementsByTagName()返回的都是 HTMLCollection类型的集合,在平时使用的时候大多将它做为数组来使用,由于它有 length属性,也可使用索引访问每个元素。不过在访问性能上则比数组要差不少,缘由是这个集合并非一个静态的结果,它表示的仅仅是一个特定的查询,每次访问该集合时都会从新执行这个查询从而更新查询结果。所谓的 “访问集合” 包括读取集合的 length属性、访问集合中的元素。
所以,当你须要遍历 HTML Collection的时候,尽可能将它转为数组后再访问,以提升性能。即便不转换为数组,也请尽量少的访问它,例如在遍历的时候能够将 length属性、成员保存到局部变量后再使用局部变量。
b. Reflow & Repaint
除了上面一点以外, DOM操做还须要考虑浏览器的 Reflow和Repaint ,由于这些都是须要消耗资源的,具体的能够参加如下文章:
如何减小浏览器的repaint和reflow?
Understanding Internet Explorer Rendering Behaviour
Notes on HTML Reflow数组
(2). 慎用 with
with(obj){ p = 1}; 代码块的行为其实是修改了代码块中的 执行环境 ,将obj放在了其做用域链的最前端,在 with代码块中访问非局部变量是都是先从 obj上开始查找,若是没有再依次按做用域链向上查找,所以使用 with至关于增长了做用域链长度。而每次查找做用域链都是要消耗时间的,过长的做用域链会致使查找性能降低。
所以,除非你能确定在 with代码中只访问 obj中的属性,不然慎用 with,替代的可使用局部变量缓存须要访问的属性。
(3). 避免使用 eval和 Function
每次 eval 或 Function 构造函数做用于字符串表示的源代码时,脚本引擎都须要将源代码转换成可执行代码。这是很消耗资源的操做 —— 一般比简单的函数调用慢 100倍以上。
eval 函数效率特别低,因为事先没法知晓传给 eval 的字符串中的内容,eval在其上下文中解释要处理的代码,也就是说编译器没法优化上下文,所以只能有浏览器在运行时解释代码。这对性能影响很大。
Function 构造函数比 eval略好,由于使用此代码不会影响周围代码 ;但其速度仍很慢。
此外,使用 eval和 Function也不利于Javascript 压缩工具执行压缩。
(4). 减小做用域链查找(这方面设计到一些内容的相关问题)
前文谈到了做用域链查找问题,这一点在循环中是尤为须要注意的问题。若是在循环中须要访问非本做用域下的变量时请在遍历以前用局部变量缓存该变量,并在遍历结束后再重写那个变量,这一点对全局变量尤为重要,由于全局变量处于做用域链的最顶端,访问时的查找次数是最多的。
低效率的写法:
// 全局变量
var globalVar = 1;
function myCallback(info){
for( var i = 100000; i--;){
//每次访问 globalVar 都须要查找到做用域链最顶端,本例中须要访问 100000 次
globalVar += i;
}
}
更高效的写法:
// 全局变量
var globalVar = 1;
function myCallback(info){
//局部变量缓存全局变量
var localVar = globalVar;
for( var i = 100000; i--;){
//访问局部变量是最快的
localVar += i;
}
//本例中只须要访问 2次全局变量
在函数中只须要将 globalVar中内容的值赋给localVar 中区
globalVar = localVar;
}
此外,要减小做用域链查找还应该减小闭包的使用。
(5). 数据访问
Javascript中的数据访问包括直接量 (字符串、正则表达式 )、变量、对象属性以及数组,其中对直接量和局部变量的访问是最快的,对对象属性以及数组的访问须要更大的开销。当出现如下状况时,建议将数据放入局部变量:
a. 对任何对象属性的访问超过 1次
b. 对任何数组成员的访问次数超过 1次
另外,还应当尽量的减小对对象以及数组深度查找。
(6). 字符串拼接
在 Javascript中使用"+" 号来拼接字符串效率是比较低的,由于每次运行都会开辟新的内存并生成新的字符串变量,而后将拼接结果赋值给新变量。与之相比更为高效的作法是使用数组的 join方法,即将须要拼接的字符串放在数组中最后调用其 join方法获得结果。不过因为使用数组也有必定的开销,所以当须要拼接的字符串较多的时候能够考虑用此方法。浏览器
关于 Javascript优化的更详细介绍请参考:
Write Efficient Javascript(PPT)
Efficient JavaScript
2. CSS选择符
在大多数人的观念中,都以为浏览器对 CSS选择符的解析式从左往右进行的,例如
#toc A { color: #444; }
这样一个选择符,若是是从右往左解析则效率会很高,由于第一个 ID选择基本上就把查找的范围限定了,但实际上浏览器对选择符的解析是从右往左进行的。如上面的选择符,浏览器必须遍历查找每个 A标签的祖先节点,效率并不像以前想象的那样高。根据浏览器的这一行为特色,在写选择符的时候须要注意不少事项,有人已经一一列举了, 详情参考此处。缓存
3. HTML
对 HTML自己的优化现现在也愈来愈多的受人关注了,详情能够参见这篇 总结性文章 。服务器