Java Web 高性能开发提高页面加载速度Word文档下载推荐.docx
- 文档编号:19056210
- 上传时间:2023-01-03
- 格式:DOCX
- 页数:16
- 大小:99.20KB
Java Web 高性能开发提高页面加载速度Word文档下载推荐.docx
《Java Web 高性能开发提高页面加载速度Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《Java Web 高性能开发提高页面加载速度Word文档下载推荐.docx(16页珍藏版)》请在冰豆网上搜索。
图像合并实现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代码
<
html>
head>
style>
.div_6148
{
width:
height:
background-image:
url(css-sprites-source.gif);
background-position:
}
/style>
/head>
body>
divclass="
div_6148"
>
<
/div>
/body>
/html>
打开测试网页显示结果如下图所示。
图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.单域名的多图片下载
imgsrc="
接下来,使用FireFox的Firebug插件监控网络。
结果如下图所示。
图7.单域名多图片的监控效果
可以看到,相同域名的多张图片,它们下载的起始点是存在延迟的。
它们并不是并行下载。
当我们将其中的3张图片换成别的域名图片。
如清单6所示。
清单5.多域名多图片下载
再次查看网络监控,可以看到,这些图片是并行下载的。
图8.多域名多图片测试结果
多域名的下载固然很好,但是太多域名并不太好,一般在2-3个域名下载就差不多。
图像的BASE64编码
不管如何,图片的下载始终都要向服务器发出请求,要是图片的下载不用向服务器发出请求,而可以随着HTML的下载同时下载到本地那就太好了。
而目前,浏览器已经支持了该特性,我们可以将图片数据编码成BASE64的字符串,使用该字符串代替图像地址。
假设用S代表这个BASE64字符串,那么就可以使用<
data:
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代码
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配置清单
Connectorport="
80"
maxHttpHeaderSize="
8192"
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="
打开压缩功能
compressionMinSize="
启用压缩的输出内容大小,这里面默认为2KB
noCompressionUserAgents="
对于以下的浏览器,不启用压缩
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("
.equals(parameter)&
&
header!
=null&
header.toLowerCase().contains("
)){
HttpServletResponseresp=(HttpServletResponse)response;
finalByteArrayOutputStreambuffer=newByteArrayOutputStream();
HttpServletResponseWrapperhsrw=newHttpServletResponseWrapper(
resp){
publicPrintWritergetWriter()throwsIOException{
returnnewPrintWriter(newOutputStreamWriter(buffer,
getCharacterEncoding()));
publicServletOutputStreamgetOutputStream()throwsIOException{
returnnewServletOutputStream(){
publicvoidwrite(intb)throwsIOException{
buffer.write(b);
};
chain.doFilter(request,hsrw);
byte[]gzipData=gzip(buffer.toByteArray());
resp.addHeader("
Content-Encoding"
"
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;
output=newGZIPOutputStream(byteOutput);
output.write(data);
}catch(IOExceptione){
}finally{
output.close();
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.压缩后的响应
Content-Encoding:
gzip
837
27:
33GMT
可以看到,压缩后的数据比压缩前数据小了很多。
压缩后的响应报头包含Content-Encoding:
gzip。
同时Content-Length包含了返回数据的大小。
GZIP压缩是一个重要的功能,前面提到的是对单一服务器的压缩优化,在高并发的情况,多个Tomcat服务器之前,需
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Java Web 高性能开发提高页面加载速度 性能 开发 提高 页面 加载 速度