大学IT网 - 最懂大学生的IT学习网站! QQ资料交流群:367606806
当前位置:大学IT网 > ASP.NET技巧 > ASP.NET网站性能优化:自动压缩CSS、JS

ASP.NET网站性能优化:自动压缩CSS、JS

关键词:ASP.NET网站性能优化压缩CSSJS  阅读(574) 赞(31)

[摘要]在开发ASP.NET网站时编写的js、css发布的时候,往往需要进行压缩,以减少文件大小,减轻服务器的负担。本文主要讲解如何让服务器自动对CSS、JS文件进行压缩。

在开发中编写的js、css发布的时候,往往需要进行压缩,以减少文件大小,减轻服务器的负担。这就得每次发版本的时候,对js、js进行压缩,然后再发布。有没有什么办法,让代码到了服务器上边,它自己进行压缩呢?

既然我这么说了,那肯定是有办法的啦,~_~。

有两种办法:

第一种,在css、js请求到来的时候读取一下相对应的文件,进行压缩后返回。此方法可以通过在Global.asax的Application_BeginRequest的事件中,进行处理,也可以在web.config中注册一个httpHandler进行处理。

第二种是在程序启动的时候,对全部css以及js进行压缩,压缩之后,每次访问都使用压缩后的文件即可。这种办法可以将js全部压缩到一个文件夹里边,不过需要注意一下文件的顺序。

压缩使用的是雅虎的压缩组件: Yahoo.Yui.Compressor.dll

由于第一种办法没能实现js压缩到一个文件,所以这里采用的是第二种方案。

压缩方法比较简单,首先引用Yahoo.Yui.Compressor.dll和EcmaScript.NET.modified.dll

以下代码实现压缩js:

//文件内容
string strContent = File.ReadAllText(jsPath, Encoding.UTF8);
//初始化
var js = new JavaScriptCompressor(strContent, false, Encoding.UTF8,                                              System.Globalization.CultureInfo.CurrentCulture);
//压缩该js
strContent = js.Compress();
File.WriteAllText(jsPath, strContent, Encoding.UTF8);
下面是实现CSS压缩的代码:
string strContent = File.ReadAllText(cssPath, Encoding.UTF8)
//进行压缩
strContent = CssCompressor.Compress(strContent);
File.WriteAllText(cssPath, strContent, Encoding.UTF8);

可能在js/css文件夹里边有些js/css文件可能不需要引入,所以也就可以不进行压缩,也有些文件本来就已经压缩过的(后缀名为.min.js或.min.css),不需要压缩,所以考虑这些情况之后,代码如下:

//文件内容
string strContent = File.ReadAllText(jsPath, Encoding.UTF8);
//若该文件为js文件, info为文件对象
if (info.Extension.ToLower() == ".js")
{
    if (!info.FullName.ToLower().EndsWith(".no.js") )
    {
        //若该文件已经压缩则不进行压缩
        if (!info.FullName.ToLower().EndsWith(".min.js"))
        {
            //初始化
            var js = new JavaScriptCompressor(strContent, false, Encoding.UTF8,                                              System.Globalization.CultureInfo.CurrentCulture);
            //压缩该js
            strContent = js.Compress();
            File.WriteAllText(jsPath, strContent, Encoding.UTF8);
 
        }
        //文件之间进行换行
        jsContent += " \n\n " + strContent;//整理成一个js文件使用
    }
}
else if (info.Extension.ToLower() == ".css") //该文件为css文件
{
    //若为不需要的css则不进行压缩
    if (!info.FullName.ToLower().EndsWith(".no.css") )
    {
        //若已经进行过压缩,则不再进行压缩
        if (!info.FullName.ToLower().EndsWith(".min.css"))
        {
            //进行压缩
            strContent = CssCompressor.Compress(strContent);
            File.WriteAllText(cssPath, strContent, Encoding.UTF8);
        }
    }
}

完整的压缩方法为:

/// <summary>
    /// 功能:压缩特定路径下的js、css文件
    /// 执行过程:
    /// (1)、获取文件夹底下的所有js以及css文件
    /// (2)、将文件压缩后保存成.au.min.js或auto.min.css格式
    /// 
    /// 注意:若是js文件中的js有顺序,需要整理一下顺序再压缩,
    /// 因为全部压缩成功后,全部js会放到一个js文件中
    /// 
    /// </summary>
    /// <param name="filePath">文件夹路径</param>
    /// <param name="jsContent">将文件夹下的所有js压缩后的内容</param>
    /// <returns></returns>
    private bool CompressJsAndCss(string filePath, ref string jsContent)
    {
        bool ret = true;
        //目录不存在
        if (!Directory.Exists(filePath))
        {
            return false;
        }
 
        //获取该文件夹下所有js或者css文件
        var fileInfos = new List<FileInfo>();
        GetJsAndCssFileList(new DirectoryInfo(filePath), ref fileInfos);
        foreach (FileInfo info in fileInfos)
        {
            try
            {
                //压缩文件保存路径
                var newFile = new FileInfo(info.FullName.Replace(info.Name, info.Name.Replace(info.Extension, ".auto.min" + info.Extension)));
 
                //文件内容
                string strContent = File.ReadAllText(info.FullName, Encoding.UTF8);
 
                //若该文件为js文件
                if (info.Extension.ToLower() == ".js")
                {
                    if (!info.FullName.ToLower().EndsWith(".no.js") )
                    {
                        //若该文件已经压缩则不进行压缩
                        if (!info.FullName.ToLower().EndsWith(".min.js"))
                        {
                            //初始化
                            var js = new JavaScriptCompressor(strContent, false, Encoding.UTF8,
                                                             System.Globalization.CultureInfo.CurrentCulture);
                            //压缩该js
                            strContent = js.Compress();
                            File.WriteAllText(newFile.FullName, strContent, Encoding.UTF8);
 
                        }
                        //文件之间进行换行
                        jsContent += " \n\n " + strContent;
                    }
                }
                else if (info.Extension.ToLower() == ".css") //该文件为css文件
                {
                    //若为不需要的css则不进行压缩
                    if (!info.FullName.ToLower().EndsWith(".no.css") )
                    {
                        //若已经进行过压缩,则不再进行压缩
                        if (!info.FullName.ToLower().EndsWith(".min.css"))
                        {
                            //进行压缩
                            strContent = CssCompressor.Compress(strContent);
                            File.WriteAllText(newFile.FullName, strContent, Encoding.UTF8);
                        }
                    }
                }
            }
            catch (Exception e)
            {
                ret = false;
                continue;
            }
        }
        return ret;
    }
 
/// <summary>
    /// 功能:获取CSS以及JS文件列表    /// 
    /// </summary>
    /// <param name="dir">目标目录</param>
    /// <param name="fileList">文件列表</param>
    private void GetJsAndCssFileList(DirectoryInfo dir, ref List<FileInfo> fileList)
    {
        FileInfo[] files = dir.GetFiles("*.js");
        fileList.AddRange(files);
        files = dir.GetFiles("*.css");
        fileList.AddRange(files);
        DirectoryInfo[] dirs = dir.GetDirectories();
        if (dirs.Length > 0)
        {
            foreach (DirectoryInfo r in dirs)
            {
                GetJsAndCssFileList(r, ref fileList);
            }
        }
}
 
压缩方法实现之后,咱们就可以在Global.asax的程序启动事件中对,js、css文件进行压缩:
 
void Application_Start(object sender, EventArgs e)
{
    //进行压缩
    AutoCompress compress = new AutoCompress();
    compress.Compress();
}
 
压缩了之后,在页面引入css、js的方法也要更改以下:
 
来看实现方法:(主要看GetCss和GetJs两个方法,这两个方法实现了获取压缩后的文件链接,只需要将这两个方法的返回值输出到页面的head标签中即可)
 
/// <summary>
    /// 功能:获取页面CSS样式(在Global中会对css进行压缩)
    ///
    /// </summary>
    /// <param name="isGetMin">是否获取压缩后的样式</param>
    /// <returns></returns>
    public string GetCss(bool isGetMin)
    {
        return GetCssFromStyleFolder(isGetMin);
    }
 
    /// <summary>
    /// 功能:获取页面JS链接(在Global中会对js进行压缩)
    /// </summary>
    /// <param name="isGetMin">是否获取压缩后的Js链接</param>
    /// <returns></returns>
    public string GetJs(bool isGetMin)
    {
        string ret = string.Empty;
        HttpContext ctx = HttpContext.Current;
 
        bool isUseGlobal = false;//是否使用了全局的缓存
        if (IsCompressAllSuccess && isGetMin)
        {
            if (File.Exists(ctx.Server.MapPath("./min/") + "all.min.js"))
            {
                ret = "<script src=\"./min/all.min.js" +
                      "\" type=\"text/javascript\"></script>";
                isUseGlobal = true;
            }
        }
 
        //没有使用全局的缓存
        if (!isUseGlobal)
        {
            ret = GetJsFromStyleFolder(isGetMin);
        }
        return ret;
    }
 
    /// <summary>
    /// 功能:根据配置的使用的样式返回该样式列表
    /// 执行过程:
    /// (1)、判断系统是否配置了样式主题,若没有配置则使用默认样式
    /// (2)、获取公共样式和配置的样式
    ///
    /// </summary>
    /// <returns></returns>
    private string GetCssFromStyleFolder(bool isGetMin)
    {
        if (!isGetMin)
            return GetStyleLink("Css");
        return GetMinStylink("Css");
    }
 
 
    /// <summary>
    /// 功能:获取js文件链接
    /// </summary>
    /// <returns></returns>
    private string GetJsFromStyleFolder(bool isGetMin)
    {
        string ret = string.Empty;
        //
        if (Directory.Exists(HttpContext.Current.Server.MapPath("./Js")))
        {
            var files = Directory.GetFiles(HttpContext.Current.Server.MapPath("./Js"), "*.js");
            if (files.Length > 0)
            {
                foreach (var file in files)
                {
                    if (!string.IsNullOrEmpty(file))
                    {
                        if (file.EndsWith(".no.js") || (file.EndsWith(".auto.min.js")))
                        {
                            continue;
                        }
 
                        //原文件名
                        string fileName = Path.GetFileName(file);
                        if (!string.IsNullOrEmpty(fileName) && isGetMin)
                        {
                            //压缩后的文件名
                            string newFileName = fileName.Replace(".js", ".auto.min.js");
 
                            //压缩后文件全路径
                    nbsp;       string minFilePath =
                            HttpContext.Current.Server.MapPath("../Js/") + newFileName;
 
                            //是否存在压缩后的文件
                            if (File.Exists(minFilePath))
                            {
                                //存在使用压缩后的文件
                                ret += "<script src=\"./js/" + newFileName +
                                    "\" type=\"text/javascript\"></script> \n";
                                continue;
                            }
 
                            //没有压缩文件,使用源文件
                            ret += "<script src=\"./js/" + fileName +
                                    "\" type=\"text/javascript\"></script> \n";
                        }
                        else
                        {
                            //使用源文件
                            ret += "<script src=\"./js/" + fileName +
                                    "\" type=\"text/javascript\"></script> \n";
                        }
                    }
                }
            }
        }
        return ret;
    }
 
    /// <summary>
    /// 功能:获取样式文件夹下的所有样式文件并返回该样式的链接字符串
    ///
    /// 执行过程:
    /// (1)、获取该样式文件夹所有css文件
    /// (2)、组装成link链接返回
    /// 
    /// </summary>
    /// <param name="styleName">样式文件夹</param>
    /// <returns></returns>
    private string GetStyleLink(string styleName)
    {
        string ret = string.Empty;
        //配置的样式是否存在
        if (Directory.Exists(HttpContext.Current.Server.MapPath("./Css")))
        {
            var files = Directory.GetFiles(HttpContext.Current.Server.MapPath("./Css"), "*.css");
            if (files.Length > 0)
            {
                //不取自动压缩出来的文件
                ret = files.Where(file => !file.EndsWith(".auto.min.css")).ToList().Aggregate(string.Empty,
                                      (current, fileName) =>
                                      current +
                                      string.Format(
                                          "<link href=\"./Css/{0}\" rel=\"stylesheet\" type=\"text/css\" /> \n ",
                                           Path.GetFileName(fileName)));
            }
        }
        return ret;
    }
 
    /// <summary>
    /// 功能:获取该样式的所有样式链接(若有压缩后的文件则直接采用压缩后的文件)
    /// 执行过程:
    /// (1)、获取所有CSS文件
    /// (2)、循环查找文件,若找到该文件的压缩后的文件则使用压缩后的文件
    /// (3)、组装好样式链接返回
    ///
    /// </summary>
    /// <param name="styleName">样式文件夹</param>
    /// <returns></returns>
    private string GetMinStylink(string styleName)
p align="left" style="margin-top:0px; margin-bottom:5px; padding-top:0px; padding-bottom:0px; border:0px; list-style:none; word-wrap:normal; word-break:normal; line-height:21px; color:rgb(70,70,70); font-family:simsun; font-size:14px; background-color:rgb(248,248,248)">     {

        string ret = string.Empty;
        //配置的样式是否存在
        if (Directory.Exists(HttpContext.Current.Server.MapPath("./Css")))
        {
            var files = Directory.GetFiles(HttpContext.Current.Server.MapPath("./Css"), "*.css");
            if (files.Length > 0)
            {
                foreach (var file in files)
                {
                    if (file != null)
                    {
                        if (Path.GetFileName(file).ToLower().EndsWith(".auto.min.css"))
                        {
                            continue;
                        }
 
                        if (!string.IsNullOrEmpty(file))
                        {
                            //原文件名
                            string fileName = Path.GetFileName(file);
                            if (!string.IsNullOrEmpty(fileName))
                            {
                                //压缩后的文件名
                                string newFileName = fileName.Replace(".css", ".auto.min.css");
 
                                //是否存在压缩后的文件
                                if (files.Any(s => s.ToLower().EndsWith(newFileName.ToLower())))
                                {
                                    //存在使用压缩后的文件
                                    ret += string.Format(
                                        "<link href=\"./CSS/{0}\" rel=\"stylesheet\" type=\"text/css\" /> \n ",
                                        newFileName);
                                    continue;
                                }
 
                                //没有压缩文件,使用源文件
                                ret += string.Format(
                                    "<link href=\"./CSS/{0}\" rel=\"stylesheet\" type=\"text/css\" /> \n ",
                                    fileName);
                            }
                            else
                            {
                                //使用源文件
                                ret += string.Format(
                                    "<link href=\"./CSS/{0}\" rel=\"stylesheet\" type=\"text/css\" /> \n ",
                                    fileName);
                            }
                        }
                    }
                }
            }
        }
        return ret;
}

源码下载: http://pan.baidu.com/s/1hqsoN7A 



相关评论