speeding up your web site 前端性能优化规则(一)
接上一篇:speeding up your web site 前端性能优化
---------------------------------------------------------------------------
启用浏览器缓存
请参考 http://www.cnblogs.com/forcertain/archive/2012/08/29/2662203.html
减少http请求
我们的页面除了本身的html结构之外,都会包含诸如图片、样式、脚本、flash等组件,这些对于我们来说都去向服务器发起请求,然后服务器响应,然后输出到客户端,由浏览器来呈现。如果能降低这些请求的数量,肯定会提高页面加载速度。减少请求数量最直接就是页面设计简单些,减少页面组件的数量,但是对于不同需求的页面总会可能包含很多的组件时,这时我们可以:合并js文件、合并css文件、合并背景图片等。这里特别提到的是js的合并,对于现代开发模块化、可复用、灵活的指导思想,我们可能会更倾向于开发多个功能性极强的js文件,仅在只需要使用的页面才引用特定的js,以减少不必要负担,而另一方面对于大部分网站所有js文件,除了引用的jquery构架外,压缩后也不过几十KB,分开加载损耗不大,而通常这些静态文件我们会设置一个较长时间浏览器缓存,这之后的加载区别不大,对于js的修改,分开可以只让浏览器重新加载修改过的js,而合并后任一修改就必须重新加载全部,另外合并特别压缩之后我们又加大了我们排查问题的难度,因此合并js要根据实际情况权衡后再做决定。
降低DNS查找次数
DNS查找,就是把域名解析成IP。很常见的情形,我们会把js、css、图片和动态程序分开到不同的服务器,还会提供不同的域名,除了服务器考虑外,浏览器对于不同的域名提高浏览器的并行下载(这其实我们下面会谈到的一个优化规则)。在加载页面时,浏览器遇到新域名,第一次会先发起一个DNS查找,一般情况下,这个时间会在几毫秒到几百毫秒,而在这段时间内所有这个域名的组件下载都会等解析完之后才依次开始,此后浏览器会缓存这个解析结果,缓存时长不同浏览器不同。不要小看这几十毫秒解析时间,可能这个时间里相同域名几十个小文件都可能下载完了。但也不是说所有组件都在一个域名下,根据yahoo的建议:至少两个最多4个的域名是比较合适的。
避免重写向
相当于找一个人但是被告知已搬家给了一个新地址,我们不得不再去新地址。除了性能之外,还会用户体验的考虑,我们应该尽量避免重写向:去掉一些不必要的转向,在服务端转向,用http头3XX和location而不是用refresh或js转向并且加客户端的缓存设置。
避免404
这可能比重定向更让人沮丧,你或许制作一个超炫的404页去提高用户体验,但是这浪费了服务器的性能,特别对于js文件,服务器在查找之后发现文件不存在,这段时间会阻断其它组件的并行下载,而很有可能一些组件的404会导致页面混乱或功能不可用,影响就极坏了。定期扫描页面,查找404及时处理。
缓存ajax结果
ajax的使用除了提高用户体验的考虑之外,它同时也节省服务器资源,但是控制不好的ajax反而会损耗性能,除了对ajax请求应用浏览器缓存、gzip压缩等优化之外,我们还应该有更多合理的控制。例如hover时发起的ajax,其实我们应该判断想要请求的内容是否已存在,存在时就直接显示,不再发起请求,而不应每次hover都发起请求。
推迟加载组件
审视下自己的页面,哪些是必须在最初必须加载的,有哪些是可以推迟加载的。其实大部份的js是可以推迟到onload事件之后加载的,例如你处理拖动或其它特效的js,在页面dom加载完成之前加载是没有任何意思的。另外在屏幕之下的图片甚至页面内容也都是可以在用户滚动时按需加载的。
推荐个google的推荐加载js的代码:
<script type="text/javascript"> // Add a script element as a child of the body function downloadJSAtOnload() { var element = document.createElement("script"); element.src = "deferredfunctions.js"; document.body.appendChild(element); } // Check for browser support of event handling capability if (window.addEventListener) window.addEventListener("load", downloadJSAtOnload, false); else if (window.attachEvent) window.attachEvent("onload", downloadJSAtOnload); else window.onload = downloadJSAtOnload; </script>
对于延迟加载图片或微博那种加载数据的网上插件不少,这里就不推荐了。
预加载组件
啊,没听错吧,上面刚说延迟加载,这里又让预加载,但是这不矛盾:延迟加载可以实现按需加载或推迟特殊效果的文件,而预加载是为了充分利用浏览器的空闲时间,提前加载以后操作可用的文件。有几种形式的预加载:无条件的预加载,在页面onload触发之后,立即去预加载;有条件的预加载,基于用户的操作提前加载可能用到的文件,如搜索当用户输入时,就可以去加载列表中可能用到的图片等文件;期望的预加载,例如你新开的频道或改版的网站,可能会出现加载慢,因为所有的文件都必须新加载而不从浏览器缓存中获取,这时你就可以把新频道或新版网站所到的文件在其它放到旧频道或旧版网站空闲的时候去下载,这样新的频道或网站可以浏览器缓存加载而不需要重新加载。
降低DOM元素的数量
一个复杂的页面不仅仅是要下载更多的内容,还会降低js DOM的操作速度,例如你对500和5000个元素遍历添加事件处理程序,将产生很大的差别。如果你的页面有很多标他签移除之后并不会影响页面的实际内容,那么你的页面就存在了多余的DOM元素。你是否只是为了布局应用了嵌套的表格?并不是为了显示有意义的内容而使用了div??其实这要求我们尽量使用标签表示实际内容,而不是为了样式布局。你可以用
document.getElementsByTagName('*').length
来查看页面有多少DOM元素。
分离组件到不同域名下
请参考 http://www.cnblogs.com/forcertain/archive/2012/09/03/2669034.html
但是要注意的,也就是上面降低DNS查找次数中提到的,这并不是越多越好,控制在2-4个就好。
尽量不使用iframe
iframe可以让我们在父页面里引用另一个页面,明白它的优劣可以让我们很好的利用它。
页面在引用第三方内容如广告会很有帮助,可以起到安全沙盒的作用,不会影响页面的布局,并且实现并行加载,但是它的代价也是很高的,它会影响到整个页面加载,也就是iframe页面加载完成,父页面才会触发onload,并且它是没有语义的,搜索引擎不友好。
----------------------------------------------------------------------------------------
接下来:speeding up your web site 前端性能优化规则(二)