zoukankan      html  css  js  c++  java
  • Web性能优化-合并js与css,减少请求

       Web性能优化已经是老生常谈的话题了, 不过笔者也一直没放在心上,主要的原因还是项目的用户量以及页面中的js,css文件就那几个,感觉没什么优化的。人总要进步的嘛,最近在被angularjs吸引着,也用了angularjs开发了一个项目,那感觉真的是谁用谁知道。

       angularjs的好处我就不在这里废话了,有兴趣的请自行度娘。背景是这样的, 在这个使用angularjs开发的项目中,由于自己的粗心导致页面打开很慢,傻了吧唧的引用了未压缩的js文件,将近1M的js啊,我还傻乎乎的建索引,优化sql,然而最终并没有什么卵用,最后还是在查请求的时候发现angularjs未压缩的文件原来那么大,然后就用了min版本的,瞬间问题解决了。话说到此优化应该就结束了吧,但作为一个有理想,有抱负的程序员咱不能太容易满足,所以决定再进行优化下,数据库和程序都已经优化了,那后面就只能来减少网络的请求数来进行优化了。再加上在学习angularjs的过程中,发现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[] { '
    ', '
    ' }, 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"));

    over

    另外,在这里推广下咱们的微信开发交流群,这里是一群致力于C#微信开发交流的平台,欢迎各位同行进行交流。也可以到群论坛与大家一起交流学习。

    微信开发交流的论坛(微兔码农说

     如有疑问加群一起交流,我需要广大屌丝小伙伴的反馈与建议,   点击这里给我发消息

  • 相关阅读:
    物联网数据卡系统源码——物联网的主要应用领域
    一张图看懂开源许可协议,开源许可证GPL、BSD、MIT、Mozilla、Apache和LGPL的区别
    memcached对key和value的限制 memcached的key最大长度和Value最大长度
    缓存技术PK:选择Memcached还是Redis?
    .Net开源框架列表
    项目管理工具Redmine各功能测试
    DBImport V3.7版本发布及软件稳定性(自动退出问题)解决过程分享
    ASP.NET Core 折腾笔记一
    发布:.NET开发人员必备的可视化调试工具(你值的拥有)
    开源发布:VS代码段快捷方式及可视化调试快速部署工具
  • 原文地址:https://www.cnblogs.com/zskbll/p/4912950.html
Copyright © 2011-2022 走看看