网络加速手段之一,JS文件资源合并下载
2012-10-15 14:09
429 查看
有过ftp下载文件经验的人都有体验,单独下载一个100M的文件比分开下载100个1M的文件速度快很多,这是因为下载需要解析域名,建立连接等额外开销的时间,因此下载100个文件就要做100次这种额外的开销。因此如果把这个100个文件整合成一个文件下载速度会快很多。
基于上述的方法,可以对HTML中的JS文件也做类似的处理,无论js文件多少个,通过配置文件,把N个js文件合并到一个文件下载。实现手段通过httpHandler。具体代码如下:
web.config文件中:
只对MergedJS.js的请求文件作合并,具体请求到哪个文件,有querystring参数给定,比如本例中使用MergedJS.js?jsid=myjs这种方式。对于其他类型的js文件,则按照IIS默认的请求方式处理。
上述配置,主要用来指定myjs使用哪些文件来合并。
MergeJS.GetJS 这个HttpHandler主要用来处理js。此处涉及到一个缓存的问题,通常情况下,js文件会默认缓存在本地浏览器缓存中,但是对于MergedJS.js这种通过httpHandler所处理的,被视为动态内容,并不会缓存在浏览器中,而是每次都会从服务器端获取最新的内容。因此可以通过编码,强制使用浏览器缓存。
由于反复读取js所做IO操作也是性能瓶颈,因此在global中首先将所有的js预读存在dictionary中,用的时候直接从dictionary中输出,避免了IO操作。代码能够判断js文件是否做了修改,如果修改了,dictionary中的值也会得到更新。
Handler处理部分的代码如下:
效果如下:使用组合下载的情况,js的下载耗费时间73ms。
但是分开下载的话就比较耗时。
当然,并不是合并为一个文件,下载的速度就一定快,具体的下载速度和策略还受到浏览器的影响,有的浏览器同时开的请求线程多,也会影响下载速度。但是总体来说,如果文件数多的话,下载单一文件总会快点的。
本文出自 “一只博客” 博客,请务必保留此出处http://cnn237111.blog.51cto.com/2359144/1026666
基于上述的方法,可以对HTML中的JS文件也做类似的处理,无论js文件多少个,通过配置文件,把N个js文件合并到一个文件下载。实现手段通过httpHandler。具体代码如下:
web.config文件中:
<httpHandlers> <add verb="*" path="MergedJS.js" type="MergeJS.GetJS"/> </httpHandlers>
只对MergedJS.js的请求文件作合并,具体请求到哪个文件,有querystring参数给定,比如本例中使用MergedJS.js?jsid=myjs这种方式。对于其他类型的js文件,则按照IIS默认的请求方式处理。
<appSettings> <add key="myjs" value="jquery-1.4.1-vsdoc.js, jquery-ui-1.8.16.custom.min.js, jquery-1.4.1.js, jquery-1.7.min.js, jquery-1.5.2.min.js, jquery-1.4.1.min.js, jquery.maskedinput-1.3.js, json2.min.js, jquery.hotkeys-0.0.3.js, jquery.loadmask.min.js, My.js"/> </appSettings>
上述配置,主要用来指定myjs使用哪些文件来合并。
MergeJS.GetJS 这个HttpHandler主要用来处理js。此处涉及到一个缓存的问题,通常情况下,js文件会默认缓存在本地浏览器缓存中,但是对于MergedJS.js这种通过httpHandler所处理的,被视为动态内容,并不会缓存在浏览器中,而是每次都会从服务器端获取最新的内容。因此可以通过编码,强制使用浏览器缓存。
由于反复读取js所做IO操作也是性能瓶颈,因此在global中首先将所有的js预读存在dictionary中,用的时候直接从dictionary中输出,避免了IO操作。代码能够判断js文件是否做了修改,如果修改了,dictionary中的值也会得到更新。
Handler处理部分的代码如下:
/// <summary> /// GetJS 的摘要说明 /// </summary> public class GetJS : IHttpHandler { public void ProcessRequest(HttpContext context) { context.Response.ContentType = "application/x-javascript";//表示是javascript文件类型 string jsid = context.Request.Params["jsid"].ToString(); //获取所有需要Merge的文件 string[] jsfiles = System.Configuration.ConfigurationManager.AppSettings[jsid].ToString().Replace("\r", "").Replace("\n", "").Split(','); //记录文件的最后修改时间,取最新修改的那个文件的时间。 DateTime lastChangeTime = new DateTime(); StringBuilder sb = new StringBuilder(); foreach (var js in jsfiles) { if (Global.dic_jsfiles.ContainsKey(js)) { DateTime tmplastDateTime = new FileInfo(Global.dic_jsfiles[js].filefullName).LastWriteTime; tmplastDateTime = DateTime.Parse(tmplastDateTime.ToString("yyyy-MM-dd HH:mm:ss"));//去除毫秒信息。 if (tmplastDateTime > Global.dic_jsfiles[js].lastModifiedTime)//如果最后修改时间更改,更新dic_jsfiles内容 { Global.dic_jsfiles[js].content = Common.ReadFile(Global.dic_jsfiles[js].filefullName);//读取新的文件 Global.dic_jsfiles[js].lastModifiedTime = tmplastDateTime; } } else//如果不存在,则读取该文件 { string filename = context.Request.PhysicalApplicationPath + "Scripts\\" + js.Trim(); Global.dic_jsfiles.Add(filename,new jsFileInfo() { filefullName = filename,content=Common.ReadFile(filename),lastModifiedTime=new FileInfo(filename).LastWriteTime }); Common.ReadFile(Global.dic_jsfiles[js].filefullName); } sb.Append(Global.dic_jsfiles[js].content + ";"); } //文件最后修改时间 lastChangeTime = Global.dic_jsfiles.Max(m => m.Value.lastModifiedTime); DateTime If_Modified_Since = new DateTime(); if (context.Request.Headers["If-Modified-Since"] == null || context.Request.Headers["If-Modified-Since"] == "") { If_Modified_Since = new DateTime(1900, 1, 1);//如果读取的请求头中If-Modified-Since没有值,就给它一个默认值为19000101 } else { If_Modified_Since = DateTime.Parse(context.Request.Headers["If-Modified-Since"]); } if (If_Modified_Since >= lastChangeTime)//如果客户端请求头中的时间最后一次修改时间,比真实的最后修改时间还新,则直接返回304代码 { context.Response.StatusCode = 304;//返回304代码,使其读取缓存 context.Response.End(); } else//否则 { //显示内容 context.Response.AddHeader("last-modified", lastChangeTime.ToString()); } context.Response.Write(sb.ToString()); } private string ReadFile(string filename) { using (StreamReader sr = new StreamReader(filename, System.Text.UTF8Encoding.UTF8)) { return sr.ReadToEnd(); } } public bool IsReusable { get { return false; } } }
效果如下:使用组合下载的情况,js的下载耗费时间73ms。
但是分开下载的话就比较耗时。
当然,并不是合并为一个文件,下载的速度就一定快,具体的下载速度和策略还受到浏览器的影响,有的浏览器同时开的请求线程多,也会影响下载速度。但是总体来说,如果文件数多的话,下载单一文件总会快点的。
本文出自 “一只博客” 博客,请务必保留此出处http://cnn237111.blog.51cto.com/2359144/1026666
相关文章推荐
- 网络加速手段之一,JS文件资源合并下载
- 网络多线线程下载并合并文件示例
- UnityWebRequest下载网络资源,支持断点续传、多文件同时下载
- 网络多线线程下载并合并文件示例
- 将指定的HTTP网络资源在本地以文件形式存放(下载)
- Android下载网络资源文件
- Jquery,Echarts在js中引用是无需下载文件,直接网络引用。src地址记录,长期更新
- 格式化网络下载的js文件
- 关于java Io流的操作,复制(多个文件)、删除、剪切、下载网络资源
- js文件合并,压缩,缓存,延迟加载
- 利用 filter 机制 给 静态资源 url 加上时间戳,来防止js和css文件的缓存,利于开发调试
- Android 利用多线程从网络下载文件
- js下如何弹出保存对话框进行文件下载
- js下如何弹出保存对话框进行文件下载
- iOS-网络编程 文件上传和断点离线下载
- java 从网络Url中下载文件
- java多线程下载服务器资源文件-------(demo)支持断点下载
- 论如何高速下载磁力链接、电驴链接、种子文件里的资源
- 文件下载资源网址
- node.js使用url下载文件