Подтвердить что ты не робот

Как gzip статический контент в ASP.NET Core в среде с собственным хостом

Есть ли способ использовать gzip static cotent при использовании собственной среды хоста для публикации веб-сайта ASP.NET Core?

4b9b3361

Ответ 1

[Редактировать 2016-11-13]

Существует еще один способ обслуживания файлов gzipped, которые заменяют шаги 2 и 3. Это в основном совершенно та же идея, но есть nuget package, что делает все это для вас легко доступным. Он в основном проверяет, соответствует ли файл .gz или .br, который соответствует запрошенному. Если он существует, он возвращает его с соответствующими заголовками. Он проверяет, что запрос имеет заголовок для соответствующего алгоритма. Код Github, если вы хотите скомпилировать его самостоятельно, здесь.

Существует также проблема, чтобы поддержать это в официальном репозитории поэтому я действительно надеюсь, что Microsoft будет иметь стандартный плагин для этого, так как он довольно распространен и логичен для использования в настоящее время.


Я думаю, что нашел наиболее оптимизированный способ обслуживания сжатого контента. Основная идея состоит в том, чтобы предварительно сжать файлы, и поскольку по умолчанию ASP.NET 5 использует использование gulp для сборки js, это так же легко сделать, как это:

1. Добавьте шаг gulp для gzip связанных библиотек:

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

Это приведет к созданию чего-то типа libraries.js.gz в папке ваших пакетов

2. Обратитесь к библиотекам .js.gz вместо library.js в файл cshtml

3. Измените статический обработчик файлов, чтобы исправить возвращенные заголовки

Нам нужно добавить Content-Encoding и изменить Content-Type по умолчанию application/x-gzip на application/javascript, потому что не все браузеры достаточно умны, чтобы правильно читать js из x-gzip

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");
            }
        }
    });

Теперь у всех нет циклов процессора, чтобы тратить время на gzip одного и того же контента, и это наилучшая производительность при обслуживании файлов. Чтобы улучшить его еще больше, все js должны быть закрыты и минимизированы до gzipping. Еще одно обновление - установить максимальный возраст CacheControl в том же OnPrepareResponse для кеширования в течение одного года и добавить asp-append-version="true" в cshtml.

P.S. Если вы запустите IIS, вам может потребоваться отключить статическое сжатие js и css, чтобы не сжимать два раза, я не уверен, как он будет себя вести в этой ситуации.

Ответ 2

@Ilya Answer is very good, но вот две альтернативы, если вы не используете Gulp.

Средство промежуточного сжатия сжатия от Microsoft ASP.NET

В репозитории ASP.NET Core BasicMiddlware вы можете найти (при написании) запрос на перенос (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

Это фиксированная версия метода 3 из ответа Ilyas, который работает с RTM файлом ASP.NET Core 1, и он обслуживает предварительно сжатые файлы 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;
                }
            }
        });

Ответ 4

Вы можете реализовать фильтр действий, который сжимает содержимое ответа, если клиент поддерживает его.

Вот пример из MVC5. Вы должны иметь возможность изменить это для работы с MVC 6:

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