• HTTP压缩


    一、问题描述

    有一页面打开需要11s左右,通过谷歌DevTools工具可以看看到,服务器接口的响应是很快的(TTFB也就200ms),但是前端接收数据的时间有点长(Content Download达到了11s)。经过查看后发现接口返回的数据量达到了12M,数据量比较大。

    二、解决方案

    1、优化代码,前端不需要的数据,接口不再返回。

    2、压缩接口返回的数据

    三、压缩接口返回的数据

    我们需要在调用操作方法之后执行压缩,所以自定义一个特性,重写ActionFilterAttribute中的OnActionExecuted方法。

    using System;
    using System.IO;
    using System.IO.Compression;
    using System.Linq;
    using System.Net.Http;
    using System.Web.Http.Filters;
    
    namespace Common.WebApi.Attributes
    {
        /// <summary>
        /// 数据压缩
        /// </summary>
        public class DataZipAttribute : ActionFilterAttribute
        {/// <summary>
            /// 压缩数据
            /// </summary>
            /// <param name="actionExecutedContext"></param>
            public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
            {
                try
                {
                    DataGzip(actionExecutedContext);
                }
                catch (Exception ex)
                {
                    //日志记录
                }
    
            }       
            /// <summary>
            /// 数据压缩
            /// </summary>
            /// <param name="actionExecutedContext"></param>
            private void DataGzip(HttpActionExecutedContext actionExecutedContext)
            {
                var content = actionExecutedContext.Response.Content;
                var acceptEncoding = actionExecutedContext.Request.Headers.AcceptEncoding.Where(x => x.Value == "gzip" || x.Value == "deflate").ToList();
                if (acceptEncoding != null && acceptEncoding.Count > 0 && content != null && actionExecutedContext.Request.Method != HttpMethod.Options)
                {
                    var bytes = content.ReadAsByteArrayAsync().Result;
                    if (acceptEncoding.FirstOrDefault().Value == "gzip")
                    {
                        actionExecutedContext.Response.Content = new ByteArrayContent(CompressionHelper.GzipCompress(bytes));
                        actionExecutedContext.Response.Content.Headers.Add("Content-Encoding", "gzip");
                    }
                    else if (acceptEncoding.FirstOrDefault().Value == "deflate")
                    {
                        actionExecutedContext.Response.Content = new ByteArrayContent(CompressionHelper.DeflateCompress(bytes));
                        actionExecutedContext.Response.Content.Headers.Add("Content-encoding", "deflate");
                    }
                }
            } 
        }
    public class CompressionHelper { public static byte[] DeflateCompress(byte[] data) { if (data == null || data.Length < 1) return data; try { using (MemoryStream stream = new MemoryStream()) { using (DeflateStream gZipStream = new DeflateStream(stream, CompressionMode.Compress)) { gZipStream.Write(data, 0, data.Length); gZipStream.Close(); } return stream.ToArray(); } } catch (Exception) { return data; } } public static byte[] GzipCompress(byte[] data) { if (data == null || data.Length < 1) return data; try { using (MemoryStream stream = new MemoryStream()) { using (GZipStream gZipStream = new GZipStream(stream, CompressionMode.Compress)) { gZipStream.Write(data, 0, data.Length); gZipStream.Close(); } return stream.ToArray(); } } catch (Exception) { return data; } } } }

    在controller文件中引用

    [DataZipAttribute ]
    public class XXXController : ApiController
    {           
    }

    或者在action方法上引用

    [HttpPost]
    [DataZipAttribute]
    public HttpResponseMessage Get()
    {

    }

    或者全局引用,在Global文件中

    protected void Application_Start()
    {            
      GlobalConfiguration.Configuration.Filters.Add(new DataZipAttribute());//数据压缩
    }

    四、HTTP压缩

    HTTP压缩是指在Web服务器和浏览器间传输压缩文本内容的方法。HTTP压缩通常采用gzip或者deflate压缩算法压缩HTML、JavaScript、CSS等文件。压缩的最大好处就是降低了网络传输的数据量,从而提高客户端浏览器的访问速度。当然,同时也会增加一点服务器的负担。

    1、简述

    通过开启服务器端的HTTP压缩功能,也可以提高网站的浏览速度,对优化文件的传输也不失为一种好的方法。只是该方法会提高服务器CPU的负荷。如果服务器CPU本身负荷就大,就需要好好地斟酌了。HTTP压缩的原理是服务器接收到客户端的HTTP请求后,检查浏览器是否支持HTTP压缩,如果支持,则根据配置压缩相应的网页文件,压缩文件下载到客户端后,由浏览器解压文件后再浏览。HTTP压缩的比较通用的算法是GZIP、deflate,所以开启服务端的HTTP压缩功能一般是指开启服务器端的GZIP功能。

    2、原理

    Web服务器处理HTTP压缩的工作原理如下:
    (1)Web服务器接收到浏览器的HTTP请求后,检查浏览器是否支持HTTP压缩;在用户浏览器发送请求的HTTP头中,带有" Accept-Encoding:gzip,deflate"参数则表明支持gzip和 deflate两种压缩算法。
    var acceptEncoding = actionExecutedContext.Request.Headers.AcceptEncoding.Where(x => x.Value == "gzip" || x.Value == "deflate").ToList();            

    (2)服务器收到浏览器发送的请求之后,判断浏览器是否支持gzip,如果支持gzip,则使用gzip算法进行压缩;如果支持deflate,则使用deflate算法进行压缩。如果都不支持,则向浏览器发送未经压缩的内容。

    if (acceptEncoding.FirstOrDefault().Value == "gzip")
    {
      actionExecutedContext.Response.Content = new ByteArrayContent(CompressionHelper.GzipCompress(bytes));
      actionExecutedContext.Response.Content.Headers.Add("Content-Encoding", "gzip");
    }
    else if (acceptEncoding.FirstOrDefault().Value == "deflate")
    {
      actionExecutedContext.Response.Content
    = new ByteArrayContent(CompressionHelper.DeflateCompress(bytes));   actionExecutedContext.Response.Content.Headers.Add("Content-encoding", "deflate"); }

    (3)浏览器接收到服务器的响应之后判断内容是否被压缩,如果被压缩则解压缩显示页面内容。

    3、总结

    目前大多数浏览器是支持gzip和deflate压缩的,我们可以通过浏览器请求头的accept-encoding看看浏览器支持的压缩方案

    五、服务端开启Gzip压缩方式

     1、IIS开启Http压缩

    • 第一步,开始→管理工具→IIS

    • 第二步,选中需要开启压缩功能的站点

    • 第三步,双击压缩,勾选启用压缩

     

  • 相关阅读:
    2015hust暑假集训 0715 F
    hust2015暑假集训 0715 c a coprime
    0714c
    hdu_1019Least Common Multiple(最小公倍数)
    hdu_1576A/B(扩展欧几里得求逆元)
    hdu_5104 Primes Problem()
    hdu_3483A Very Simple Problem(C(m,n)+快速幂矩阵)
    hdu_2604Queuing(快速幂矩阵)
    hdu_3003Pupu(快速幂)
    神奇的读入读出
  • 原文地址:https://www.cnblogs.com/qtiger/p/14150951.html
Copyright © 2020-2023  润新知