网站前端性能优化总结

fmms 10年前
     <p><strong> 一、服务器侧优化</strong></p>    <p><strong> 1</strong><strong>. </strong><strong>添加 </strong><strong>Expires </strong><strong>或 </strong><strong>Cache-Control </strong><strong>信息头</strong><strong> </strong></p>    <p> 某些经常使用到、并且不会经常做改动的图片(banner、logo等等)、静态文件(登录首页、说明文档等)可以设置较长的有效期(expiration date),这些HTTP头向客户端表明了文档的有效性和持久性。如果有缓存,文档就可以从缓存(除已经过期)而不是从服务器读取。接着,客户端考察缓存中的副本,看看是否过期或者失效,以决定是否必须从服务器获得更新。</p>    <p> 各个容器都有针对的方案,,以 Apache 为例:</p>    <div class="cnblogs_code">     <div>      <span style="color:#000000;">ExpiresActive On<br /> ExpiresByType image/gif </span>      <span style="color:#000000;">"</span>      <span style="color:#000000;">access plus 1 weeks</span>      <span style="color:#000000;">"</span>     </div>    </div>    <p> 表示gif文件缓存一周,配置可以根据具体的业务进行调整,具体配置可以参考:<a title="http://lamp.linux.gov.cn/Apache/ApacheMenu/mod/mod_expires.html" href="/misc/goto?guid=4958190670981079280" target="_blank">http://lamp.linux.gov.cn/Apache/ApacheMenu/mod/mod_expires.html</a></p>    <p><strong> 2</strong><strong>. </strong><strong>压缩内容</strong><strong> </strong></p>    <p> 对于绝大多数站点,这都是必要的一步,能有效减轻网络流量压力。</p>    <div class="cnblogs_code">     <div>      <span style="color:#000000;"><ifmodule mod_deflate.c><br /> DeflateCompressionLevel </span>      <span style="color:#000000;">9</span>      <span style="color:#000000;"><br /> AddOutputFilterByType DEFLATE text/html text/plain text/xml application/x-httpd-php<br /> AddOutputFilter DEFLATE html htm xml php css js<br /> </ifmodule></span>     </div>    </div>    <p> 表示zlib在压缩时可以最大程度的使用内存,压缩html、文本、xml和php这几种类型的文件,指定扩展名为html、htm、xml、php、css和js的文件启用压缩。</p>    <p> 具体配置可以参考:<a title="http://lamp.linux.gov.cn/Apache/ApacheMenu/mod/mod_deflate.html" href="/misc/goto?guid=4958190671744717600" target="_blank">http://lamp.linux.gov.cn/Apache/ApacheMenu/mod/mod_deflate.html</a></p>    <p><strong> 3. </strong><strong>设置</strong><strong> </strong><strong>Etags</strong><strong> </strong></p>    <p> 在使用etags之前,有必要复习一下 <a title="http://www.ietf.org/rfc/rfc2068.txt" href="/misc/goto?guid=4958190672485461443" target="_blank">RFC2068</a> 中规定的返回值 200 和 304 的含义:</p>    <div class="cnblogs_code">     <div>      <span style="color:#000000;">200</span>      <span style="color:#000000;">--OK<br /> </span>      <span style="color:#000000;">304</span>      <span style="color:#000000;">--Not Modified</span>     </div>    </div>    <p> 客户端在请求一份文件的时候,服务端会检查客户端是否存在该文件,<strong>如果客户端不存在该文件</strong>,则下载该文件并返回200;<strong>如果客户端存在该文件并且该文件在规定期限内没有被修改(</strong><strong>Inode</strong><strong>,</strong><strong>MTime</strong><strong>和</strong><strong>Size</strong><strong>)</strong>,则服务端只返回一个304,并不返回资源内容,客户端将会使用之前的缓存文件。而etags就是判断该文件是否被修改的记号,与服务器端的资源一一关联,所以etags对于CGI类型的页面缓存尤其有用。</p>    <p> 下图是优化前的首页:(注意,此时没有压缩首页图片,即使使用了缓存,仍需要5s左右的时间)</p>    <p><img style="display:block;margin-left:auto;margin-right:auto;" alt="" src="https://simg.open-open.com/show/b13165eeb91b8c2f8b54e6578e834f41.png" width="660" /></p>    <p style="text-align:center;">化前的某页面</p>    <p> 需要注意的是,使用etags会增加服务器端的负载,在实际应用中需要自行平衡。</p>    <p> <strong>二、Cookie优化</strong></p>    <p><strong> 1. </strong><strong>减小Cookie体积<br /> </strong> HTTP coockie可以用于权限验证和个性化身份等多种用途。coockie内的有关信息是通过HTTP文件头来在web服务器和浏览器之间进行交流的。因此保持coockie尽可能的小以减少用户的响应时间十分重要。</p>    <p> 使cookie体积尽量小;</p>    <p> 在合适的子域名上设置bookie,以免影响其他子域名下的响应;</p>    <p> 设置合理的过期时间,去掉不必要的cookie。</p>    <p> 下面对比一下各个网站的cookie:</p>    <p><img style="display:block;margin-left:auto;margin-right:auto;" alt="" src="https://simg.open-open.com/show/2f2ace3fc889b0147013168391ed1aa8.png" /></p>    <p style="text-align:center;">图中可以看出,6K的cookie显然是不必要的。</p>    <p><strong> 2. </strong><strong>对于页面内容使用无coockie域名</strong></p>    <p> 当浏览器在请求中同时请求一张静态的图片和发送coockie时,服务器对于这些coockie不会做任何地使用。因此它们只是因为某些负面因素而创建的网络传输。所以你应该确定对于静态内容的请求是无coockie的请求。创建一个子域名并用他来存放所有静态内容。</p>    <p> 例如,域名是www.example.org,则可以考虑可以在static.example.org上存在静态内容。但是,如果不是在www.example.org上而是在顶级域名example.org设置了coockie,那么所有对于static.example.org的请求都包含coockie。在这种情况下,可以考虑重新购买一个新的域名来存在静态内容,并且要保持这个域名是无coockie的。例如,t.qq.com使用的是qpic.cn,weibo.com使用的是sinaimg.cn,xiaonei.com使用的是hdn.xnimg.cn等等。</p>    <p> 性能方面的考虑还有使用带有www的子域名并且在它上面设置coockie,因为忽略www会把cookie设置到*.example.com上去,使cookie带有一些不必要的信息。</p>    <p> <strong>三、JAVA SCRIPT 和 CSS 优化</strong></p>    <p><strong> 1. </strong><strong>把 </strong><strong>CSS </strong><strong>放到代码页上端</strong><strong> </strong></p>    <p> 这么做可以避免浏览器在解释一次之后,使用css进行第二次解释,因为用户对css裸奔日效果根本就不感兴趣。</p>    <p><img style="display:block;margin-left:auto;margin-right:auto;" alt="" src="https://simg.open-open.com/show/3de16adf552052409701ff9a1b2ae937.jpg" width="660" /></p>    <p style="text-align:center;">css裸奔节效果图(来源:网络)<strong> <br /> </strong></p>    <p><strong> 2. </strong><strong>避免 </strong><strong>CSS </strong><strong>表达式</strong><strong> </strong></p>    <p> 凡是只有IE能用的东西,都不是好东西。</p>    <p><strong> 3. </strong><strong>从页面中剥离 </strong><strong>JavaScript </strong><strong>与 </strong><strong>CSS</strong></p>    <p> 剥离后,能够有针对性的对其进行单独的处理策略,比如压缩或者缓存策略。</p>    <p style="text-align:center;"><img style="display:block;margin-left:auto;margin-right:auto;" alt="" src="https://simg.open-open.com/show/49719e04dc26c5661779831fb0f755b2.png" width="660" />(css已经剥离,但js嵌入到html里面了,并且放在了html的上部,所以这货是正面+反面教材)</p>    <p><strong> 4. </strong><strong>精简 </strong><strong>JavaScript </strong><strong>与 </strong><strong>CSS</strong></p>    <p> 语法能简写话尽量简写。</p>    <p><img style="display:block;margin-left:auto;margin-right:auto;" alt="" src="https://simg.open-open.com/show/b42711744434b84621455e223ef04bd2.png" /></p>    <p style="text-align:center;">(相同表现的类合并)</p>    <p><strong> 5. </strong><strong>使用 </strong><strong><link> </strong><strong>而不是</strong><strong> @importChoose <link> over @import</strong></p>    <p> 在 IE 中 @import 指令等同于把 link 标记写在 HTML 的底部,这与第一条相违背。</p>    <p><strong> 6. </strong><strong>避免使用CSS </strong><strong>Filter</strong></p>    <p> 尽量使用png格式的图片来代替滤镜效果,因为开启滤镜会加大浏览器的开销。<strong>  <br /> </strong></p>    <p><strong> 7. JS</strong><strong>尽量放到页面最下端</strong></p>    <p> 当一个脚本在下载的时候,浏览器会卡住,无法响应其他请求。所以,可以将功能性的JS放到最后端去处理。</p>    <p><strong> 8</strong><strong>. </strong><strong>页面展现尽量交给</strong><strong>CSS</strong><strong>完成</strong></p>    <p> 曾经见过一个JS+CSS写出来的下拉框,如图:</p>    <p><img style="display:block;margin-left:auto;margin-right:auto;" alt="" src="https://simg.open-open.com/show/cea5feca3892364a6440ae06c6dd7176.png" /> 实现原理是JS获取页面的每一个select元素和其对应的属性,然后用js重新画出新的样式效果:</p>    <p><img style="display:block;margin-left:auto;margin-right:auto;" alt="" src="https://simg.open-open.com/show/e64fa6df0706e88a46f974ca5df599c6.png" width="660" /></p>    <p> 多出的这部分JS执行过程会降低客户端的性能,所以最终没有采用这个select样式。</p>    <p> <strong>四、图片优化</strong></p>    <p><strong> 1. </strong><strong>优化图片</strong><strong> </strong></p>    <p> 尽可能的使用 PNG 格式的图片,因为和GIF相比,PNG有更多的功能和更小的体积,而且未来PNG会加入动画效果:</p>    <p><img style="display:block;margin-left:auto;margin-right:auto;" alt="" src="https://simg.open-open.com/show/de9134fbd644e7c202155c9e10c20f2c.png" width="660" /></p>    <p><strong> 2. </strong><strong>使用 </strong><strong>CSS Sprites </strong><strong>对图片优化</strong><strong> </strong></p>    <p> 简单的说就是"利用 CSS background 相关元素进行背景图绝对定位",把多次HTTP 调用变为一次调用:</p>    <p><img style="display:block;margin-left:auto;margin-right:auto;" alt="" src="https://simg.open-open.com/show/449386a4c8e33590682922637aca45cf.png" /></p>    <p> 这些表情在鼠标没有经过的时候,都是从一张图片上绝对定位出来的,只有在鼠标放到某一张表情上时,才会从服务器上下载gif图片,这样可以减少(N-1)次HTTP请求。</p>    <p> 使用 CSS Sprites 的不足之处是客户端将消耗更多内存,因为CSS Sprites 会打开多个图片的副本,目前的解决办法是按照使用频率不同,合并成几个级别的图片,分批次下载并在客户端展示。</p>    <p><strong> 3. </strong><strong>不要在 </strong><strong>HTML </strong><strong>中缩放图片</strong><strong> </strong></p>    <p> 用 <a title="http://www.imagemagick.org/" href="/misc/goto?guid=4958190673229458741" target="_blank">ImageMagic</a> 命令(convert )就能将图片缩放成合适的尺寸,所以尽量不要交给浏览器去执行。</p>    <p><strong> 4. </strong><strong>用更小的并且可缓存的 </strong><strong>favicon.ico</strong></p>    <p> 原因是没有favicon.ico,服务器会返回一个404,与可以长时间缓存的文件相比,大量的404会增加服务器的响应数量。</p>    <p><img style="display:block;margin-left:auto;margin-right:auto;" alt="" src="https://simg.open-open.com/show/2ce6a0c70d59f1f72b8ffff300f362fb.png" width="660" /></p>    <p style="text-align:center;">(服务器上因为缺少favicon.ico而产生的404错误)</p>    <p><strong> 4. </strong><strong>压缩图片不一定是有损的</strong><strong> </strong></p>    <p> 对已有图片进行压缩并不对影响用户体验,主要基于以下两点:</p>    <p> 1. 用户未必会感觉到色彩的损失;</p>    <p> 2. 压缩不一定会损坏图片的质量。</p>    <p> 无损压缩图片的原理可以参考下面的链接,本文不再赘述:<a title="http://en.wikipedia.org/wiki/Image_compression" href="/misc/goto?guid=4958190673961619261" target="_blank">http://en.wikipedia.org/wiki/Image_compression</a></p>    <p> 最初测试平台首页使用的是未压缩过的图片,下载速度明显受拖延,有时会达到将近十秒钟左右的下载时间,在经过无损压缩首页图片之后,提升效果效果很明显,基本控制在了一秒钟之内:</p>    <p><img style="display:block;margin-left:auto;margin-right:auto;" alt="" src="https://simg.open-open.com/show/aa1ec9e2e2a5b6db1459d3dc5df90e8d.png" width="660" /> 下图是压缩前后的大小对比:</p>    <p><img style="display:block;margin-left:auto;margin-right:auto;" alt="" src="https://simg.open-open.com/show/bfc38f83f4df75758b8a24ba0df0f05c.png" /></p>    <p> 该工具地址为:<a title="http://www.smushit.com/" href="/misc/goto?guid=4958190674699519169" target="_blank">http://www.smushit.com/</a> ,强烈推荐使用。</p>    <p> <strong>五、内容优化</strong></p>    <p><strong> 1. </strong><strong>减少 </strong><strong>DNS</strong><strong> </strong><strong>查找</strong></p>    <p> DNS lookup 是很耗费时间的步骤,网站上如果过多的使用了站外的 Widget ,DNS 查找带来的问题是不容忽视的。</p>    <p><strong> 2. </strong><strong>尽量减少重定向</strong></p>    <p> 并且注意一些不必要的重定向,比如对 Web 站点子目录的后面添加个 "/" ,就能有效避免一次重定向。对于服务器来说,请求<a title="http://example.com/fml" href="/misc/goto?guid=4958190675446501738" target="_blank">http://example.com/fml</a> 与请求 <a title="http://example.com/fml/" href="/misc/goto?guid=4958190676184249463" target="_blank">http://example.com/fml/</a>  是有差异的。如果是 Apache 服务器,可以通过配置mod_rewrite解决这个问题。具体请参考:<a title="http://lamp.linux.gov.cn/Apache/ApacheMenu/mod/mod_rewrite.html" href="/misc/goto?guid=4958190676927570216" target="_blank">http://lamp.linux.gov.cn/Apache/ApacheMenu/mod/mod_rewrite.html</a><strong> <br /> </strong></p>    <p><strong> 3. </strong><strong>切分组件到多个域</strong></p>    <p> 主要的目的是提高页面组件<strong>并行下载能力</strong>,但注意,也不要同时使用过多的域名,否则就会出现第一条DNS lookup过多的问题,一般情况下两个域名就可以了。<strong> <br /> </strong></p>    <p><strong> 4. </strong><strong>杜绝 </strong><strong>http 404</strong><strong> </strong><strong>错误</strong></p>    <p> 对页面链接的充分测试加上对 Web 服务器 error 日志的不断跟踪可以有效减少 404 错误,并提升用户体验。</p>    <p> <strong>后记:</strong></p>    <p> 这次总结给我带来的启发并不在于提升系统性能性能本身,提升性能只是一个很表面上的东西,网上的方法有很多,测试的方法也有很多,照着都做一遍,性能确实会有所提升,但是这种知其然而不知其所以然的性能提升是没有意义的,这便是本文的目的所在。</p>    <p> 参考:</p>    <p> <a title="http://developer.yahoo.com/performance/" href="/misc/goto?guid=4958190677660001258" target="_blank">http://developer.yahoo.com/performance/</a></p>    <p> <a title="http://code.google.com/speed/page-speed/docs/rules_intro.html" href="/misc/goto?guid=4958190678398484344" target="_blank">http://code.google.com/speed/page-speed/docs/rules_intro.html</a></p>    <p> <a title="http://book.douban.com/subject/4719162/" href="/misc/goto?guid=4958190679142611944" target="_blank">http://book.douban.com/subject/4719162/</a></p>    <p> <a title="http://book.douban.com/subject/3132277/" href="/misc/goto?guid=4958190679895454730" target="_blank">http://book.douban.com/subject/3132277/</a><br /> <br />       转自:<a href="/misc/goto?guid=4958190680634526000">http://blog.csdn.net/wireless_tech/archive/2011/06/21/6558888.aspx</a><br /> </p>