求知 文章 文库 Lib 视频 iPerson 课程 认证 咨询 工具 讲座 Modeler   Code  
会员   
 
  
 
 
     
   
分享到
一、高性能WEB开发基础
 
火龙果软件    发布于 2014-04-22
 

一、高性能WEB开发之HTTP服务器

新产品为了效果,做的比较炫,用了很多的图片和JavaScript,所以前端的性能是很大的问题,分篇记录前端性能优化的一些小经验。

第一篇:HTTP服务器

因tomcat处理静态资源的速度比较慢,所以首先想到的就是把所有静态资源(JS,CSS,image,swf)

提到单独的服务器,用更加快速的HTTP服务器,这里选择了nginx了,nginx相比apache,更加轻量级,

配置更加简单,而且nginx不仅仅是高性能的HTTP服务器,还是高性能的反向代理服务器。

目前很多大型网站都使用了nginx,新浪、网易、QQ等都使用了nginx,说明nginx的稳定性和性能还是非常不错的。

1. nginx 安装(linux)

http://nginx.org/en/download.html 下载最新稳定版本

根据自己需要的功能先下载对应模板,这里下载了下面几个模块:

openssl-0.9.8l,zlib-1.2.3,pcre-8.00

编译安装nginx:

./configure   
--without-http_rewrite_module
--with-http_ssl_module
--with-openssl=../../lib/openssl-0.9.8l
--with-zlib=../../lib/zlib-1.2.3
--with-pcre=../../lib/pcre-8.00
--prefix=/usr/local/nginx

make

make install

2、nginx处理静态资源的配置

#启动GZIP压缩CSS和JS  
gzip on;
# 压缩级别 1-9,默认是1,级别越高压缩率越大,当然压缩时间也就越长
gzip_comp_level 4;
# 压缩类型
gzip_types text/css application/x-javascript;

# 定义静态资源访问的服务,对应的域名:res.abc.com
server {
listen 80;
server_name res.abc.com;

# 开启服务器读取文件的缓存,
open_file_cache max=200 inactive=2h;
open_file_cache_valid 3h;
open_file_cache_errors off;

charset utf-8;

# 判断如果是图片或swf,客户端缓存5天
location ~* ^.+.(ico|gif|bmp|jpg|jpeg|png|swf)$ {
root /usr/local/resource/;
access_log off;
index index.html index.htm;
expires 5d;
}

# 因JS,CSS改动比较频繁,客户端缓存8小时
location ~* ^.+.(js|css)$ {
root /usr/local/resource/;
access_log off;
index index.html index.htm;
expires 8h;
}

# 其他静态资源
location / {
root /usr/local/resource;
access_log off;
expires 8h;
}
}

3、nginx 反向代理设置

# 反向代理服务,绑定域名www.abc.com  
server {
listen 80;
server_name www.abc.com;

charset utf-8;

# BBS使用Discuz!
# 因反向代理为了提高性能,一部分http头部信息不会转发给后台的服务器,
# 使用proxy_pass_header 和 proxy_set_header 把有需要的http头部信息转发给后台服务器
location ^~ /bbs/ {
root html;
access_log off;
index index.php;
# 转发host的信息,如果不设置host,在后台使用request.getServerName()取到的域名不是www.abc.com,而是127.0.0.1
proxy_set_header Host $host;
# 因Discuz! 为了安全,需要获取客户端User-Agent来判断每次POST数据是否跟第一次请求来自同1个浏览器,
# 如果不转发User-Agent,Discuz! 提交数据就会报"您的请求来路不正确,无法提交"的错误
proxy_pass_header User-Agent;
proxy_pass http://127.0.0.1:8081;
}

# 其他请求转发给tomcat
location / {
root html;
access_log off;
index index.jsp;
proxy_pass http://127.0.0.1:8080;
}

error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}

nginx详细配置参考:http://wiki.nginx.org/

PS:如果安装提示GCC not found,运行下面命令安装就可以(apt-get install build-essential),仅限debian

二、高性能WEB开发之Web性能测试工具推荐

WEB性能测试工具主要分为三种,一种是测试页面资源加载速度的,一种是测试页面加载完毕后页面呈现、JS操作速度的,还有一种是总体上对页面进行评价分析,下面分别对这些工具进行介绍,如果谁有更好的工具也请一起分享下。

Firebug:

Firebug 是firefox中最为经典的开发工具,可以监控请求头,响应头,显示资源加载瀑布图:

HttpWatch :

httpwatch 功能类似firebug,可以监控请求头,响应头,显示资源加载瀑布图。但是httpwatch还能显示GZIP压缩信息,DNS查询,TCP链接信息,个人在监控http请求比较喜欢使用httpwatch,

httpwatch包含IE和firefox插件。不过httpwatch专业版本是收费的,免费版本有些功能限制。

DynaTrace's Ajax Edition:

dynaTrace 是本人常使用的1个免费工具,该工具不但可以检测资源加载瀑布图,而且还能监控页面呈现时间,CPU花销,JS分析和执行时间,CSS解析时间的等。

Speed Tracer:

speed trace 是google chrome的1个插件,speed trace的优势点是用于监控JS的解析执行时间,还可以监控页面的重绘、回流,这个还是很强的(dynaTrace也能有这个功能)。

注:安装这个插件,需要安装 Google Chrome Developer Channel 版本,但是这个链接的地址在国内好像打不开,如果打不开,请大家直接到这个地址去下载:

http://www.google.com/chrome/eula.html?extra=devchannel

Page Speed :

Page speed 是基于firebug的1个工具,主要可以对页面进行评分,总分100分,而且会显示对各项的改进意见,Page Speed也能检测到JS的解析时间。

yslow :

yslow跟pge speed一样是基于 firefox\firebug的插件,功能与page speed类似,对各种影响网站性能的因素进行评分,yslow是yahoo的工具,本人也一直在使用,推荐一下。

webpagetest :

webpagetest 是1个在线进行性能测试的网站,在该网站输入你的url,就会生成1个url加载的时间瀑布图,对所有加载的资源(css,js,image等等)列出优化的清单,也是非常好用的工具。

三、高性能WEB开发之图片篇

在该网站在不影响原图片的质量下去掉图片中一些元数据,那么这怎么去实现呢?本文就主要告诉你如何高性能WEB开发之图片篇

一、缩小图片大小

当图片很多的时候,减少图片大小是提高下载速度最直接的方法。

1. 使用PNG8代替GIF(非动画图片),因为PNG8在效果一样的情况,图片大小比GIF要小。

2. 用fireworks处理PNG图片,在我们产品中很多PNG图片是美工直接用photoshop导出的,

后来让美工用fireworks处理PNG(大概的方式是选择保存为PNG8,删除背景色)。

处理后100K的图片大小基本减少了3/4,但图片质量也会有少许降低,要看自己是否能接受。

3. 使用Smush.it(http://www.smushit.com/ysmush.it/)压缩图片,Smush.it是YUI团队做1个在线压缩图片的网站,

该网站在不影响原图片的质量下去掉图片中一些元数据,所以可以放心使用该网站进行压缩,

但这个压缩比例也是比较有限的。

二、合并图片和拆分图片

1. CSS Sprites合并图片以减少请求数来提高性能大家都知道。但不要把图片合并太多,太多太大了,

就会因为这1个图片影响这个页面的显示了。

2. 有时候我们需要把1个大图片拆分成多个小图片,比如产品首页图片比较少,就1个很大的banner图片,

因浏览器都可以并发下载图片,所以如果不拆分,只使用1个大图片的话,下载速度反而会比较慢

三、透明图片处理

IE6不能显示透明的PNG图片,是很多开发人员特别头疼的事,分别介绍下几种方式的优缺点。

1.使用AlphaImageLoader,IE6支持filter,使用下面的CSS代码,可以让IE6支持PNG

#some-element {  
background: url(image.png);
_background: none;
_filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='image.png', sizingMethod='crop');
}

优点:使用简单

缺点:性能损耗很大,AlphaImageLoader会花费很多资源去处理透明图片,使用AlphaImageLoader,IE使用内存会迅速上升。

而且AlphaImageLoader所有处理都在同1个线程中同步进行,所以当AlphaImageLoader多的时候,会阻塞UI的渲染。

使用_filter,IE7也可以识别,其实IE7是可以识别PNG透明图片的,如果在IE7下使用上面代码,IE7不会直接使用图片,而是使用AlphaImageLoader。

注:个人建议尽量避免使用AlphaImageLoader

2. JS处理

使用DD_belatedPNG(http://www.dillerdesign.com/experiment/DD_belatedPNG/),可以很简单的对界面上所有的透明图片进行同一处理。

优点:使用简单(比AlphaImageLoader还简单)

缺点:当页面上需要处理的图片比较多的时候,速度也比较慢,而且不能动态改变图片。

3. VML

IE6支持VML,VML可以使用透明图片,代码如下:

修改html代码头部

html  xmlns ="http://www.w3.org/1999/xhtml"  xmlns:v >   
head >
style type ="text/css" >
v\:* { behavior : url(#default#VML) ; }
span style="color: rgb(128, 0, 0);">style >
span style="color: rgb(128, 0, 0);">head >
body >
v:image src ="image.png" />
span style="color: rgb(128, 0, 0);">body >
span style="color: rgb(128, 0, 0);">html >

优点:性能好,速度快

缺点:使用复杂,而且不支持firefox等浏览器,需要判断不同的浏览器输出不同的HTML代码。

四、多域名下载图片

因每个浏览器对同1个域名同时只能发送固定的请求,比如IE6好像是2个,所以可以对图片资源开通多个域名进行请求,

比如img1.abc.com,img2.abc.com。但域名不要开启太多,因为解析域名和打开新的连接都需要消耗时间,域名多了,说不定反而会更慢。一般2-4个域名就够了。

五、IE6下缓存背景图片

IE6背景图片缓存是个麻烦事,很多人知道使用下面的JS来让IE6缓存背景图片

try{  
document.execCommand("BackgroundImageCache", false, true);
}catch(e){}

但是这样做的效果并不是非常好,当出现鼠标移动改变背景图片的时候,IE6老是会发送1个图片请求(尽管该背景图片已经下载),

虽然返回结果是304,但还是要花费不少时间。在这种情况下,可以使用下面1个变通的方式来处理,

在页面上直接使用1个DIV元素来加载该图片,这样加载图片就能真正被缓存,鼠标移动也不会发送请求了。

六、预加载图片

使用下面代码可以在页面加载完毕后预加载下1个页面的图片,当进入下1个页面就不用再下载图片了。

window.onload=function(){  
var img = new Image();
img.src = "images/image.png";
img = null;
};

四、高性能WEB开发之疯狂的HTML压缩

在“JS、CSS的合并、压缩、缓存管理”一文中说到自己写过的1个自动合并、压缩JS,CSS,并添加版本号的组件。这次把压缩html的功能也加入到该组件中,流程很简单,就是在程序启动(contextInitialized or Application_Start)的时候扫描所有html,jsp(aspx)进行压缩。

上一篇随笔中网友 skyaspnet 问我如何压缩HTML,当时回答是推荐他使用gzip,后来想想,要是能把所有的html,jsp(aspx)在运行前都压缩成1行未免不是一件好事啊。一般我们启动gzip都比较少对html启动gzip,因为现在的html都是动态的,不会使用浏览器缓存,而启用gzip的话每次请求都需要压缩,会比较消耗服务器资源,对js,css启动gzip比较好是因为js,css都会使用缓存。我个人觉得的压缩html的最大好处就是一本万利,只要写好了一次,以后所有程序都可以使用,不会增加任何额外的开发工作。

在“JS、CSS的合并、压缩、缓存管理”一文中说到自己写过的1个自动合并、压缩JS,CSS,并添加版本号的组件。这次把压缩html的功能也加入到该组件中,流程很简单,就是在程序启动(contextInitialized or Application_Start)的时候扫描所有html,jsp(aspx)进行压缩。

压缩的注意事项:

实现的方式主要是用正则表达式去查找,替换。在html压缩的时候,主要要注意下面几点:

1. pre,textarea 标签里面的内容格式需要保留,不能压缩。

2. 去掉html注释的时候,有些注释是不能去掉的,比如:<!--[if IE 6]> ..... <![endif]-->

3. 压缩嵌入式js中的注释要注意,因为可能注释符号会出现在字符串中,比如: var url = "http://www.cnblogs.com"; // 前面的//不是注释

去掉JS换行符的时候,不能直接跟一下行动内容,需要有空格,考虑下面的代码:

else  return;

如果不带空格,则变成elsereturn。

4. jsp(aspx) 中很有可能会使用嵌入一些服务器代码,这个时候也需要单独处理,里面注释的处理方法跟js的一样。

源代码:

下面是java实现的源代码,也可以 猛击此处 下载该代码,相信大家都看的懂,也很容易改成net代码:

show source 

使用注意事项:

使用了上面方法后,再运行程序,是不是发现每个页面查看源代码的时候都变成1行啦,还不错吧,但是在使用的时候还是要注意一些问题:

1. 嵌入js本来想调用yuicompressor来压缩,yuicompressor压缩JS前,会先编译js是否合法,因我们嵌入的js中可能很多会用到一些服务器端代码,比如 var now = ,这样的代码会编译不通过,所以无法使用yuicompressor。

最后只能自己写压缩JS代码,自己写的比较粗燥,所以有个问题还解决,就是如果开发人员在一句js代码后面没有加分号的话,压缩成1行就很有可能出问题。所以使用这个需要保证每条语句结束后都必须带分号。

2. 因为是在程序启动的时候压缩所有jsp(aspx),所以如果是用户请求的时候动态产生的html就无法压缩。

五、高性能web开发之网络传输环节

本节主要谈网络传输环节,利用HTTP 1.1的长连接特性,使得在一定程度上,服务器可以主动推送数据(减少了很多不必要的轮询)。

1.减少请求数.

1. 缓存,使用Expires 等设置过期时间;如果内容没有过期就不发送请求

2. 合并小体积内容,例如吧数量众多的小图片放在一个图片,之后用css部分呈现(大体积的内容就别合并了)

3. 延迟加载;部分内容,例如图片在页面呈现的时候才加载 (常用的就是滚动条到了以后才加载);减少不必要的请求

4. 合并重复内容和文件

5. 考虑使用第三方CDN资源,例如jQuery有免费的CDN,有些用户已经在其他网站访问过该内容了,那么到我们的网站加载就更快了 (而且使用CDN降低对我们服务器的压力)

6. 使用HTML 5 中的Local Storage等保存数据

2.减少响应内容的体积.

1. 适当的时候只返回响应头304 (HTTP缓存,如ETag等)

2. 使用Gzip等压缩文件内容

3. 使用免费的第三方工具,压缩css,js和html等文件的大小 (例如我们常见的 jquery.min.js)

4. 适当使用Ajax操作

5. 在适当的时候,将样式,HTML和数据分离 (数据量很大的时候极大减小文件体积)

<ul id="id"> 
<li style="一大堆的样式">数据 </li>
<li style="一大堆的样式">数据 </li>
<li style="一大堆的样式">数据 </li>
</ul>
分成HTML 样式 和数据3部分

HTML
<ul id="id">
<li></li>
<!-- 如果使用数据模板等方式 只需要保留一个Li 否则需要多个 -->
</ul>

样式保存在CSS文件中一些基本的小常识 虽然有很多个li 不用给每个li指定class

数据

1. 使用JSON返回 (如果觉得麻烦也可以嵌入在页面中)

2. 选择体积更小的数据格式,例如JSON一般就比XML体积来的小 (都经过压缩以后还是更小)

3. 在设计上,只传送变化的部分数据 (例如要获取100条数据,可能已经加载了90条,那么再加载10条就好了)

4. 移除请求和响应中不必要的HTTP Header (例如WCF Restful service中有的时候要传递表明当前数据是JSON还是XML的HTTP Header)

5. 部分功能,如压缩会消耗CPU, 如ajax等会增加开发工作量,请谨慎选择

3.增加请求并发数.

1. RFC中,浏览器对于同一个域名下的资源只能使用2个线程同时进行访问(很多新的浏览器支持6个或者更多);解决方法是使用子域名,例如1.abc.com 2.abc.com

<img src ="1.abc.com/1.png" /> 
<img src ="1.abc.com/2.png" />
<img src ="2.abc.com/3.png" />
<img src ="2.abc.com/4.png" />
<img src ="3.abc.com/5.png" />
<img src ="3.abc.com/6.png" />
<img src ="4.abc.com/7.png" />
<img src ="4.abc.com/8.png" />

2. 将一个超大的文件(例如有些人喜欢吧整个网站的js都放在一个文件)拆成一系列的中小文件 (有利于并发加载和缓存!)这个文件大小的Size选择很重要 我个人建议是10k-200k (依赖于网络)

3. 上一条并没有和1-2冲突,文件太小太多也不行,文件太少太大也不行,这是一个平衡的问题

4. 通过分拆文件,使得最常用页面(例如首页)的加载速度变快了

5. 控制加载顺序,例如先加载页面大体结构,然后多个javascript异步请求加载数据(把一个大的html变为多个小的html片段)

4.其他特殊技术.

利用HTTP 1.1的长连接特性,使得在一定程度上,服务器可以主动推送数据(减少了很多不必要的轮询)

5.工具.

1. Fiddler (Free)

2. FireDebug (Free)

3. HttpWatch

 
相关文章

深度解析:清理烂代码
如何编写出拥抱变化的代码
重构-使代码更简洁优美
团队项目开发"编码规范"系列文章
 
相关文档

重构-改善既有代码的设计
软件重构v2
代码整洁之道
高质量编程规范
 
相关课程

基于HTML5客户端、Web端的应用开发
HTML 5+CSS 开发
嵌入式C高质量编程
C++高级编程
 
分享到
 
 


使用decj简化Web前端开发
Web开发框架形成之旅
更有效率的使用Visual Studio
MVP+WCF+三层结构搭建框架
ASP.NET运行机制浅析【图解】
编写更好的C#代码
10个Visual Studio开发调试技巧
更多...   


.NET框架与分布式应用架构设计
.NET & WPF & WCF应用开发
UML&.Net架构设计
COM组件开发
.Net应用开发
InstallShield


日照港 .NET Framework & WCF应用开发
神华信息 .NET单元测试
北京 .Net应用软件系统架构
台达电子 .NET程序设计与开发
赛门铁克 C#与.NET架构设计
广东核电 .Net应用系统架构
更多...