Java Web 高性能开发提高页面加载速度.docx

上传人:b****5 文档编号:6059364 上传时间:2023-01-03 格式:DOCX 页数:16 大小:99.20KB
下载 相关 举报
Java Web 高性能开发提高页面加载速度.docx_第1页
第1页 / 共16页
Java Web 高性能开发提高页面加载速度.docx_第2页
第2页 / 共16页
Java Web 高性能开发提高页面加载速度.docx_第3页
第3页 / 共16页
Java Web 高性能开发提高页面加载速度.docx_第4页
第4页 / 共16页
Java Web 高性能开发提高页面加载速度.docx_第5页
第5页 / 共16页
点击查看更多>>
下载资源
资源描述

Java Web 高性能开发提高页面加载速度.docx

《Java Web 高性能开发提高页面加载速度.docx》由会员分享,可在线阅读,更多相关《Java Web 高性能开发提高页面加载速度.docx(16页珍藏版)》请在冰豆网上搜索。

Java Web 高性能开发提高页面加载速度.docx

JavaWeb高性能开发提高页面加载速度

JavaWeb高性能开发,提高页面加载速度

魏强,东北大学软件学院硕士研究生,现在主要从事Eclipse插件的开发,同时热爱着Web技术,尤其对JavaWeb相关技术,更是情有独钟。

他的邮箱是:

neuswc20063500@。

简介:

 Web发展的速度让许多人叹为观止,层出不穷的组件、技术,只需要合理的组合、恰当的设置,就可以让Web程序性能不断飞跃。

所有Web的思想都是通用的,它们也可以运用到JavaWeb。

这一系列的文章,将从各个角度,包括前端高性能、反向代理、数据库高性能、负载均衡等等,以JavaWeb为背景进行讲述,同时用实际的工具、实际的数据来对比被优化前后的JavaWeb程序。

第一部分,主要讲解网页前端的性能优化,这一部分是最直接与用户接触的。

事实证明,与其消耗大量时间在服务器端,在前端进行的优化更易获得用户的肯定。

引言

前端的高性能部分,主要是指减少请求数、减少传输的数据以及提高用户体验,在这个部分,图片的优化显得至关重要。

许多网站的美化,都是靠绚丽的图片达到的,图片恰恰是占用带宽的元凶。

每个img标签,浏览器都会试图发起一个下载请求。

本文就详细介绍了图片优化的几种方式,介绍了使用的工具以及优化后的结果。

图片压缩

减少图片的大小,可以明显的提高性能,而对于已有图片,要想减少图片的大小,只能改变图片的格式,这里推荐的是PNG8的格式,它可以在基本保持清晰度的情况下,减少图片的大小。

知道这个原理以后,可以用Windows的画图工具、以及PhotoShop工具逐个的改变。

但是这样做的缺点是单张处理,效率太慢。

本文推荐一个在线转换工具Smush.it,可以批量的进行压缩与转换。

它的地址是:

图1.Yahoo提供的在线压缩工具

我们上传了一张大小为3790K的图片,待在线程序处理完毕后,点击DownloadSmushedImages下载查看结果。

下载界面如下图所示。

图2.压缩后的结果

打开下载下来的压缩包,查看结果可以看到,图片从3790减少到了3344,就如下图所示。

对于大批量的图片网站,这个方法会帮助快速实现批量图片压缩。

图3.压缩后的结果

图像合并实现CSSSprites

CSSSprites是一个吸引人的技术,它其实就是把网页中一些背景图片整合到一张图片文件中,再利用CSS的“background-image”,“background-repeat”,“background-position”的组合进行背景定位,background-position可以用数字能精确的定位出背景图片的位置。

利用CSSSprites能很好地减少网页的HTTP请求,从而大大的提高了页面的性能,这也是CSSSprites最大的优点,也是其被广泛传播和应用的主要原因。

CSSSprites能减少图片的字节,由于图像合并后基本信息不用重复,那么多张图片合并成1张图片的字节往往总是小于这些图片的字节总和。

同时CSSSprites解决了网页设计师在图片命名上的困扰,只需对一张集合的图片上命名就可以了,不需要对每一个小元素进行命名,从而提高了网页的制作效率。

更换风格方便,只需要在一张或少张图片上修改图片的颜色或样式,整个网页的风格就可以改变。

维护起来更加方便。

同时,由于将图片合并到一张图片,因此图片的请求数就被缩减到1个。

其他的请求都可以用到本地缓存,不需要访问服务器。

下图是一个合并以后的图片。

它将很多小图标都拼到了一起。

图4.合并后的图片

这里介绍一个小工具---“CSSSprites样式生成工具2.0”,可以从这里下载。

这是一个简单免费的小工具,用该工具打开上面的图片,选中图片中的某块。

如下图的“绿色大拇指”部分,工具会计算出这个部分的长、宽、距离左上角的距离。

勾选复制类名、复制宽、复制高,再点击“复制当前样式”按钮。

这样生成的样式会被复制到剪切板上。

图5.小工具的使用

生成的CSS代码如清单1所示。

清单1.小工具生成的CSS代码

.div_6148{width:

18px;height:

20px;background-position:

-17px-209px;}

将这段代码运用在网页上,它的代码如下清单所示。

清单2.测试CSSSprites代码

打开测试网页显示结果如下图所示。

图6.测试网页效果

可以看到,网页只显示工具选择的“绿色大拇指”部分,这样的代码可以运用在网页的多个部分,而图片只需要下载一次,这就是该技术的最大优势,减少了因为小图片引起的多个请求。

多域名请求

有时候,图片数据太多,一些公司的解决方法是将图片数据分到多个域名的服务器上,这在一方面是将服务器的请求压力分到多个硬件服务器上。

另一方面,是利用了浏览器的特性。

一般来说,浏览器对于相同域名的图片,最多用2-4个线程并行下载。

不同浏览器的并发下载数,都是不同的,并发数如下清单所示。

清单3.各浏览器的并发下载数

BrowsersHTTP/1.1HTTP/1.0

IE6,724

IE866

FireFox228

FireFox366

Safari3,444

Chrome1,26?

Chrome344

Opera9.63,10.00alpha44

而相同域名的其他图片,则要等到其他图片下载完后才会开始下载。

这里我做了一个测试,选择了多个相同域名的图片在同一网页上。

代码如清单5所示。

清单4.单域名的多图片下载

接下来,使用FireFox的Firebug插件监控网络。

结果如下图所示。

图7.单域名多图片的监控效果

可以看到,相同域名的多张图片,它们下载的起始点是存在延迟的。

它们并不是并行下载。

当我们将其中的3张图片换成别的域名图片。

如清单6所示。

清单5.多域名多图片下载

再次查看网络监控,可以看到,这些图片是并行下载的。

图8.多域名多图片测试结果

多域名的下载固然很好,但是太多域名并不太好,一般在2-3个域名下载就差不多。

图像的BASE64编码

不管如何,图片的下载始终都要向服务器发出请求,要是图片的下载不用向服务器发出请求,而可以随着HTML的下载同时下载到本地那就太好了。

而目前,浏览器已经支持了该特性,我们可以将图片数据编码成BASE64的字符串,使用该字符串代替图像地址。

假设用S代表这个BASE64字符串,那么就可以使用

image/png;base64,S">来显示这个图像。

可以看出,图像的数据包含在了HTML代码里,无需再次访问服务器。

那么图像要如何编码成BASE64字符串呢?

可以使用在线的工具---“Base64Online”,这个工具可以上传图片将图片转换为BASE64字符串。

当然,如果读者有兴趣,完全可以自己实现一个BASE64编码工具,比如使用Java开发,它的代码就如清单7所示。

清单6.BASE64的Java代码

publicstaticStringgetPicBASE64(StringpicPath){

Stringcontent=null;

try{

FileInputStreamfis=newFileInputStream(picPath);

byte[]bytes=newbyte[fis.available()];

fis.read(bytes);

content=newsun.misc.BASE64Encoder().encode(bytes);//具体的编码方法

fis.close();

}catch(Exceptione){

e.printStackTrace();

}

returncontent;

}

本文编码了一个图像,并且将编码获得的BASE64字符串,写到了HTML之中,如下清单8所示。

清单7.嵌入BASE64的测试HTML代码

image/png;base64,

iVBORw0KGgoAAAANSUhEUgAAAeQAAAB8BAMAAABKwt5QAAAAA3NCSVQICAjb4U/gAAAAGFBMVEX/

……(省略了大部分编码)…BJRU5ErkJggg==">

由于图片数据包含在了BASE64字符串中,因此无需向服务器请求图像数据,结果显示如下图所示。

图9.BASE64显示图像

然而这种策略并不能滥用,它适用的情况是浏览器连接服务器的时间>图片下载时间,也就是发起连接的代价要大于图片下载,那么这个时候将图片编码为BASE64字符串,就可以避免连接的建立,提高效率。

如果图片较大的话,使用BASE64编码虽然可以避免连接建立,但是相对于图像下载,请求的建立只占很小的比例,如果用BASE64,对于动态网页来说图像缓存就会失效(静态网页可以缓存),而且BASE64字符串的总大小要大于纯图片的大小,这样一算就非常不合适了。

因此,如果你的页面已经静态化,图像又不是非常大,可以尝试BASE64编码,客户端会将网页内容和图片的BASE64编码一起缓存;而如果你的页面是动态页面,图像还较大,每次都要下载BASE64字符串,那么就不能用BASE64编码图像,而正常引用图像,从而使用到浏览器的图像缓存,提高下载速度。

从现实我们接触的角度看,如一些在线HTML编辑器,里面的小图标,如笑脸等,都使用到了BASE64编码,因为它们非常小,数量多,BASE64可以帮助网页减少图标的请求数,提高效率。

GZIP压缩

为了减少传输的数据,压缩是一个不错的选择,而HTTP协议支持GZIP的压缩格式,服务器响应的报头包含Content-Encoding:

gzip,它告诉浏览器,这个响应的返回数据,已经压缩成GZIP格式,浏览器获得数据后要进行解压缩操作。

这在一定程度可以减少服务器传输的数据,提高系统性能。

那么如何给服务器响应添加Content-Encoding:

gzip报头,同时压缩响应数据呢?

如果你用的是Tomcat服务器,打开$tomcat_home$/conf/server.xml文件,对Connector进行配置,配置如清单9所示。

清单8.TOMCAT配置清单

maxThreads="150"minSpareThreads="25"maxSpareThreads="75"

enableLookups="false"redirectPort="8443"acceptCount="100"

connectionTimeout="20000"disableUploadTimeout="true"URIEncoding="utf-8"

compression="on"

compressionMinSize="2048"

noCompressionUserAgents="gozilla,traviata"

compressableMimeType="text/html,text/xml"/>

我们为Connector添加了如下几个属性,他们意义分别是:

compression="on"打开压缩功能

compressionMinSize="2048"启用压缩的输出内容大小,这里面默认为2KB

noCompressionUserAgents="gozilla,traviata"对于以下的浏览器,不启用压缩

compressableMimeType="text/html,text/xml,image/png" 压缩类型

有时候,我们无法配置server.xml,比如如果我们只是租用了别人的空间,但是它并没有启用GZIP,那么我们就要使用程序启用GZIP功能。

我们将需要压缩的文件,放到指定的文件夹,使用一个过滤器,过滤对这个文件夹里文件的请求。

清单9.自定义Filter压缩GZIP

//监视对gzipCategory文件夹的请求

@WebFilter(urlPatterns={"/gzipCategory/*"})

publicclassGZIPFilterimplementsFilter{

@Override

publicvoiddoFilter(ServletRequestrequest,ServletResponseresponse,

FilterChainchain)throwsIOException,ServletException{

Stringparameter=request.getParameter("gzip");

//判断是否包含了Accept-Encoding请求头部

HttpServletRequests=(HttpServletRequest)request;

Stringheader=s.getHeader("Accept-Encoding");

//"1".equals(parameter)只是为了控制,如果传入gzip=1,才执行压缩,目的是测试用

if("1".equals(parameter)&&header!

=null&&header.toLowerCase().contains("gzip")){

HttpServletResponseresp=(HttpServletResponse)response;

finalByteArrayOutputStreambuffer=newByteArrayOutputStream();

HttpServletResponseWrapperhsrw=newHttpServletResponseWrapper(

resp){

@Override

publicPrintWritergetWriter()throwsIOException{

returnnewPrintWriter(newOutputStreamWriter(buffer,

getCharacterEncoding()));

}

@Override

publicServletOutputStreamgetOutputStream()throwsIOException{

returnnewServletOutputStream(){

@Override

publicvoidwrite(intb)throwsIOException{

buffer.write(b);

}

};

}

};

chain.doFilter(request,hsrw);

byte[]gzipData=gzip(buffer.toByteArray());

resp.addHeader("Content-Encoding","gzip");

resp.setContentLength(gzipData.length);

ServletOutputStreamoutput=response.getOutputStream();

output.write(gzipData);

output.flush();

}else{

chain.doFilter(request,response);

}

}

//用GZIP压缩字节数组

privatebyte[]gzip(byte[]data){

ByteArrayOutputStreambyteOutput=newByteArrayOutputStream(10240);

GZIPOutputStreamoutput=null;

try{

output=newGZIPOutputStream(byteOutput);

output.write(data);

}catch(IOExceptione){

}finally{

try{

output.close();

}catch(IOExceptione){

}

}

returnbyteOutput.toByteArray();

}

……

}

该程序的主体思想,是在响应流写回之前,对响应的字节数据进行GZIP压缩,因为并不是所有的浏览器都支持GZIP解压缩,如果浏览器支持GZIP解压缩,会在请求报头的Accept-Encoding里包含gzip。

这是告诉服务器浏览器支持GZIP解压缩,因此如果用程序控制压缩,为了保险起见,还需要判断浏览器是否发送accept-encoding:

gzip报头,如果包含了该报头,才执行压缩。

为了验证压缩前后的情况,使用Firebug监控请求和响应报头。

清单10.压缩前请求

GET/testProject/gzipCategory/test.htmlHTTP/1.1

Accept:

*/*

Accept-Language:

zh-cn

Accept-Encoding:

gzip,deflate

User-Agent:

Mozilla/4.0(compatible;MSIE6.0;WindowsNT5.1;SV1)

Host:

localhost:

9090

Connection:

Keep-Alive

清单11.不压缩的响应

HTTP/1.1200OK

Server:

Apache-Coyote/1.1

ETag:

W/"5060-1242444154000"

Last-Modified:

Sat,16May200903:

22:

34GMT

Content-Type:

text/html

Content-Length:

5060

Date:

Mon,18May200912:

29:

49GMT

清单12.压缩后的响应

HTTP/1.1200OK

Server:

Apache-Coyote/1.1

ETag:

W/"5060-1242444154000"

Last-Modified:

Sat,16May200903:

22:

34GMT

Content-Encoding:

gzip

Content-Type:

text/html

Content-Length:

837

Date:

Mon,18May200912:

27:

33GMT

可以看到,压缩后的数据比压缩前数据小了很多。

压缩后的响应报头包含Content-Encoding:

gzip。

同时Content-Length包含了返回数据的大小。

GZIP压缩是一个重要的功能,前面提到的是对单一服务器的压缩优化,在高并发的情况,多个Tomcat服务器之前,需

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 法律文书 > 调解书

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1