I have been working on the web for some time. I want to share with you some experiences in loading JS files on the web.
1. First, let's talk about merging and compressing JS files.
To facilitate centralized management of JS merge and compression, we create a JS. ashx file to specifically handle merge compression. Here we use the Yahoo. Yui. Compressor tool to compress our JS files.
The Code is as follows:
Public class JS: ihttphandler {public void processrequest (httpcontext context) {context. response. contenttype = "text/JavaScript"; httprequest request = context. request; httpresponse response = context. response; If (! Request. querystring. allkeys. contains ("href") {response. write ("NO content");} else {string href = context. request. querystring ["href"]. trim (); string [] files = href. split (New String [] {","}, stringsplitoptions. removeemptyentries); foreach (string filename in files) {string filepath = context. server. mappath (filename); If (file. exists (filepath) {string content = file. readalltext (filepath, encoding. utf8); content = javascriptcompressor. compress (content); response. write (content);} else {response. write ("\ r \ N source file not found" + filepath + "\ r \ n") ;}}} public bool isreusable {get {return false ;}}}
When we access Js in a browser, for example:
Http: // localhost: 58798/JS. ashx? Href = scripts/jquery. lazyload. JS, scripts/jquery. Validate. js
Returned results
However, in actual development, many projects put JS references in a very unfriendly place to pursue JS merging and compression, and write a long string, such as JS reference above.
Let's talk about how to improve it:
public static class Extensions { const string jsFileKey = "JSFileKey"; static string jshandlerUrl = string.Empty; public static string JsHandlerUrl { get { if (string.IsNullOrEmpty(jshandlerUrl)) { jshandlerUrl = ConfigurationManager.AppSettings["jsHandlerUrl"] ?? string.Empty; } return jshandlerUrl; } } public static void AppendJsFile(this HtmlHelper htmlHelper, string jsFile, int group = 1) { NameValueCollection jsFiles = null; if (htmlHelper.ViewContext.HttpContext.Items.Contains(jsFileKey)) { jsFiles = htmlHelper.ViewContext.HttpContext.Items[jsFileKey] as NameValueCollection; } else { jsFiles = new NameValueCollection(); htmlHelper.ViewContext.HttpContext.Items.Add(jsFileKey, jsFiles); } if (jsFiles.AllKeys.Contains(group.ToString())) { string fileUrl = jsFiles[group.ToString()]; if (!fileUrl.Contains(jsFile)) jsFiles.Add(group.ToString(), jsFile); } else { jsFiles.Add(group.ToString(), jsFile); } htmlHelper.ViewContext.HttpContext.Items[jsFileKey] = jsFiles; } public static MvcHtmlString RenderJsFile(this HtmlHelper htmlHelper) { NameValueCollection jsFiles = null; StringBuilder content = new StringBuilder(); if (htmlHelper.ViewContext.HttpContext.Items.Contains(jsFileKey)) { jsFiles = htmlHelper.ViewContext.HttpContext.Items[jsFileKey] as NameValueCollection; List<string> jsKeys = jsFiles.AllKeys.OrderBy(x => x).ToList<string>(); string jsFormat = "<script type=\"text/javascript\" src=\"{0}\"></script>"; foreach (string key in jsKeys) { string jsFile = jsFiles[key]; content.AppendFormat(jsFormat, JsHandlerUrl + jsFile); //htmlHelper.ViewContext.HttpContext.Response.Write(string.Format(jsFormat, JsHandlerUrl + jsFile)); } } return new MvcHtmlString(content.ToString()); } }
In this way, we can easily write code during development, for example:
@{Html.AppendJsFile("Scripts/jquery.lazyload.js");}
In this way, all JS files are cached, and all JS files are output at one time by calling @ HTML. renderjsfile. For example:
I will not say much about the reason for writing this Code. This idea is available in both renderpartial and renderaction in MVC, as shown in
Duplicate JS references are also removed from Js. ashx.Is it convenient?
The final HTML code:
2. Next let's take a look at the JS delay loading, in order to achieve JS delay loading we need to reference the relevant JS, here I use lazyload. JS, please refer to the specific http://blog.csdn.net/dz45693/article/details/7529584
Effect of delayed Loading
Only one 2.2k lazyload. js file is loaded before the file is loaded. Other JS files are loaded after ready.
Corresponding HTML code
3. Next, let's take a look at the JS cache. The cache involves the server and client cache. If the client cache is white, the 304 response will be made.
Modified code:
Class cacheitem {Public String content {set; get;} public datetime expires {set; get ;}} public void processrequest (httpcontext context) {context. response. contenttype = "text/JavaScript"; httprequest request = context. request; httpresponse response = context. response; If (! Request. querystring. allkeys. contains ("href") {response. write ("NO content");} else {string href = context. request. querystring ["href"]. trim (); string [] files = href. split (New String [] {","}, stringsplitoptions. removeemptyentries); cacheitem item = NULL; object OBJ = httpruntime. cache. get (href); // server cache if (null = OBJ) {stringbuilder alltext = new stringbuilder (); foreach (string filename In files) {string filepath = context. server. mappath (filename); If (file. exists (filepath) {string content = file. readalltext (filepath, encoding. utf8); content = javascriptcompressor. compress (content); // response. write (content); alltext. append (content);} else {// response. write ("\ r \ N source file not found" + filepath + "\ r \ n"); alltext. append ("\ r \ N source file not found" + filepath + "\ r \ n") ;}// end foreach item = new cacheitem () {Content = alltext. tostring (), expires = datetime. now. addhours (1)}; httpruntime. cache. insert (href, item, null, item. expires, timespan. zero);} else {item = OBJ as cacheitem;} If (request. headers ["If-modified-since"]! = NULL & timespan. fromticks (item. expires. ticks-datetime. parse (request. headers ["If-modified-since"]). ticks ). seconds <100) {response. statuscode = 304; // response. headers. add ("content-encoding", "gzip"); response. statusdescription = "not modified";} else {response. write (item. content); setclientcaching (response, datetime. now); }}// end else href} private void setclientcaching (httpresponse Resp Onse, datetime lastmodified) {response. cache. setetag (lastmodified. ticks. tostring (); response. cache. setlastmodified (lastmodified); // public to specify that the response can be cached by the client and the shared (proxy. Response. cache. setcacheability (httpcacheability. Public); // This is the maximum absolute time that allows a document to exist before it is deemed as obsolete. Response. cache. setmaxage (New timespan (7, 0, 0, 0); // set the cache expiration time from the absolute time to the adjustable time response. cache. setslidingexpiration (true );}
Running Effect
Code: http://download.csdn.net/detail/dz45693/4272920