【问题标题】:Manually Enable Compression Using httpModule使用 httpModule 手动启用压缩
【发布时间】:2012-01-07 00:02:31
【问题描述】:

我正在尝试在我们工作 Intranet 上的网站上启用 gzip 压缩。不幸的是,我无法访问 IIS,所以我所做的任何更改都是通过 web.config 进行的。

服务器正在运行 IIS 6 和 .NET 2.0。

我通过添加一个 httpmodule 来启用压缩

public class EnableCompression : IHttpModule
{
    public void Init(HttpApplication application)
    {
        application.BeginRequest += 
            (new EventHandler(this.Application_BeginRequest));

    }

    private void Application_BeginRequest(Object source, EventArgs e)
    {
        HttpContext context = HttpContext.Current;
        context.Response.Filter = new GZipStream(context.Response.Filter, CompressionMode.Compress);
        HttpContext.Current.Response.AppendHeader("Content-encoding", "gzip");
        HttpContext.Current.Response.Cache.VaryByHeaders["Accept-encoding"] = true;
    }

}

我在 web.config 中注册了...

<system.web>
    <httpModules>
      <add name="EnableCompression" type="EnableCompression"/>
    </httpModules>
</system.web>

嗯,以上工作正常,除了 javascript 和 css 文件没有被压缩。根据我的发现,我必须将 .js 和 .css 添加到 IIS 6 中的应用程序映射中,但我当然不能这样做。

显然这可以通过 web.config 文件完成,但我不知道该怎么做。

如何为 .js 和 .css 文件启用压缩?

【问题讨论】:

  • 您的代码有两个错误。首先,您应该检查传入的请求是否设置了Accept-Encoding HTTP 标头,如果是,gzip 是否是允许的值之一(框架还支持放气,使用DeflateStream,实际上导致输出更小)。其次,VaryByHeaders 设置仅在您启用输出缓存时有效,并告诉运行时通过指定的标头改变输出缓存。在您的情况下,对于Accept-Encoding 的每个不同设置(包括无),您最终将在缓存中获得同一压缩页面的多个副本。
  • Thatnks,我一定会加入你的 cmets

标签: asp.net .net


【解决方案1】:

在IIS6中,静态代码不被托管HttpModules处理;它需要原生 ISAPI。

您可以使用的一个技巧是将 *.js 和 *.css 文件转换为动态文件。为此,您可以将它们更改为 *.aspx,并将 ContentType 设置为正确的 MIME 类型。例如:

this.Response.ContentType = "application/x-javascript";

唯一的另一个技巧是在标记文件的 Page 指令中设置 StyleSheetTheme=""。否则,运行时将坚持文档中的&lt;head&gt; 部分。您可以启用输出缓存以尽量减少对性能的影响。

我在 JS 方面写了一篇关于此的博客文章,以防万一(CSS 类似,只是 MIME 类型不同):http://www.12titans.net/p/dynamic-javascript.aspx

不幸的是,这需要更改应用程序中 JS 和 CSS 文件的名称,但如果您想要压缩并且无法访问 IIS,我认为没有办法解决。

如果您想保留 *.js 和 *.css 扩展名,可以通过在 web.config 中为它们添加处理程序来实现。例如:

<compilation>
  <buildProviders>
    <add extension=".css" type="System.Web.Compilation.PageBuildProvider"/>
  </buildProviders>
</compilation>

<httpHandlers>
  <add path="*.css" verb="*" type="System.Web.UI.PageHandlerFactory"
       validate="true"/>
</httpHandlers>

从命名的角度来看,这有帮助,但对性能没有帮助;这些文件仍然是动态的——它们基本上是 *.aspx 文件,但具有不同的扩展名。它也不能与 ASP.NET 主题一起正常工作,因为无论扩展名如何,主题文件夹中的页面都不能是动态的。

【讨论】:

  • 小心转换为动态。 IIS 在提供静态文件方面比动态(内核模式)要快得多。仅当您的应用受带宽问题支配时才考虑这一点。
  • 通过启用输出缓存,您可以在第一次请求后使动态文件与静态文件一样快,从而启用 http.sys 缓存。只需遵守 http.sys 将缓存的内容的限制,例如没有查询字符串、没有动态缓存失效等。
  • 我很失望地得知我无法压缩我的 js 和 css 文件。我宁愿不经历将文件转换为动态的麻烦。我肯定会启用输出缓存,我只是不希望页面在第一次加载时要花很长时间。
  • 您可以从 web.config 控制静态压缩,但只能使用 IIS7+ (system.webServer/urlCompression)。有一些方法可以减轻首次访问时加载时间的增加。例如,您可以有一个启动脚本,当您的 AppPool 回收时加载页面。使用预编译的网站也有帮助。
【解决方案2】:

添加到@RickNZ 的答案:

转换为动态时要小心。 IIS 在提供静态文件方面比动态(内核模式)要快得多。仅在您的应用程序受带宽问题支配时才考虑这一点。

另一种选择是查看静态内容的 CDN(内容交付网络)。 Azure、亚马逊、Akamai 和其他公司提供服务。这是提供静态文件的一种非常快速的地理位置友好的方式。

【讨论】:

  • 我会研究 CDN。由于我们使用的网络服务器是本地的,我想知道在本地下载完整的有效负载还是从 CDN 下载压缩文件会更快
  • 如果它是本地的,那么可能不会更好 - CDN 有助于云中的网站,并且在全球访问时表现出色。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-09-21
  • 2018-02-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-29
  • 2021-07-31
相关资源
最近更新 更多