最近在对一个项目进行优化,后端方面,因为程序主要逻辑已经定型,所以只能对目前的部分代码进行重构,不能进行大规模的重写。主要包括减少数据库的访问,使用memcached缓存ajax轮询请求数据;而也并不是每个页面或功能点都需要对数据进行memcached缓存的,根据用户访问量与产品业务逻辑的分析只需针对几个特定的页面,如专题页面,视频播放页面,直播视频简介页面。例如大规模的流量入口集中于专题页面,而该页面存在大量的数据库查询,很多操作都是通过ajax获取对应的视频信息,而这些信息在发布后一般是不会变动的,所以直接对视频数据缓存于memcached中。这样需要修改的代码较少且能很好的减轻数据库服务器的压力。不过这里主要谈下前端数据请求传递的优化。
前端方面优化的话则肯定要参考雅虎的yslow优化法则了。
在未优化前使用firefox的yslow附加组件给网站打分结果为“D” 或“C”,下面几项优化完成后,得分为“A”或“B”;可能普通用户在网速很好的时候体验上与之前没有什么不同,不过对于带宽有限的用户体验有了很大的改进。
Make fewer HTTP requests
This page has 8 external Javascript scripts. Try combining them into one.
This page has 3 external stylesheets. Try combining them into one.
This page has 21 external background images. Try combining them with CSS sprites.
1、js有公用的也有只有当前页面采用的,全部合并受困于cms独立的js文件,且自定义的js合并工作量大且需要再次调试完成,主要成员是当初这样制作时考虑的是对应页面加载对应javascript。其中有两个是网站分析相关的。
2、js文件工作量大且不利于调试,不过css就没有太多这方面的顾虑且便于修改调试。经过3天的努力把整站的34个css样式表全部合并为一个css文件了。还好当初做过css模块化重用的考虑,不过即使这样也还是删除了许多重复的代码。总大小160kb没要太大的变化,不过css样式表只有一个了。节约了很多连接请求啊。
3、这里当初构建前端页面的时候没有太考虑sprites,所以以至于有太多的琐碎css小图需要请求连接。只是现在css结构完全成形,修改起来会很麻烦,需要重新切图,修改css等等。这里暂时不做修改。
Grade F on Use a Content Delivery Network (CDN)
xxxx.net: 71 components, 5619.0K
s25.cnzz.com: 1 component, 6.6K
c.cnzz.com: 1 component, 0.5K
player.pplive.cn: 1 component, 276.5K
wwwimages.adobe.com: 1 component, 1.7K
icon.cnzz.com: 1 component, 0.4K
使用内容分发网络,不过对于非大型高并发的网站来说这点暂时还是能容忍的。
Grade F on Add Expires headers
对文件添加缓存过期时间,apache需要mod_expires.c模块的支持,对于网站上的静态内容可以设置为never expire,动态内容按图片/js/css的更新时间来设定缓存时间。用户第一次访问你的网站页面意味着需要很多次http请求,通过使用Expires文件头可以让内容具有缓存性。它避免接下来的页面访问中不必要的http请求,浏览器或代理使用缓存来减少http的请求次数与大小以加快页面的响应速度,而服务器在http响应中的Expires文件头信息则告诉客户端内容需要缓存多久。
ExpiresActive On
ExpiresDefault A600
ExpiresByType image/x-icon A2592000
ExpiresByType application/javascript A2592000
ExpiresByType text/css A604800
ExpiresByType image/gif A2592000
ExpiresByType image/png A2592000
ExpiresByType image/jpeg A2592000
ExpiresByType text/plain A86400
ExpiresByType application/x-shockwave-flash A2592000
ExpiresByType video/x-flv A2592000
ExpiresByType application/pdf A2592000
#ExpiresByType text/html A600
另外,当点击浏览器上的刷新,客户端发送的请求中均是max-age=0,表示validate操作,发送请求到服务器
要求检查cache,再更新cache,一般得到的是304 Not Modified,表示没变动。
Grade F on Compress components with gzip
gzip数据压缩传递,用户70%-80%的时间都是在等待数据从服务器上下载。gzip对数据的压缩率很高可以达到70%以上,可以很大程度的压缩数据,减少加载的时间。
且可传递的数据包括文档,css、js、图片、xml等数据都能通过gzip方式进行压缩传递。如上文的160kb的css文件通过apache deflate压缩传递回来只有32kb了。所以压缩数据进行传输对节省用户等待时间,提高用户的体验有很大的帮助。不过gzip需要浏览器与服务器同时支持,即服务器能够对数据进行压缩,浏览器能支持识别压缩的数据内容。好在现在主流的浏览器都是支持gzip与deflate压缩的,最常见的apache iis nginx等都是能够实现的。
Apache1.x 使用的是第三方的mod_gzip模块,Apache2.x则考虑到了传输数据压缩的问题,直接内置的mod_deflate模块,可以在httpd.conf中开启,重启服务器即可。
LoadModule deflate_module modules/mod_deflate.so
Nginx 开启Gzip
#nginx gzip
# ngx_http_gzip_module 模块支持
# output compression saves bandwidth
gzip on;
gzip_proxied any;
gzip_http_version 1.1;
gzip_min_length 1100;
gzip_comp_level 5;
gzip_buffers 8 16k;
gzip_types text/plain text/xml text/css application/x-javascript application/xml application/xml+rss text/javascript application/atom+xml;
gzip_vary on;
#gzip_disable "MSIE [1-6]\.";
Grade C on Put JavaScript at bottom
javascript主要是依赖cms原来的。所以对于这部分在页面构建是没有进行变动,不过现在javascript可以直接放到</body>上面了。
Grade E on Avoid CSS expressions
什么危害可以直接参考yahoo的解答
CSS表达式是一个强大的(危险)的方式动态设置CSS属性。他们支持在Internet Explorer版本5起,但与IE8开始被废弃。作为一个例子,可以设置的背景颜色交替每隔一小时,使用CSS表达式:
background-color: expression( (new Date()).getHours()%2 ? "#B8D4FF" : "#F08A00" );
在这里,表达方法接受一个JavaScript表达式。 CSS属性设置根据JavaScript表达式计算出来的结果。expression的表达方法在非ie浏览器没有效果,因此在跨浏览器设计中只针对Internet Explorer。
css表达式的问题是,他们比大多数人预期的更加频繁地计算。他们不仅在页面呈现和调整大小,滚动页面时,甚至当用户在页面上移动鼠标都会重新计算一次。给CSS表达式添加计数器能够跟踪表达式的计算频率。在页面上移动鼠标,可以很容易地产生超过10,000的计算量。
一个减少CSS表达式计算的方法之一是使用一次性的表达,他在第一个表达式求值时将结果赋值给指定的样式属性,用这个属性取代了CSS表达式。如果样式属性必须设置动态页面的整个生命周期,使用事件句柄来代替CSS表达式是一种方法。如果您必须使用CSS表达式,请记住,他们可能会评估了数千次,并可能会影响你的页面的性能。
Grade F on Configure entity tags (ETags)
配置ETags,简单点说ETags就是服务器与浏览器之间用于判断浏览器缓存与服务器端的数据是否匹配的机制。ETag实体是比last-modified-date更加灵活的机制。ETag是识别内容版本的唯一字符串,服务器通过还有ETag的响应头信息指定加载文件的ETag。
浏览器要验证一个文件,就用if-none-match文件头把ETag传回给服务器,如果ETag匹配,就会返回一个304状态码,这样就节省这个文件对应大小的字节数了。ETag格式限制就是字符串必须在双引号内,IIS的ETag格式是,Filetimestamp:ChangeNumber;Apache1.x和Apache2.x的ETag格式是Inode-size-timestamp。不过ETag存在的一个问题是,它是根据网站所在服务器的唯一属性来生成的,当浏览器请求的这文件即使目录,权限,大小,修改日期等一模一样但存在与另一台服务器上,ETag也不会匹配的。
如果你没有使用ETag验证,那么就去掉好了。而文件认证则是采用last-modified文件头了。Apache在.htaccess中加入 FileETag None 即可。有关IIS的ETag信息查看http://support.microsoft.com/?id=922733
此外还有
1、外域过多,dns查找时间过长。
页面中存在太多站外域名了,这样加大了dns查找的时间,其中完全可以规避掉的有adobe图片logo,另cnzz域名太多了,icon都独立为一个域名请求。可以考虑替换一个网站数据分析。google分析就很不错。
2、引用不存在的文件
如图片/css/js/ico等,特别是引用不存在的javascript文件,服务器会提示该文件不存在,而浏览器则还是会继续把它返回的数据当作javascript执行。加大浏览器的负担。
3、图片进行了缩放,如1000pxX500px的图片缩放为200pxX100px。img图片位显示的图片最好不要缩放。
4、html标签必须属性要添加上。如img的alt
5、还有如css/js 使用压缩工具进行文件压缩,推荐 yui compressor
上面的很多东西都是参考来自于yahoo 优化法则的,这里有份中文pdf,Yahoo-Web网站性能优化最佳实践。
****文档参考****
http://www.cnblogs.com/yuyii/archive/2008/10/16/1312238.html
http://kangzj.net/how-to-enable-gzip-for-ur-website/
http://developer.yahoo.com/performance/rules.html
http://httpd.apache.org/docs/2.2/mod/mod_expires.html
http://wiki.nginx.org/NginxChsHttpGzipModule