说明:前面一篇文章《web前端优化》中主要提到一些比较理论的东西,这篇文章主要介绍楼主在代码中的实现。
引言:当前能看到很多互联网网站中有关web前端优化都采用js合并压缩的方式输出。楼主找了几个地址参考
地址1、地址2
那么下面就开始了如何实现。
1.既然需要将js合并压缩输出那么就先需要构造一个如上链接所示的那样的链接地址。
@using MvcApplication.ExtensionsFolder <html> <head> <title>@ViewBag.Title</title> @Html.LoadJsList("jquery-1.4.4.min.js,jquery-ui.js,MicrosoftAjax.js&v=20121222") </head>
然后看看有关给MvcHtmlString类的扩展方法LoadJsList的实现,在mvc中扩展方法的使用已经比较普遍了。
public static MvcHtmlString LoadJsList(this HtmlHelper htmlhelp, string ListJs) { StringBuilder sb = new StringBuilder(); string jsFormat = "<script type=\"text/javascript\" src=\"{0}\"></script>"; sb.AppendFormat(jsFormat, JsHandlerUrl + ListJs); return new MvcHtmlString(sb.ToString()); }
2.这样的话输出页面输出就是
<script type="text/javascript" src="http://localhost:1309/ashx/MergerJsHandler.ashx?href=jquery-1.4.4.min.js,jquery-ui.js,MicrosoftAjax.js&v=20121222"></script>
至此我们已经完成一半了,接下来就是输出合并以及压缩出来的js了。
3.在MergerJsHandler.ashx文件中
private string JsHandlerUrl { get { return ConfigurationManager.AppSettings["jsAddress"] ?? string.Empty; } } public void ProcessRequest(HttpContext context) { //"http://localhost:1309/ashx/MergerJsHandler.ashx?href=jquery-1.4.4.min.js,domestic.js,v=20121222 context.Response.ContentType = "text/plain"; HttpRequest request = context.Request; HttpResponse response = context.Response; if (!context.Request.QueryString.AllKeys.Contains("href")) { response.Write("error"); } else { string[] filesName = request.QueryString["href"].Trim().Split(new string[] { ","}, StringSplitOptions.RemoveEmptyEntries); Compress(request.QueryString["v"], context, filesName); } }
就是获取参数然后调用compress方法做处理,并且输出。
压缩我采用的是Yahoo.Yui.Compressor 。这个压缩工具既能压缩js还可以压缩css。
/// <summary> /// /// </summary> /// <param name="v">指示是否修改</param> /// <param name="context">当前上下文</param> private void Compress(string v, HttpContext context, string[] jsPar) { StringBuilder sb = new StringBuilder(); var SaveJsFilePath = ConfigurationManager.AppSettings["jsAddress"] ?? string.Empty; var files = System.IO.Directory.GetFiles(context.Server.MapPath("~/") + SaveJsFilePath, v, SearchOption.TopDirectoryOnly); if (files != null && files.Length > 0)//存在的话,直接输出压缩的内容 { var content = File.ReadAllText(files[0], Encoding.UTF8); sb.Append(content); } else//获取各个js然后压缩在一起,保存并输出 { foreach (var file in jsPar) { var path = context.Server.MapPath("~/") + JsHandlerUrl + file; FileInfo finfo = new FileInfo(JsHandlerUrl + file); string strContent = File.ReadAllText(path, Encoding.UTF8); //取消文件只读 File.SetAttributes(path, FileAttributes.Normal); //if (finfo.Extension.ToLower() == ".js") //{ //初始化JS压缩类 var js = new JavaScriptCompressor(); js.CompressionType = CompressionType.Standard;//压缩类型 js.Encoding = Encoding.UTF8;//编码 js.IgnoreEval = false;//大小写转换 js.ThreadCulture = System.Globalization.CultureInfo.CurrentCulture; //压缩该js strContent = js.Compress(strContent); sb.Append(strContent); //} //else if (finfo.Extension.ToLower() == ".css") //{ // //进行CSS压缩 // CssCompressor css = new CssCompressor(); // strContent = css.Compress(strContent); // File.WriteAllText(file, strContent, Encoding.UTF8); //} } File.WriteAllText(context.Server.MapPath("~/") + SaveJsFilePath + v, sb.ToString(), Encoding.UTF8); } context.Response.Write(sb.ToString()); }
那么这个打印出来的代码就是我们成功处理后的了。
至此就大功告成了。当然上面的参数没有做过滤等等的考虑,在实际开发中过滤和一些恶意的请求都是需要处理的,毕竟楼主还是没有在实际开发中使用用过,不过应该相差不远吧。呵呵。
最后看看效果
不过我有一个问题,就是为嘛合并请求的大小比那3个独立的js大小还要大呢。难道是因为请求参数和请求头里边有猫腻吗。