Web optimization-mvc js dynamic merge dynamic compression remove JS repeated references JS cache JS delayed Loading

Source: Internet
Author: User
Tags allkeys

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

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.