浏览器请求处理流程以下图:javascript
一、减小http请求,合理设置 HTTP缓存前端
http协议是无状态的应用层协议,意味着每次http请求都须要创建通讯链路、进行数据传输,而在服务器端,每一个http都须要启动独立的线程去处理。这些通讯和服务的开销都很昂贵,减小http请求的数目可有效提升访问性能。java
减小http的主要手段是合并CSS、合并javascript、合并图片。将浏览器一次访问须要的javascript和CSS合并成一个文件,这样浏览器就只须要一次请求。图片也能够合并,多张图片合并成一张,若是每张图片都有不一样的超连接,可经过CSS偏移响应鼠标点击操做,构造不一样的URL。
缓存的力量是强大的,恰当的缓存设置能够大大的减小 HTTP请求。假设某网站首页,当浏览器没有缓存的时候访问一共会发出 78个请求,共 600多 K数据,而当第二次访问即浏览器已缓存以后访问则仅有 10个请求,共 20多 K数据。 (这里须要说明的是,若是直接 F5刷新页面的话效果是不同的,这种状况下请求数仍是同样,不过被缓存资源的请求服务器是 304响应,只有 Header没有Body,能够节省带宽 )数组
怎样才算合理设置 ?原则很简单,能缓存越多越好,能缓存越久越好。例如,不多变化的图片资源能够直接经过 HTTP Header中的Expires设置一个很长的过时头 ;变化不频繁而又可能会变的资源可使用 Last-Modifed来作请求验证。尽量的让资源可以在缓存中待得更久。关于 HTTP缓存的具体设置和原理此处就再也不详述了。浏览器
二、使用浏览器缓存缓存
对一个网站而言,CSS、javascript、logo、图标这些静态资源文件更新的频率都比较低,而这些文件又几乎是每次http请求都须要的,若是将这些文件缓存在浏览器中,能够极好的改善性能。经过设置http头中的cache-control和expires的属性,可设定浏览器缓存,缓存时间能够是数天,甚至是几个月。服务器
在某些时候,静态资源文件变化须要及时应用到客户端浏览器,这种状况,可经过改变文件名实现,即更新javascript文件并非更新javascript文件内容,而是生成一个新的JS文件并更新HTML文件中的引用。
使用浏览器缓存策略的网站在更新静态资源时,应采用逐量更新的方法,好比须要更新10个图标文件,不宜把10个文件一次所有更新,而是应该一个文件一个文件逐步更新,并有必定的间隔时间,以避免用户浏览器突然大量缓存失效,集中更新缓存,形成服务器负载骤增、网络堵塞的状况。cookie
三、启用压缩网络
在服务器端对文件进行压缩,在浏览器端对文件解压缩,可有效减小通讯传输的数据量。若是能够的话,尽量的将外部的脚本、样式进行合并,多个合为一个。文本文件的压缩效率可达到80%以上,所以HTML、CSS、javascript文件启用GZip压缩可达到较好的效果。可是压缩对服务器和浏览器产生必定的压力,在通讯带宽良好,而服务器资源不足的状况下要权衡考虑。框架
四、CSS Sprites
合并 CSS图片,减小请求数的又一个好办法。
五、LazyLoad Images
这条策略实际上并不必定能减小 HTTP请求数,可是却能在某些条件下或者页面刚加载时减小 HTTP请求数。对于图片而言,在页面刚加载的时候能够只加载第一屏,当用户继续日后滚屏的时候才加载后续的图片。这样一来,假如用户只对第一屏的内容感兴趣时,那剩余的图片请求就都节省了。
六、CSS放在页面最上部,javascript放在页面最下面
浏览器会在下载完成所有CSS以后才对整个页面进行渲染,所以最好的作法是将CSS放在页面最上面,让浏览器尽快下载CSS。若是将 CSS放在其余地方好比 BODY中,则浏览器有可能还未下载和解析到 CSS就已经开始渲染页面了,这就致使页面由无 CSS状态跳转到 CSS状态,用户体验比较糟糕,因此能够考虑将CSS放在HEAD中。
Javascript则相反,浏览器在加载javascript后当即执行,有可能会阻塞整个页面,形成页面显示缓慢,所以javascript最好放在页面最下面。但若是页面解析时就须要用到javascript,这时放到底部就不合适了。
Lazy Load Javascript(只有在须要加载的时候加载,在通常状况下并不加载信息内容。)随着 Javascript框架的流行,愈来愈多的站点也使用起了框架。不过,一个框架每每包括了不少的功能实现,这些功能并非每个页面都须要的,若是下载了不须要的脚本则算得上是一种资源浪费 -既浪费了带宽又浪费了执行花费的时间。目前的作法大概有两种,一种是为那些流量特别大的页面专门定制一个专用的 mini版框架,另外一种则是 Lazy Load。
七、异步请求Callback(就是将一些行为样式提取出来,慢慢的加载信息的内容)
在某些页面中可能存在这样一种需求,须要使用 script标签来异步的请求数据。相似:
像以上这种方式直接在页面上写 <script>
对页面的性能也是有影响的,即增长了页面首次加载的负担,推迟了 DOMLoaded和window.onload 事件的触发时机。若是时效性容许的话,能够考虑在 DOMLoaded事件触发的时候加载,或者使用 setTimeout方式来灵活的控制加载的时机。
八、减小cookie传输
一方面,cookie包含在每次请求和响应中,太大的cookie会严重影响数据传输,所以哪些数据须要写入cookie须要慎重考虑,尽可能减小cookie中传输的数据量。另外一方面,对于某些静态资源的访问,如CSS、script等,发送cookie没有意义,能够考虑静态资源使用独立域名访问,避免请求静态资源时发送cookie,减小cookie传输次数。
九、Javascript代码优化
(1). DOM
a.HTML Collection(HTML收集器,返回的是一个数组内容信息)
在脚本中 document.images、document.forms、getElementsByTagName()返回的都是HTMLCollection类型的集合,在平时使用的时候大多将它做为数组来使用,由于它有 length属性,也可使用索引访问每个元素。不过在访问性能上则比数组要差不少,缘由是这个集合并非一个静态的结果,它表示的仅仅是一个特定的查询,每次访问该集合时都会从新执行这个查询从而更新查询结果。所谓的“访问集合” 包括读取集合的 length属性、访问集合中的元素。
所以,当你须要遍历 HTML Collection的时候,尽可能将它转为数组后再访问,以提升性能。即便不转换为数组,也请尽量少的访问它,例如在遍历的时候能够将 length属性、成员保存到局部变量后再使用局部变量。
b. Reflow & Repaint
除了上面一点以外, DOM操做还须要考虑浏览器的Reflow和Repaint ,由于这些都是须要消耗资源的。
(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). 减小做用域链查找
前文谈到了做用域链查找问题,这一点在循环中是尤为须要注意的问题。若是在循环中须要访问非本做用域下的变量时请在遍历以前用局部变量缓存该变量,并在遍历结束后再重写那个变量,这一点对全局变量尤为重要,由于全局变量处于做用域链的最顶端,访问时的查找次数是最多的。