ASP.Net MVC应用程序中的HTML输出压缩

39

这似乎是下面问题的一个副本,但唯一的答案是一个失效的链接:
如何压缩 ASP.NET 应用程序的 Html 输出?

在处理 ASP.Net 时,对我而言比较烦人的是 Visual Studio 使用空格代替制表符进行空格处理,这会增加最终 HTML 的大小。一开始我想简单地更改 Visual Studio 设置以使用制表符,但是其他团队成员可能仍然会使用空格进行排版。

我的问题有两部分:第一,是否有一种每个项目设置的方式来更改使用空格还是制表符(如果值得的话);第二,是否有一种简单的方式可以在生成时压缩所有视图?


可能是ASP.NET应用程序的HTML输出最小化的重复问题。 - obayhan
5个回答

45

启用GZIP的效果比缩小HTML要大得多。

在运行时进行缩小可能会损害您的服务器(假设您不使用缓存)。在部署期间缩小您的Asp.Net标记可能是一个好主意。这样,您仍然在代码存储库中拥有非缩小版本的代码,在服务器上有一个缩小版本。考虑一个部署过程,在该过程中您调用一个HTML缩小工具(例如,Dean Hume的此工具看起来很有前途)对所有.aspx文件进行操作。


1
+1. 无论如何,您都应该在传输时压缩输出,这样当您使用一个制表符和几个空格时,将占用相同的带宽。 - bobince
1
@ErçinDedeoğlu,在写作时,在StackOverflow上给出解决方法提示是相当普遍的。目前,每个人都期望对所有问题给出确切的答案,但我应该去删除所有的回答吗? - naivists
5
即使我已经启用了GZIP压缩,谷歌PageSpeed Insights仍然建议我缩小HTML文件,以实现13%的减少。我希望同时使用两者。 - Tomas Kubes
@Er Mayank Stack Overflow本身并没有被缩小,他们拥有更多的资源。http://meta.stackexchange.com/questions/173486/why-is-stackoverflow-html-not-minified - Tomas Kubes
你提交了一个需要/期望回答的意见,然后因为被踩了而感到不满?不确定那种心态是从哪里得来的,能够获得18k声望值。 - The Muffin Man
显示剩余4条评论

13

我使用了你的程序包,效果非常好!但是只在IIS服务器上运行,本地机器上无法运行。 - rkawano
1
@rkawano,你可以:
  1. 安装WebMarkupMin.Core包,并将WebMarkupMin作为库在你的.NET应用程序中使用(直接使用HtmlMinifierXhtmlMinifierXmlMinifier类)。
  2. 安装Web Essentials 2013,并使用上下文菜单命令“Web Essentials” > “Minify HTML file(s)”对HTML文件进行缩小。
目前WebMarkupMin的命令行版本尚不存在。
- Andrey Taritsyn
有了disableMinificationInDebugMode="false"设置,它在本地IIS上也被压缩了!非常感谢! - rkawano
我该如何使用这个链接 https://github.com/Taritsyn/WebMarkupMin/wiki/WebMarkupMin:-ASP.NET-4.X-MVC,在我的本地机器上安装它? - nmit026
1
@nmit026,将Web应用程序切换到发布模式-https://github.com/Taritsyn/WebMarkupMin/wiki/ASP.NET-4.X-Extensions#webmarkupmin-configuration - Andrey Taritsyn

6

这个链接(从您提供的相关链接中)是有效的。它提供了一种解决方案,可以将WebRazorHostFactory替换为一个可以压缩您的HTML的工具。

要使其正常工作,您需要在Web.config文件中添加以下内容:

<system.web.webPages.razor>
  <host factoryType="Omari.Web.Mvc.WhiteSpaceCleaningMvcWebRazorHostFactory, WhiteSpaceCleanerForWebFormsAndMVC3" />
</system.web.webPages.razor>

这个部分通常放置在Views\Web.config文件中。


3
不适用于MVC4。如需MVC4支持,请参考https://github.com/Chebur9tina/HtmlOptimizerMvc4。 - Cheburek

6

谷歌页面速度将会很喜欢这个:

我曾经苦恼了一段时间,但是最好的方式是结合以下几点:

你可以使用我的助手类MinifyHtmlAttributeGitHubGist上。它使用Zeta Producer Html Compressor来最小化HTML,并使用System.Web.Optimization的捆绑功能,以最小化内联JavaScript和CSS(对于您的关键CSS 0.0)。

Zeta Producer Html Compressor NuGet Package

将Google的HtmlCompressor库移植到.NET以最小化HTML源代码。

现在,您可以压缩和最小化您的HTML,同时内联CSS和JavaScript也会被最小化!太棒了! ;)

希望有人能发现这个有用。


0

这是一个老问题,但我会提供我的解决方案,以防对其他人有所帮助。

我使用正则表达式编写了一个“缩小”过滤器,大部分情况下都能正常工作。但当涉及到保留pretextarea标签中的空格时,它就失败了。几天前,我因此遇到了困境,于是花了三天时间阅读别人尝试过的方法并尝试自己的想法。最终,我选择使用HtmlAgilityPack解析HTML,并从那里删除空格节点。由于HAP不认为pretextarea元素中的空格是空格,所以它对我很有帮助,正好做到了我想要的效果。一开始我遇到了麻烦,因为HTML被分成了多个块,但我通过缓冲它直到完整解决了这个问题。以下是我的代码,如果对其他人有用,可以参考一下。

请注意,此筛选器在我的应用程序(ASP.NET MVC 5)中有效。理想情况下,应该在发布时进行缩小以避免使用此类过滤器。最后,在他的回答中,@naivists指出,GZIP压缩响应将比缩小效果更好,但我略有不同意见。是的,它确实会,但缩小还会稍微减少响应。它真正发挥作用的地方是在使用CSS进行样式设计时,因为现在您不必担心空格对元素的影响和错位,并且不必使用边距/填充/定位技巧来纠正它。
[AttributeUsage(AttributeTargets.Class, Inherited = false)]
internal sealed class MinifyHtmlAttribute :
    ActionFilterAttribute {
    public override void OnActionExecuted(
        ActionExecutedContext filterContext) {
        if (filterContext == null
            || filterContext.IsChildAction) {
            return;
        }

        filterContext.HttpContext.Response.Filter = new MinifyHtmlStream(filterContext.HttpContext);
    }
}

internal sealed class MinifyHtmlStream :
    MemoryStream {
    private readonly MemoryStream BufferStream;
    private readonly HttpContextBase Context;
    private readonly Stream FilterStream;

    public MinifyHtmlStream(
        HttpContextBase httpContextBase) {
        BufferStream = new MemoryStream();
        Context = httpContextBase;
        FilterStream = httpContextBase.Response.Filter;
    }

    public override void Flush() {
        BufferStream.Seek(0, SeekOrigin.Begin);

        if (Context.Response.ContentType != "text/html") {
            BufferStream.CopyTo(FilterStream);

            return;
        }

        var document = new HtmlDocument();

        document.Load(BufferStream);

        var spans = document.DocumentNode.Descendants().Where(
            d =>
                d.NodeType == HtmlNodeType.Element
                && d.Name == "span").SelectMany(
            d => d.ChildNodes.Where(
                cn => cn.NodeType == HtmlNodeType.Text)).ToList();

        //  Some spans have content that needs to be trimmed.
        foreach (var span in spans) {
            span.InnerHtml = span.InnerHtml.Trim();
        }

        var nodes = document.DocumentNode.Descendants().Where(
            d =>
                (d.NodeType == HtmlNodeType.Text
                && d.InnerText.Trim().Length == 0)
                || (d.NodeType == HtmlNodeType.Comment
                && d.InnerText.Trim() != "<!DOCTYPE html>")).Select(
            d => d).ToList();

        foreach (var node in nodes) {
            node.Remove();
        }

        document.Save(FilterStream);
    }

    public override void Write(
        byte[] buffer,
        int offset,
        int count) {
        BufferStream.Write(buffer, offset, count);
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接