• web优化之asp.net js延迟加载 js动态合并 js动态压缩


    紧接着上一篇文章js文件 合并 压缩 去掉重复引用 缓存 延迟加载来说,遗留了一个很大的问题那就是js文本怎么合并与压缩了,上一篇文章中的

       public static void AppendJsFile(this HtmlHelper htmlHelper, string jsFile, int group = 1)  
       public static MvcHtmlString RenderJsFile(this HtmlHelper htmlHelper)  

    都只限于MVC中使用,我们能不能搞一个更通用的东东了,答案是肯定的。

    先说说思路吧,其实很简单 就是我们自己接管输出流,如何接管了?在Global.asax文件中添加以下代码:

      public override void Init()
            {
                base.Init();
                this.ReleaseRequestState += new EventHandler(InstallResponseFilter);
            }
            private void InstallResponseFilter(object sender, EventArgs e)
            {
                HttpResponse response = HttpContext.Current.Response;
    
                if (response.ContentType == "text/html")
                    response.Filter = new PageFilter(response.Filter);
            }

    我还是沿用先前的项目做demo吧


    和我们平时的开发没有任何区别,但是返回结果却是如下


    我们看到js文件和js文本都合并 并且也是压缩了的。

    关键的一切还是PageFilter的功劳啊

    代码如下:

        public class PageFilter : Stream
        {
            Stream responseStream;
            long position;
            StringBuilder responseHtml;
    
            public PageFilter(Stream inputStream)
            {
                responseStream = inputStream;
                responseHtml = new StringBuilder();
            }
    
            #region Filter overrides
            public override bool CanRead
            {
                get { return true; }
            }
    
            public override bool CanSeek
            {
                get { return true; }
            }
    
            public override bool CanWrite
            {
                get { return true; }
            }
    
            public override void Close()
            {
                responseStream.Close();
            }
    
            public override void Flush()
            {
                responseStream.Flush();
            }
    
            public override long Length
            {
                get { return 0; }
            }
    
            public override long Position
            {
                get { return position; }
                set { position = value; }
            }
    
            public override long Seek(long offset, SeekOrigin origin)
            {
                return responseStream.Seek(offset, origin);
            }
    
            public override void SetLength(long length)
            {
                responseStream.SetLength(length);
            }
    
            public override int Read(byte[] buffer, int offset, int count)
            {
                return responseStream.Read(buffer, offset, count);
            }
            #endregion
    
            #region Dirty work
            public override void Write(byte[] buffer, int offset, int count)
            {
                HttpResponse response = HttpContext.Current.Response;
                string charset = response.Charset ?? "utf-8";
                string finalHtml = Encoding.GetEncoding(charset).GetString(buffer, offset, count);
                Regex eof = new Regex("</html>", RegexOptions.IgnoreCase);
    
                if (!eof.IsMatch(finalHtml))
                {
                    responseHtml.Append(finalHtml);
                }
                else
                {
                    responseHtml.Append(finalHtml);
                     finalHtml = responseHtml.ToString();
                    //js文本
                    Regex reg = new Regex("<script[^>]*>(?<content>[^<]*)</script>", RegexOptions.IgnoreCase | RegexOptions.Multiline);
                    //js引用
                    Regex regSrc = new Regex("src=\"?(?<src>[^'\">]*)\"?", RegexOptions.IgnoreCase | RegexOptions.Multiline);
                    StringBuilder jsContent = new StringBuilder();
                    List<string> jsSrc = new List<string>();
    
                    MatchCollection mc = reg.Matches(finalHtml);
    
                    if (mc.Count > 0)
                    {
                        #region 找出js部分
    
                        foreach (Match m in mc)
                        {
                            string str = m.Groups["content"].Value;
                            if (!string.IsNullOrEmpty(str))
                            {
                                jsContent.AppendLine(str);//找出js文本
                            }
                            else
                            {
                                //找出js引用
                                Match mSrc = regSrc.Match(m.Value);
                                if (mSrc != null && mSrc.Success)
                                {
                                    string temp = mSrc.Groups["src"].Value;
                                    if (!jsSrc.Contains(temp))
                                        jsSrc.Add(temp);
                                }
                            }
                        }
                        #endregion
    
                        finalHtml = reg.Replace(finalHtml, string.Empty);
    
                        #region 合并js文本和js引用
    
                        //生成新的js引用
                        string jsFileFormat = "<script type=\"text/javascript\" src=\"{0}\"></script>";
                        string jshref = string.Format(jsFileFormat, "http://localhost:58798/js.ashx?href=" + string.Join(",", jsSrc));
                        //生成新的js文本
                        string jstextFormat = "<script type=\"text/javascript\">{0}</script>";
                        //压缩js文本
                        string jsContentstr = jsContent.ToString();
                        if(!string.IsNullOrEmpty(jsContentstr))
                         jsContentstr = JavaScriptCompressor.Compress(jsContent.ToString());
                        string jsText = string.Format(jstextFormat, jsContentstr);
                        //插入新生成的js
                        int bodyindex = finalHtml.ToLower().LastIndexOf("</body>");
                        finalHtml = finalHtml.Insert(bodyindex, jshref + Environment.NewLine + jsText);
                        #endregion
                    }
                    byte[] data = Encoding.GetEncoding(charset).GetBytes(finalHtml);
                    responseStream.Write(data, 0, data.Length);
                }
    
            }
    
            #endregion
        }

    说了这么多,这里只是提供一个思想,一个js合并的思想,在真实的项目中还有很多细节需要注意啊。

  • 相关阅读:
    iframe标签用法详解
    Redis 数据备份与恢复,安全,性能测试,客户端连接,管道技术,分区(四)
    Redis 有序集合(sorted set),发布订阅,事务,脚本,连接,服务器(三)
    Redis 命令,键(key),字符串(String),哈希(Hash),列表(List),集合(Set)(二)
    Redis 安装,配置,简介,数据类型(一)
    Python2.x与3​​.x版本区别
    Python主流框架
    python面向对象( item系列,__enter__ 和__exit__,__call__方法,元类)
    Json对象与Json字符串互转(4种转换方式)
    JSON.parse和eval的区别
  • 原文地址:https://www.cnblogs.com/majiang/p/2580798.html
Copyright © 2020-2023  润新知