【问题标题】:Blazor Webassembly Brotli and Gzip compression on IISIIS 上的 Blazor Webassembly Brotli 和 Gzip 压缩
【发布时间】:2021-12-16 02:24:28
【问题描述】:

作为 Blazor 开发人员,我认为没有关于此主题的好的文档。 我上传了一个非常简单的 Blazor webassembly(v5) 网站,只有 1 个页面,现在在浏览器中加载需要 20 多秒。我尝试使用基于thisMicrosoft doc 的压缩,并使用了文档建议的web.config 文件。 我还安装了 URL 重写模块 Microsoft IIS Compression、StaticCompresstionModule 和 DynamicCopressionModule 并尝试修改 web.config 的以下行,但它根本不起作用:

web.config:

...
 <httpCompression  directory="%SystemDrive%\inetpub\temp\IIS Temporary Compressed Files">
    <scheme name="br" dll="%ProgramFiles%\IIS\IIS Compression\iisbrotli.dll" />
     <scheme name="gzip" dll="%ProgramFiles%\IIS\IIS Compression\iiszlib.dll" />
....

结果仍然没有压缩,这是我浏览器的开发者工具截图:

这对于使用 Blazor 作为前端的每个人来说都是一个问题。 谁能提供一步一步的工作答案?

更新:这是我的最终 web.config(不起作用):

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <system.webServer>
    <staticContent>
      <remove fileExtension=".blat" />
      <remove fileExtension=".dat" />
      <remove fileExtension=".dll" />
      <remove fileExtension=".json" />
      <remove fileExtension=".wasm" />
      <remove fileExtension=".woff" />
      <remove fileExtension=".woff2" />
      <mimeMap fileExtension=".blat" mimeType="application/octet-stream" />
      <mimeMap fileExtension=".dll" mimeType="application/octet-stream" />
      <mimeMap fileExtension=".dat" mimeType="application/octet-stream" />
      <mimeMap fileExtension=".json" mimeType="application/json" />
      <mimeMap fileExtension=".wasm" mimeType="application/wasm" />
      <mimeMap fileExtension=".woff" mimeType="application/font-woff" />
      <mimeMap fileExtension=".woff2" mimeType="application/font-woff" />


 

      <mimeMap fileExtension=".js.gz" mimeType="application/javascript" />
      <mimeMap fileExtension=".dat.gz" mimeType="application/octet-stream" />
      <mimeMap fileExtension=".dll.gz" mimeType="application/octet-stream" />
      <mimeMap fileExtension=".json.gz" mimeType="application/json" />
      <mimeMap fileExtension=".wasm.gz" mimeType="application/wasm" />
      <mimeMap fileExtension=".blat.gz" mimeType="application/octet-stream" />
      <mimeMap fileExtension=".html.gz" mimeType="text/html" />
      <mimeMap fileExtension=".css.gz" mimeType="text/css" />
      <mimeMap fileExtension=".ico.gz" mimeType="image/x-icon" />
      <mimeMap fileExtension=".svg.gz" mimeType="image/svg+xml" />
      <mimeMap fileExtension=".js.br" mimeType="application/javascript" />
      <mimeMap fileExtension=".dat.br" mimeType="application/octet-stream" />
      <mimeMap fileExtension=".dll.br" mimeType="application/octet-stream" />
      <mimeMap fileExtension=".json.br" mimeType="application/json" />
      <mimeMap fileExtension=".wasm.br" mimeType="application/wasm" />
      <mimeMap fileExtension=".blat.br" mimeType="application/octet-stream" />
      <mimeMap fileExtension=".html.br" mimeType="text/html" />
      <mimeMap fileExtension=".css.br" mimeType="text/css" />
      <mimeMap fileExtension=".ico.br" mimeType="image/x-icon" />
      <mimeMap fileExtension=".svg.br" mimeType="image/svg+xml" />
    </staticContent>
 <rewrite>
      <outboundRules rewriteBeforeCache="true">
        <rule name="Add Vary Accept-Encoding" preCondition="PreCompressedFile" enabled="true">
          <match serverVariable="RESPONSE_Vary" pattern=".*" />
          <action type="Rewrite" value="Accept-Encoding" />
        </rule>
        <rule name="Add Encoding Brotli" preCondition="PreCompressedBrotli" enabled="true" stopProcessing="true">
          <match serverVariable="RESPONSE_Content_Encoding" pattern=".*" />
          <action type="Rewrite" value="br" />
        </rule>
        <rule name="Add Encoding Gzip" preCondition="PreCompressedGzip" enabled="true" stopProcessing="true">
          <match serverVariable="RESPONSE_Content_Encoding" pattern=".*" />
          <action type="Rewrite" value="gzip" />
        </rule>
        <preConditions>
          <preCondition name="PreCompressedFile">
            <add input="{HTTP_URL}" pattern="\.(gz|br)$" />
          </preCondition>
            <preCondition name="PreCompressedBrotli">
            <add input="{HTTP_URL}" pattern="\.br$" />
          </preCondition>
          <preCondition name="PreCompressedGzip">
            <add input="{HTTP_URL}" pattern="\.gz$" />
          </preCondition>
        </preConditions>
      </outboundRules>
      <rules>
        <rule name="Serve subdir">
          <match url=".*" />
          <action type="Rewrite" url="wwwroot\{R:0}" />
        </rule>
        <rule name="Rewrite brotli file" stopProcessing="true">
          <match url="(.*)"/>
          <conditions>
            <add input="{HTTP_ACCEPT_ENCODING}" pattern="br" />
            <add input="{REQUEST_FILENAME}" pattern="\.(js|dat|dll|json|wasm|blat|htm|html|css|ico|svg)$" />
            <add input="{REQUEST_FILENAME}.br" matchType="IsFile" />
          </conditions>
          <action type="Rewrite" url="{R:1}.br" />
        </rule>
        <rule name="Rewrite gzip file" stopProcessing="true">
          <match url="(.*)"/>
          <conditions>
            <add input="{HTTP_ACCEPT_ENCODING}" pattern="gzip" />
            <add input="{REQUEST_FILENAME}" pattern="\.(js|dat|dll|json|wasm|blat|htm|html|css|ico|svg)$" />
            <add input="{REQUEST_FILENAME}.gz" matchType="IsFile" />
          </conditions>
          <action type="Rewrite" url="{R:1}.gz" />
        </rule>
        <rule name="SPA fallback routing" stopProcessing="true">
          <match url=".*" />
          <conditions logicalGrouping="MatchAll">
            <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
          </conditions>
          <action type="Rewrite" url="wwwroot\" />
        </rule>
      </rules>
    </rewrite>
    <httpCompression>
      <dynamicTypes>
        <add mimeType="application/octet-stream" enabled="true" />
        <add mimeType="application/json" enabled="true" />
        <add mimeType="application/wasm" enabled="true" />
        <add mimeType="application/font-woff" enabled="true" />
      </dynamicTypes>
      <staticTypes>
        <add mimeType="application/octet-stream" enabled="true" />
        <add mimeType="application/json" enabled="true" />
        <add mimeType="application/wasm" enabled="true" />
        <add mimeType="application/font-woff" enabled="true" />
      </staticTypes>
    </httpCompression>
  </system.webServer>
</configuration>

【问题讨论】:

  • 部署后第一次访问或者闲置一段时间后,确实需要一段时间才能得到响应。 IIS需要创建一个进程为应用程序分配CPU资源和内存空间,让应用程序先在服务器上运行,然后将css、脚本文件等资源缓存到客户端。
  • 为什么你认为它没有被压缩?您的屏幕截图显示 24MB 资源的 10MB 传输大小 - 因此某些内容被压缩。您是否检查了其中一个 dll 文件的请求/响应,以查看您的浏览器说它可以接受什么压缩以及服务器响应了什么?也许分享一下,因为它比单独的概述更有用。
  • @MisterMagoo 因为我已经停止了这张照片的下载,而且文档说如果 dll 被压缩,你应该在浏览器的内容编码中看到“br”或“gzip”。
  • 为什么首先加载需要 20 秒?你想建立什么样的网站?您是否尝试过将您的应用拆分为延迟加载的程序集?
  • 检查浏览器的初始 HTTP 请求标头,是否将 Accept-encoding 设置为接受 br、gzip 等?

标签: iis compression blazor gzip brotli


【解决方案1】:

TL;DR

您很可能在 IIS 中遇到了站点配置错误的问题。要确认它,请检查您的站点配置是否会在Configuration Editor 中加载:

  1. 选择您的网站
  2. 双击Configuration Editor
  3. 检查这是否会给您带来错误

然后通过更新站点配置来解决错误并一一消除它们。

挑战在于很难提供一个通用的示例,因为它取决于许多未知因素:操作系统版本、IIS 版本、现有配置等。

详细步骤

有两种方法可以做到这一点:使用 IIS 压缩方案提供程序(选项 1)或使用重写(选项 2)。

先决条件

这是我用于设置的内容:

  • Windows 10 专业版
  • IIS 10.0 版
  • 已安装URL Rewrite Module
  • Dynamic Content CompressionStatic Content Compression IIS 功能 are enabledTurn Windows features on or off 对话框中
  • 使用 .NET5.0 创建的新 Blazor 应用 dotnet new blazorwasm

选项 1:使用 IIS 压缩方案提供程序添加压缩

  1. InstallMicrosoft IIS 压缩

  2. 更新您的网站配置

    注意:似乎建议的configuration 在默认情况下在 IIS 中不起作用。我不得不从中删除一些条目,因为它们与 IIS 机器配置中的条目重复。

这是一个最终对我有用的配置:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <system.webServer>
    <staticContent>
      <remove fileExtension=".blat" />
      <remove fileExtension=".dat" />
      <remove fileExtension=".dll" />
      <remove fileExtension=".json" />
      <remove fileExtension=".wasm" />
      <remove fileExtension=".woff" />
      <remove fileExtension=".woff2" />
      <mimeMap fileExtension=".blat" mimeType="application/octet-stream" />
      <mimeMap fileExtension=".dll" mimeType="application/octet-stream" />
      <mimeMap fileExtension=".dat" mimeType="application/octet-stream" />
      <mimeMap fileExtension=".json" mimeType="application/json" />
      <mimeMap fileExtension=".wasm" mimeType="application/wasm" />
      <mimeMap fileExtension=".woff" mimeType="application/font-woff" />
      <mimeMap fileExtension=".woff2" mimeType="application/font-woff" />
    </staticContent>
    <rewrite>
      <rules>
        <rule name="Serve subdir">
          <match url=".*" />
          <action type="Rewrite" url="wwwroot\{R:0}" />
        </rule>
        <rule name="SPA fallback routing" stopProcessing="true">
          <match url=".*" />
          <conditions logicalGrouping="MatchAll">
            <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
          </conditions>
          <action type="Rewrite" url="wwwroot\" />
        </rule>
      </rules>
    </rewrite>
    <urlCompression doStaticCompression="true" doDynamicCompression="true" />
    <httpCompression>
      <dynamicTypes>
        <add mimeType="application/octet-stream" enabled="true" />
        <add mimeType="application/json" enabled="true" />
        <add mimeType="application/wasm" enabled="true" />
        <add mimeType="application/font-woff" enabled="true" />
      </dynamicTypes>
      <staticTypes>
        <add mimeType="application/octet-stream" enabled="true" />
        <add mimeType="application/json" enabled="true" />
        <add mimeType="application/wasm" enabled="true" />
        <add mimeType="application/font-woff" enabled="true" />
      </staticTypes>
    </httpCompression>
  </system.webServer>
</configuration>

选项 2:使用重写添加压缩

  1. 下载this article中提供的web.config

  2. 完成与上述类似的活动,消除所有web.config 不一致。

    注意:在我的例子中,由于 IIS 报告了重复,我不得不为 .wasm 删除 mimeMap

    ...
    <staticContent>
      <remove fileExtension=".dll" />
      <remove fileExtension=".json" />
      <remove fileExtension=".woff" />
      <remove fileExtension=".woff2" />
      <remove fileExtension=".wasm" /> <!-- added this line -->
      <mimeMap fileExtension=".json" mimeType="application/json" />
      ...
    

结果

因此,对于任一选项,您应该能够看到以下内容。

  • 用于 HTTP

  • 对于 HTTPs

【讨论】:

  • 谢谢我明天会检查你的答案。如果赏金到期,我将添加另一个赏金并将其提供给您。
  • 很遗憾这没有用。
  • 有趣。因此,如果您选择选项 1,您可以打开配置编辑器吗?当你这样做时,你可以切换到system.webServer/httpCompression 部分吗?如果可以,请检查以下属性:(Collection) 应包含 brgzip 方案,dynamicTypesststicTypes 应列出正确的 mimeTypes(例如 application/octet-stream 等)。
  • 还有一点,有时 IIS 需要完全重启才能应用配置。您可以通过运行 iisreset.exe /restart 在管理员命令提示符下执行此操作。
  • 它没有 httpCompression 部分
【解决方案2】:

首先,您需要遵循 Sasha 提到的先决条件步骤。 在服务器上已经设置压缩后,使用选项 2 中提到的 web.config 修改 web.config。

不要忘记在你的 web.config 中添加这一行

<remove fileExtension=".wasm" />

在添加上述内容之前,我的应用在加载时出错。

之后,您可以清除浏览器缓存和历史记录以进行测试。

【讨论】: