高性能网站建设进阶指南(一)
WEB性能提升的14条规则:
1、尽量减少HTTP请求(使用css sprites);
2、使用CDN;
3、添加Expires头;
4、添加Gzip压缩组件;
5、将样式表放在顶部;
6、避免CSS表达式,使用外部的js和css,并精简JS,删除重复的脚本;
7、减少DNS查询;
8、避免重定向;
9、配置ETag;
10、使ajax可缓存;
第一章 理解ajax性能
1、权衡:但是在97%的情况下,过早优化是万恶之源,但我们不应该错过那关键的3%。现实情况的项目三角形(项目管理的三角形是时间、成本和范围):时间、质量、成本三选二,在生活和工作中权衡无处不在,选择算法要权衡运行时间和内存,会为抢占市场而牺牲代码质量。这些权衡对增量式开发(是一种任务高度和分阶段的策略,系统的各个部分以不同的时间和速度开发,完成之后进行整合。它并不强调是否采用迭代式开发和瀑布式开发这两种再加工策略。取代增量式开发的另一个选择是使用大爆炸集成方式来开发整个系统。)的效果很大。
2、优化的原则:优化对系统资源开销大的组件或模板,如优化循环,循环嵌套的越多,可优化的选择就越少
测试WEB应用时,应该尽可能的模拟用户的环境,使用低端机器和低速网络来测试,开发人员的配置都比较高,在开发环境下测试会掩盖性能问题。
3、页面之间的跳转(请求替换页面)会带来很大的开销,因此对于连续页面之间差别小的应用来说,使用ajax技术。
传统方式下用户操作的结果是请求替换页面,页ajax的实现方式是:发送数据包(数据包要尽可能的小)到服务器端(通常编码为json文本),然后服务器返回另一个数据包(也是json编码)来响应,最后js程序使用这些数据来更新浏览器的显示。这样做,数据的传输量、用户操作和可视化反馈的时间间隔都明显减少,服务器和浏览器需要做的工作量反而减少了,但是ajax程序员需要做的工作量很可能因此页增加,这也是需要权衡的因素之一。
ajax应用的常见错误是把所有应用数据都发送给浏览器,这会引入ajax本应该避免的延迟问题。
4、使用ajax库。运行程序最大的开销是DOM,并不是js,布局是(处理CSS)最大的开销。因此要理解DOM的奥秘并减少它的影响。
5、如果浏览器要展示一个非常大的数据集无需用滚动而要用分页。
7、只有评估,才能有把握对性能产生积极的影响。
第二章 创建快速响应的WEB应用
1、当用户和浏览器交互时,操作系统首先要判断是计算机中的哪个设备在输入,然后判断哪个应用应该接收这些输入之后,将它们打包为单独事件并放置到该应用的事件队列中。浏览器按照队列顺序完成其队列中单独事件的处理。它按先进先出的顺序把它们从队列中取出来,然后决定如何处理这个事件。通常,浏览器将基于这些事件做如下的操作:对事件本身做处理(例如:浏览网页、显示设定动画)或执行页面本身的JS。
如下图
浏览器使用单线程在队列中取出事件,然后对事件本身进行处理或执行JS,所以浏览器一次只能处理一个任务,并且任何一个任务都能阻止其它任务的执行。
2、怎样是够快?
页面响应超过0.2--0.1秒(页面不够快,不够平滑)时会被用户注意到。
超过1秒(给用户的感觉是慢)的延迟要提示用户计算机正在解决这个问题,如:改变光标的形状。
超过10秒(用户焦虑,感觉网站慢)的任何操作都需要一个百分比完成指示器以及一个方便用户中断操作且有清晰标识的方法。
3、测试性能的方法
手动代码检测(记录)和自动代码检测(性能分析)
手动代码检测:在函数中添加计时器,利用var sta=new Date().getMilliseconds();在很多浏览器中有console,可以用console.log()函数来代替alert(),如console.log("你好啊!");
自动代码检测工具是用来查找瓶颈或运行最慢的代码块。firebug有性能分析器。
4、性能优化:使用多线程把用户开销很大的代码从与用户交互的线程中剥离出来,但是JS不支持多线程,解决方法是web workers API,把开销很大的JS委托给workers。如果有浏览器不支持web worker API,则可以用Gears worker API插件。而且很多操作系统和浏览器都已经绑定sqlite(也可以用Navicat for SQLite、sqlitespy ),也可以使用JS的定时器控制代码的执行。
线程处理:XHR(xml HttpRequest)有两种的执行方式同步和异步。
5、快速响应的另一个关键方面是:内存管理,JS有GC机制,然而,自动内存管理是有开销的,当执行回收时,它们会冻结整个运行环境(包括正在调用的主浏览器JS线程),直到遍历完整个对象创建的“堆”,因为冻结运行环境的时间短而避开用户的注意,但是随着应用程序占用的内存的增加,要查找所有没有用到的对象所用的时间较长时就会被用户注意到。整个浏览器就有可能定期被冻结。
6、如果确定内存性能有影响:
使用delete关键字从内存中移除不再需要的JS对象;
从网页的DOM树上移除不再是必须的节点;
第三章 拆分初始化负载
DHTML(动态HTML),下载JS时有阻塞特性,但是下载CSS时没有
1、压缩JS,可以把JS分成两部分,一个用于页面初始化,另一个则可以延迟加载,可以缩短应用程序的加载时间。
Doloto是自动拆分JS的系统,把JS代码拆分成两部分,一部分用于页面初始化,另一部分再需要用到时再加载或者在初始化代码加载完成时再加载,但是平时还是需要开发者手动拆分JS代码。
Doloto安装时需要首先安装.NET Framework 3.5,Doloto下载地址:http://pan.baidu.com/s/1pJqO8mJ
更多Doloto的资源:http://research.microsoft.com/en-us/projects/doloto/
拆分代码的难点:
(1)避免出现未定义标识符错误,解决方法:提示正在加载中......,提醒用户该功能还没有加载完成。
(2)延迟加载的代码里绑定界面元素的事件处理程序。IE的通过attchEvent实现,其它浏览器采用addAttchListener
(3)使用桩函数:与原函数名相同,但函数体为空,或者是用临时代码代替原有内容的函数,需要加载时再用原函数代替桩函数。