模仿yui将css和js打包,加速网页速度
如果你有机会用firebug看看自己网站的网络请求,你会发现请求数量之多超乎你的想象。为减少这个数量,有许多技术方案。比如yui的combo,会将所有需要的js混合成一个文件下载,现代web服务器好像也有这种技术,通过分析网页的链接,将一些文件合并。但这是别人实现的,也许不合你的需求。以下代码是本人在诗篇建站平台上的一个servlet,希望能给你写类似的代码起到一些参考作用。
1、约定格式。这是: http://www.m3958.com/in 的网页源代码的片段,你必须在客户端和服务器端约定格式。
<script type="text/javascript" src="/yuicombo?version=2.2&prefix=/codemirror/2.2/&lib/codemirror.js&mode/xml/xml.js&mode/javascript/javascript.js&mode/css/css.js&mode/htmlmixed/htmlmixed.js&lib/util/dialog.js&lib/util/searchcursor.js&lib/util/search.js"></script>
参数:
version,如果一个combo请求带有version参数,作者就应该知道这个url的内容什么时候改变。这个参数很有用,待会儿继续说。
prefix,postfix这个故名思意了,可以大大的缩短url长度。
separator,如果大部分文件是具有相同前后缀,而有的没有遵循这个约定,也可以混合在一起,就是这个searator之后,不再添加前后缀。
那么version有什么用呢?既然你知道version和内容变化的对应关系,对于具有version的url请求,你可以设置永久缓存,比如10年。除此之外,从url生成一个md5值,作为etag发送给浏览器。当浏览器请求的时候,服务器如果发现:有version,有etag,那么最大的可能是用户强制刷新浏览器,通过比较etag和url的md5值,如果一致,返回304即可。
1. [代码][Java]代码
if(finalqs.isEmpty()){//在混合請求的情況下,如果缺少某個組件,yui會自動拉去,這個情況下前綴也是yuicombo
finalqs = req.getRequestURI().replace("/yuicombo", "/yui");
fns = new String[]{finalqs};
}
//client cache 针对url而定,那么只要url不同,cache就不会hit
//如果某个url带有version字段,那么作者必须知道这个内容的变化,所以可以永久缓存。
if("css".equals(type)){
type = "text/css";
}else if("js".equals(type)){
type = "text/javascript";
}else{
;
}
if(type == null || type.isEmpty())type = "text/javascript";
res.setContentType(type + ";charset=utf-8");
res.setCharacterEncoding("UTF-8");
if(version == null || version.isEmpty()){
;
}else{
String etag = req.getHeader("If-None-Match");
if(etag != null && etag.equals(shaService.encrypt(finalqs))){
res.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
return;http://www.enterdesk.com/special/shouhui/
}手绘图片
res.setHeader("Cache-Control","max-age=" + PeriodContants.YEAR_IN_SECONDS * 10);
res.setHeader("Etag", shaService.encrypt(finalqs));
}
Writer out = res.getWriter();
File wr = new File(getServletContext().getRealPath("/"));
boolean separatorReached = false;
for(String fn : fns){
if(fn.startsWith("type=") || fn.startsWith("prefix=") || fn.startsWith("postfix=") || fn.startsWith("separator=") || fn.startsWith("version=")){
continue;
}
if(fn.equals(separator)){
separatorReached = true;
continue;
}
File f = null;
if(!separatorReached){
if(prefix != null && !prefix.isEmpty()){
fn = prefix + fn;
}
if(postfix != null && !postfix.isEmpty() && !fn.endsWith(postfix)){
fn = fn + postfix;
}
}
f = new File(wr,fn);
if(f != null && f.isFile() && f.exists()){
try {
FileInputStream is = new FileInputStream(f);
out.write(autils.read2String(is, "utf-8"));
} catch (Exception e) {
e.printStackTrace();
}
}
}
out.flush();
out.close();