如何在自托管环境中对ASP.NET Core中的静态内容进行gzip

时间:2015-03-19 23:18:15

标签: asp.net-core asp.net-core-mvc

使用自托管环境发布ASP.NET Core网站时,是否有提供gzip静态功能的方法?

4 个答案:

答案 0 :(得分:14)

[编辑2016-11-13]

还有另一种方法来提供替换步骤2和3的gzip压缩文件。这基本上是完全相同的想法,但有一个nuget package可以随时为您提供所有功能。它基本上检查是否匹配所请求的.gz.br文件。如果存在,则返回适当的标题。它确实验证请求是否具有相应算法的标头。如果你想自己编译它的Github代码是here

在官方repository中还有一个问题需要支持,因此我真的希望微软能够使用标准插件来实现这一目标,因为现在使用它是相当普遍和合乎逻辑的。

我认为我找到了最优化的压缩内容服务方式。主要思想是预压缩文件,因为默认的ASP.NET 5方法是使用gulp来构建js,所以这很容易做到:

1.添加gulp步骤以gzip捆绑的库:

gulp.task("buildApplication:js", function () {
    return gulp.src(...)
        ...
        .pipe(gzip()) 
        ...
});

这将在您的包文件夹中生成类似libraries.js.gz的内容

2.在cshtml文件中引用libraries.js.gz而不是libraries.js

3.修改静态文件处理程序以修复返回的标题

我们需要添加Content-Encoding并将Content-Type从默认application/x-gzip更改为application/javascript,因为并非所有浏览器都足够聪明,可以从x-gzip正确读取js

app.UseStaticFiles(new StaticFileOptions
    {
        OnPrepareResponse = context =>
        {  
            if (headers.ContentType.MediaType == "application/x-gzip")
            {
                if (context.File.Name.EndsWith("js.gz"))
                {
                    headers.ContentType = new MediaTypeHeaderValue("application/javascript");
                }
                else if (context.File.Name.EndsWith("css.gz"))
                {
                    headers.ContentType = new MediaTypeHeaderValue("text/css");
                }

                context.Context.Response.Headers.Add("Content-Encoding", "gzip");
            }
        }
    });

现在所有没有CPU周期浪费到一直gzip相同的内容,这是提供文件的最佳性能。为了进一步改善它,所有js必须在gzipping之前进行整理和缩小。另一个升级是将相同OnPrepareResponse中的CacheControl max age设置为缓存一年,并在cshtml中添加asp-append-version="true"

P.S。如果您将在IIS后面托管,您可能需要关闭js和css的静态压缩而不是双重压缩,我不确定它在这种情况下会如何表现。

答案 1 :(得分:8)

这是来自Ilyas的方法3 的固定版本,该解决方案适用于ASP.NET Core 1 RTM,它提供预先压缩的javascript文件:

app.UseStaticFiles(new StaticFileOptions
        {
            OnPrepareResponse = context =>
            {
                IHeaderDictionary headers = context.Context.Response.Headers;
                string contentType = headers["Content-Type"];
                if (contentType == "application/x-gzip")
                {
                    if (context.File.Name.EndsWith("js.gz"))
                    {
                        contentType = "application/javascript";
                    }
                    else if (context.File.Name.EndsWith("css.gz"))
                    {
                        contentType = "text/css";
                    }
                    headers.Add("Content-Encoding", "gzip");
                    headers["Content-Type"] = contentType;
                }
            }
        });

答案 2 :(得分:5)

@ Ilya的答案非常好但如果您不使用Gulp,这里有两种选择。

ASP.NET核心响应压缩中间件

在ASP.NET Core BasicMiddlware存储库中,您可以找到(在撰写本文时)Response Compression Middleware的拉取请求(PR)。您可以下载代码并将其添加到IApplicationBuilder,如此(在撰写本文时):

public void Configure(IApplicationBuilder app)
{
    app.UseResponseCompression(
        new ResponseCompressionOptions()
        {
            MimeTypes = new string[] { "text/plain" }
        });

    // ...Omitted
}

IIS(Internet Information Server)

IIS(Internet Information Server)具有本机静态文件模块,该模块独立于您在本文中了解到的ASP.NET静态文件中间件组件。由于ASP.NET模块在IIS本机模块之前运行,因此它们优先于IIS本机模块。从ASP.NET Beta 7开始,IIS主机已更改,因此ASP.NET未处理的请求将返回空404响应,而不是允许IIS本机模块运行。要选择运行IIS本机模块,请将以下调用添加到Startup.Configure。

的末尾
public void Configure(IApplicationBuilder app)
{
    // ...Omitted

    // Enable the IIS native module to run after the ASP.NET middleware components.
    // This call should be placed at the end of your Startup.Configure method so that
    // it doesn't interfere with other middleware functionality.
    app.RunIISPipeline();
}

然后在你的Web.config中使用以下设置打开GZIP压缩(注意我包含了一些额外的行来压缩像.json文件这样的东西,否则它们将被IIS解压缩):

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.webServer>
    <!-- httpCompression - GZip compress static file content. Overrides the server default which only compresses static 
                           files over 2700 bytes. See http://zoompf.com/blog/2012/02/lose-the-wait-http-compression and
                           http://www.iis.net/configreference/system.webserver/httpcompression -->
    <!-- minFileSizeForComp - The minimum file size to compress. -->
    <httpCompression directory="%SystemDrive%\inetpub\temp\IIS Temporary Compressed Files" minFileSizeForComp="1024">
      <scheme name="gzip" dll="%Windir%\system32\inetsrv\gzip.dll" />
      <dynamicTypes>
        <add mimeType="text/*" enabled="true" />
        <add mimeType="message/*" enabled="true" />
        <add mimeType="application/x-javascript" enabled="true" />

        <!-- Compress XML files -->
        <add mimeType="application/xml" enabled="true" />
        <!-- Compress JavaScript files -->
        <add mimeType="application/javascript" enabled="true" />
        <!-- Compress JSON files -->
        <add mimeType="application/json" enabled="true" />
        <!-- Compress SVG files -->
        <add mimeType="image/svg+xml" enabled="true" />
        <!-- Compress RSS feeds -->
        <add mimeType="application/rss+xml" enabled="true" />
        <!-- Compress Atom feeds -->
        <add mimeType="application/atom+xml" enabled="true" />

        <add mimeType="*/*" enabled="false" />
      </dynamicTypes>
      <staticTypes>
        <add mimeType="text/*" enabled="true" />
        <add mimeType="message/*" enabled="true" />
        <add mimeType="application/x-javascript" enabled="true" />
        <add mimeType="application/atom+xml" enabled="true" />
        <add mimeType="application/xaml+xml" enabled="true" />

        <!-- Compress ICO icon files (Note that most .ico files are uncompressed but there are some that can contain 
             PNG compressed images. If you are doing this, remove this line). -->
        <add mimeType="image/x-icon" enabled="true" />
        <!-- Compress XML files -->
        <add mimeType="application/xml" enabled="true" />
        <add mimeType="application/xml; charset=UTF-8" enabled="true" />
        <!-- Compress JavaScript files -->
        <add mimeType="application/javascript" enabled="true" />
        <!-- Compress JSON files -->
        <add mimeType="application/json" enabled="true" />
        <!-- Compress SVG files -->
        <add mimeType="image/svg+xml" enabled="true" />
        <!-- Compress EOT font files -->
        <add mimeType="application/vnd.ms-fontobject" enabled="true" />
        <!-- Compress TTF font files - application/font-ttf will probably be the new correct MIME type. IIS still uses application/x-font-ttf. -->
        <!--<add mimeType="application/font-ttf" enabled="true" />-->
        <add mimeType="application/x-font-ttf" enabled="true" />
        <!-- Compress OTF font files - application/font-opentype will probably be the new correct MIME type. IIS still uses font/otf. -->
        <!--<add mimeType="application/font-opentype" enabled="true" />-->
        <add mimeType="font/otf" enabled="true" />
        <!-- Compress RSS feeds -->
        <add mimeType="application/rss+xml" enabled="true" />
        <add mimeType="application/rss+xml; charset=UTF-8" enabled="true" />

        <add mimeType="*/*" enabled="false" />
      </staticTypes>
    </httpCompression>
    <!-- Enable gzip and deflate HTTP compression. See http://www.iis.net/configreference/system.webserver/urlcompression
         doDynamicCompression - enables or disables dynamic content compression at the site, application, or folder level.
         doStaticCompression - enables or disables static content compression at the site, application, or folder level. 
         dynamicCompressionBeforeCache - specifies whether IIS will dynamically compress content that has not been cached. 
                                         When the dynamicCompressionBeforeCache attribute is true, IIS dynamically compresses 
                                         the response the first time a request is made and queues the content for compression. 
                                         Subsequent requests are served dynamically until the compressed response has been 
                                         added to the cache directory. Once the compressed response is added to the cache 
                                         directory, the cached response is sent to clients for subsequent requests. When 
                                         dynamicCompressionBeforeCache is false, IIS returns the uncompressed response until 
                                         the compressed response has been added to the cache directory. 
                                         Note: This is set to false in Debug mode to enable Browser Link to work when debugging.
                                         The value is set to true in Release mode (See web.Release.config).-->
    <urlCompression doDynamicCompression="true" doStaticCompression="true" dynamicCompressionBeforeCache="false" />
  </system.webServer>
</configuration>

答案 3 :(得分:1)

如果客户端支持,可以实现压缩响应内容的动作过滤器。

这是MVC5的一个例子。您应该能够修改它以使用MVC 6:

http://www.erwinvandervalk.net/2015/02/enabling-gzip-compression-in-webapi-and.html