Web性能优化-合并js与css,减少请求

  Web性能优化已经是老生常谈的话题了, 不过笔者也一直没放在心上,主要的原因还是项目的用户量以及页面中的js,css文件就那几个,感觉没什么优化的。人总要进步的嘛。js也可以像咱们的C#一样进行模块化开发,那进行模块化的时候就需要将不同的模块放在不同的文件中,这样问题就来了,我们页面的请求数会增多,减少页面请求的方式就是将多个css文件或者js文件进行合并,参考了下别人的博客,总结下下面的方法。

  首先先讲下思路,添加一个asp.net处理程序,然后在页面中的script标签中的src的值设置为这个asp.net的处理程序的路径,并加上一个参数(css类似),如下所示:

  <link href="/Css/CombineFiles.axd?fn=index" rel="stylesheet" />

  在程序中我们可以获取到fn的值,然后根据fn的值在/css/路径下面找到对应的文件名,如fn的值为index,那么就在/css/文件夹下面找到文件名问index.txt的文件,然后打开读取文件中的内容,如下所示:

 

 

第一行表示的是当前请求的css文件,如果是js文件,则第一行为js。后面的每行则表示的为文件名。在上图中的例子中,表示的是,当前请求的是a.css,b.css,c.css合并和的文件。那我们只需要将三个文件合并后并输入就行了。下面直接上代码:

复制代码
 public class CombineFiles : IHttpHandler
    {
        #region IHttpHandler Members
        /// <summary>
        /// 缓存key值
        /// </summary>
        private const string CacheKeyFormat = "_CacheKey_{0}_";
        public bool IsReusable
        {
            get { return true; }
        }

        public void ProcessRequest(HttpContext context)
        {
            HttpRequest request = context.Request;
            HttpResponse response = context.Response;

            string cachekey = string.Empty;
            bool flag = false;//标志是否是最新合并的内容
            string fn = request.QueryString["fn"];
            if (!string.IsNullOrEmpty(fn))
            {
                cachekey = string.Format(CacheKeyFormat, fn);
                CompressCacheItem cacheItem = HttpRuntime.Cache[cachekey] as CompressCacheItem;
                if (cacheItem == null)
                {
                    flag = true;
                    string path = context.Server.MapPath("");
                    StringBuilder sb = new StringBuilder();
                    //找到请求的文本文件
                    var con = File.ReadAllText(string.Format("{0}\\{1}.txt", path, fn)).
                        Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
                    response.ContentType = con[0] == "css" ? "text/css" : "text/javascript";
                    for (int i = 1; i < con.Length; i++)
                    {
                        var filename = string.Format("{0}\\{1}.{2}", path, con[i],con[0]);
                        if (File.Exists(filename))
                        {
                            string readstr = File.ReadAllText(filename, Encoding.UTF8);
                            sb.Append(readstr);
                        }
                    }
                    cacheItem = new CompressCacheItem() { Type = con[0], Content = sb.ToString(), Expires = DateTime.Now.AddDays(30) };
                    HttpRuntime.Cache.Insert(cachekey, cacheItem, null, cacheItem.Expires, TimeSpan.Zero);
                }

                string ifModifiedSince = request.Headers["If-Modified-Since"];
                if (!string.IsNullOrEmpty(ifModifiedSince)&&cacheItem.Expires>DateTime.Parse(ifModifiedSince)&&!flag)
                {
                    response.StatusCode = (int)System.Net.HttpStatusCode.NotModified;
                    response.StatusDescription = "Not Modified";
                }
                else
                {
                    response.Write(cacheItem.Content);
                    SetClientCaching(response, cacheItem.Expires);
                }
            }

        }

        private void SetClientCaching(HttpResponse response, DateTime expires)
        {
            response.Cache.SetETag(DateTime.Now.Ticks.ToString());
            response.Cache.SetLastModified(DateTime.Now);

            //public 以指定响应能由客户端和共享(代理)缓存进行缓存。    
            response.Cache.SetCacheability(HttpCacheability.Public);

            //是允许文档在被视为陈旧之前存在的最长绝对时间。 
            response.Cache.SetMaxAge(TimeSpan.FromTicks(expires.Ticks));

            response.Cache.SetSlidingExpiration(true);
        }
        private class CompressCacheItem
        {
            /// <summary>
            /// 类型 js 或 css 
            /// </summary>
            public string Type { get; set; } // js css  
            /// <summary>
            /// 内容
            /// </summary>
            public string Content { set; get; }
            /// <summary>
            /// 过期时间
            /// </summary>
            public DateTime Expires { set; get; }
        }

        #endregion
    }
复制代码

 

此代码是在园子里一个园友的博客的基础上进行改进的。链接找不到了,在这里就不贴出来了。

 

最后呢,需要在配置文件中加入如下配置信息:

复制代码
<configuration>
    <system.web>
      <compilation debug="true" targetFramework="4.0" />
    <httpHandlers>
      <add verb="GET" path="*.axd" type="Angular.CombineFiles"/>
    </httpHandlers>
    </system.web>

</configuration>
复制代码

 

上面的代码中可以实现功能是,合并js或css,并将其缓存起来,当每次请求时都会判断当前浏览器中是否有缓存,且是否有效,如果有效则直接响应302,告诉浏览器本地缓存是可以使用的,不需要从服务器端重新下载,介绍了很多流量,并且提高了速度。假如,在项目升级的过程中,修改了js或者css,想让浏览器强制下载最新的文件时,可将HttpRuntime.Cache中的缓存移除,这样当重新请求时,会重新合并文件,并响应到客户端。

如下所示:

 HttpRuntime.Cache.Remove(string.Format("_CacheKey_{0}_","index"));

 

原文链接:http://www.cnblogs.com/zskbll/p/4912950.html


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值