构建高性能的网站课程组:小马玉伯小凡版本:第一版2010年Google的例子Google的例子Google的例子•预加载•用户行为分析迟钝的Web•Web已经成为我们的日常工具•好的用户体验(快稳准)•我不能容忍慢(因为我有其他的选择)•慢500ms=20%将放弃访问(Google)•慢100ms=1%将放弃交易(Amazon)后端=5%前端=95%就是这里,前端=88%前端性能的重要性80%-90%的优化空间集中在前端114条优化军规20条最佳实践2性能分析工具介绍3本次话题14条优化原则1.尽可能的减少HTTP请求数2.使用CDN3.添加Expires头(或者Cache-control)4.Gzip组件5.把CSS样式放在页面的上方。6.将脚本放在底部(包括内联的)7.避免在CSS中使用Expressions8.将javascript和css独立成外部文件9.减少DNS查询10.压缩JavaScript和CSS文件(包括内联的)11.避免跳转12.移除重复的脚本13.配置ETags14.缓存Ajax请求尽可能的减少HTTP请求数•组件越少=页面越快•减少HTTP请求开销•整合脚本,整合样式,整合图片为CSSSpritesCSSSpritesbackground-position:-0px-0px;background-position:-20px-0px;background-position:-40px-0px;background-position:-60px-0px;background-position:-80px-0px;background-position:-100px-0px;background-position:-120px-0px;background-position:-140px-0px;background-position:-160px-0px;background-position:-180px-0px;10个请求变为了一个使用CDN(ContentDeliveryNetwork)•静态的内容•让内容更靠近你的用户•Akamai,AmazonS3添加Expire头(或者Cache-control)•静态的内容–“Neverexpire”设置Expires头永不过期–一旦内容被缓存,浏览器就不会再发起请求–你需要更新内容时,重命名它–Apache例子:ExpiresActiveOnExpiresDefaultmodificationplus10years•动态的内容–使用Cache-control–使用If-Modified-Since启用Gzip压缩•发送前压缩内容,由浏览器解压•主流浏览器支持压缩的内容•搜索引擎蜘蛛也是如此•请求头信息Accept-Encoding:gzip,deflate•响应头信息Content-Encoding:gzip•所有的文本内容都应该被gzip压缩:html(php),js,css,xml,txt…把CSS样式放在页面的上方•Firefox和IE在CSS传输完成之前不会渲染任何东西。•此时有些CSS并不是必要的,例如@mediaprint•尽可能早的把样式放置到文档中headtitleMypage/titlelinkhref=“styles.css”…//headbody!--content--将脚本放在页面底部•Scripts阻塞下载•浏览器的逻辑:因为脚本可以在任何时间执行location.href或者document.write,何必下载可能没有用的内容呢?•将脚本放在底部可以缓解阻塞下载页面主体内容•内嵌脚本也该如此!--content--scriptsrc=“script.js”…//body/html避免在CSS中使用Expressions•CSSexpression:#content{position:absolute;left:expression(document.body.offsetWidth+‘px’);}•只有IE支持(IE8标准模式停止支持)•XSS注入攻击•它们的执行次数常常比你预期的要多•永远不要使用它将JavaScript和CSS独立成外部文件•有助于缓存,永不过期的策略•与其他页面共享•会增加2个或更多的HTTP请求•首页可以考虑直接写在页面内(内嵌)减少DNS查询•浏览器需要将域名映射到一个IP地址•DNS查询需要时间•每个页面2-4个域名压缩JavaScript和CSS文件•用gzip压缩,•使用脚本压缩工具(YUICompressor/GoogleClosureCompiler•内联样式和脚本也应该压缩淘宝首页的样式和脚本避免重定向•增加web请求•原因:重新启动一个请求避免重复的脚本引用•优雅(DRY)•IE可能会再次加载配置ETags•ETags是用来帮助缓存的•服务器A上的一个组件与服务器B上的相同组件拥有不同的ETag•配置ETags也会消耗服务器的资源•…或者索性移除它并贯彻“永不过期”策略缓存AJAX请求•通过XMLHttpRequest返回的内容和其他组件是相似的•同样应该压缩gzipped•用样应该缓存(具体情况具体分析,实时数据不该缓存)•Cache-control:max-age=?20条最佳实践1.尽早刷新缓冲区2.用GET方法发送Ajax请求3.组件延迟加载4.组件预加载5.减少DOM元素个数6.多域并行下载7.尽量少用iframes8.避免404错误9.减小cookie的大小10.对某些静态资源减少无谓的cookie传输11.减少访问DOM的次数12.编写聪明的事件处理器代码13.使用link而不是@import14.避免使用CSS滤镜15.优化图片16.优化CSSsprites17.不要在HTML中缩放图片18.减小favicon.ico的体积并缓存它19.保证组件不超过25k20.将组件拆包分到多个文档中contentjavascriptjavascriptcontentcontentcontentcontentserverservercsscssimagesimagesimagesimagesmobilemobilecookiecookiecontentforServer•尽早清除缓冲区–PHP:flush()–JSP:out.flush()•用GET方法发送Ajax请求–POST方法有两个过程(发送请求headers,发送请求数据)–GET请求在一个TCP数据包中(除非你有很多的cookies)forContent•组件延迟加载–不可见的组件:非当前的Tab,隐藏的图片–附加组件:动画,拖动–YUILoader•预加载组件–无条件的预加载(Google首页的例子)–有条件的预加载(淘宝搜索结果图片延迟加载)•减少DOM元素个数–元素越多,下载的数据越多,JS操作DOM速度越慢–document.getElementsByTagName('*').length•多域并行下载–towrequestsperdomain(IE8扩大到6)•尽量少使用iframe淘宝首页的例子forContent(2)•尽量少使用iframe–iframe的优点:•能帮助你延后加载第三方的内容。譬如标志和广告。•沙箱安全•可以平行的加载脚本–iframe的缺点:•公共文件的重复加载•浏览器的消耗•避免404错误–无意义的加载forCookie•减小cookie的大小•对某些静态资源减少无谓的cookie传输–img0x.taobaocdn.com–a.tbcdn.cnforJavaScript&CSS•减少访问DOM的次数–访问DOM很影响速度,尤其是复杂的DOM–不要滥用document.getElementById•编写聪明的事件处理程序–用YAHOO.util.Event.onDOMReady替代window.onload–格外小心鼠标事件的处理•使用link而不是@import–在IE里,@import相当于将link放在页面尾部•避免使用滤镜–只有IE支持–增加内存消耗forImage•优化图片–给PNG一个机会!–剥离JPEG文件中的注释•优化CSSsprites•不要在HTML中缩放图片–如果你需要imgwidth=100height=100src=“cat.jpg/那么就让cat.jpg100x100而不是500x500•减小favicon.ico的体积并缓存它–浏览器总是会请求它!–类似的文件有:crossdomain.xmlforMobile(iPhone)•保证组件不超过25k–iPhone不会Cache它们–25kb指的是未压缩前的大小•将组件拆包分到多个文档中iphonewebapp开发笔记——=node/1129网站性能测试工具SpeedTracer-GoogleMsfast-FacebookPagetest-AOLDynaTraceHttpWatchFiddler-MicrosoftySlow–YAHOO!工具•ySlow=8×{100-[4×(JS文件数-3)+4×(CSS文件数-2)+3×(CSS背景图连接数-6)]}+6×(100-10×未使用CDN的连接个数)+10×[100-11×(Expire时间小于172800秒的连接个数)]+8×[100-11×(文件大小大于500字节且未使用gzip的连接个数)]+4×[body中没有CSS连接?100∶(99-10×body中的CSS连接数)]+4×(100-5×head中的JavaScript连接数)+3×[不存在CSS表达式?100:(90-2×CSS表达式数目)]+3×[100-5×(域名数-4)]+4×(100-10×未精简的CSS与JS个数)+4×(100-10×Redirect个数)+4×[100-5×(重复的JavaScript个数+重复的CSS个数)]+2×(100-11×未使用Etag的连接个数)+4×(100-5×未缓存或者缓存时间不足3600秒的AJAX请求个数)+3×(100-5×请求方式不是GET的AJAX个数)+3×{DOM元素数量MaxDOM?100∶[99-10×⌈((DOM元素数量-900))/250⌉]}+4×(100-5×状态为404的连接个数)+3×[cookie大小不超过1000字节?100∶(99-10×⌊页面cookie的大小/1000⌋)]+3×(100-5×不满足cookiefree要求的链接个数)+4×[100-(2×使用hack的filter个数+5×未使用hack的filter个数)]+3×(100-5×在HTML代码中设定width和height的图片数)+2×[100-(favicon不可缓存或缓存时间小于3600秒?5∶0)-(favicon大小超过2000字节?5∶0)]Score=F/89感谢YAHOO!