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

发布于 2024-08-18 17:43:38 字数 384 浏览 12 评论 0原文

这可能与以下问题重复,但唯一的答案是死链接:
缩小 ASP.NET 应用程序的 Html 输出

使用 ASP.Net 时对我来说更烦人的方面之一是 Visual Studio 在白色间距中使用空格而不是制表符,这会增加最终 HTML 的大小。我最初想简单地更改 Visual Studio 设置以使用选项卡,但我团队中的其他人仍然会最终覆盖空格。

我的问题有两个:首先,有没有一种方法可以在每个项目设置上更改是否使用空格或制表符(如果使用空格或制表符,是否值得),其次,有没有一种方法可以在生成时简单地缩小所有视图?

This is likely a duplicate of the below question but the only answer is a dead link:
Minify Html output of ASP.NET Application

When working with ASP.Net one of the more annoying aspects to me is the fact that Visual Studio puts spaces instead of tabs for white spacing which increases the size of the final HTML. I originally thought of simply changing Visual Studio settings to use tabs instead but then others on my team will still end up overlaying with spaces anyway.

My question is two fold: first is there a way to on a per project setting to change if spaces or tabs are used (and is it even worthwhile if so) and second, is there a way to simply minify all of the views when generated?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

初懵 2024-08-25 17:43:38

无论如何,启用 GZIP 比缩小 HTML 的效果要好得多。

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

Enabling GZIP will have much more effect than minifying your HTML, anyway.

Doing minification at runtime could hurt your servers (assuming you don't use caching). It may be a good idea to minfiy your Asp.Net markup during deployment. This way, you still have a non-minified version of code in your code repository, and a minified version on the server. Think of a deployment process where you invoke an HTML minifier (for instance, this tool by Dean Hume looks promising) on all .aspx files.

没有你我更好 2024-08-25 17:43:38

I recommend you to try WebMarkupMin.Mvc. Documentation is available at - http://webmarkupmin.codeplex.com/documentation

戈亓 2024-08-25 17:43:38

此链接有效(来自您提供的相关链接)。它有一个解决方案,可以让您用缩小 HTML 的解决方案替换 WebRazorHostFactory

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

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

此部分通常放置在 Views\Web.config 中。

This link works (from the related link that you provide). It has a solution that let you replace the WebRazorHostFactory by one that minifies your HTML.

To make it work, you have to add the following in your Web.config file:

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

This section is usually placed into Views\Web.config.

灯下孤影 2024-08-25 17:43:38

Google Pagespeed 会喜欢这个:

我为此苦苦挣扎了一段时间,我发现最好的方法是结合几件事:

您可以使用我的 Helper 类 MinifyHtmlAttributeGitHubGist 上。它使用 Zeta Producer Html 压缩机 来最小化 HTML 并使用 System.Web.Optimization 的捆绑,以最小化内联 javascript 和 CSS(对于您关键的 css 0.0)

Zeta Producer Html 压缩器 NuGet 包

Google HtmlCompressor 库的 .NET 端口,用于缩小 HTML 源代码
代码。

现在您可以压缩并缩小您的 html,同时缩小内联 css 和 javascript!太棒了! ;)

希望有人觉得这很有用。

Google Pagespeed will love this:

I struggled for a while with this and the best way that I found was a combination of a few things:

You can use my Helper Class MinifyHtmlAttribute on GitHubGist. It uses the Zeta Producer Html Compressor to minimize the HTML and with System.Web.Optimization's Bundling, to minimize inline javascript and CSS (for your critical css 0.0)

Zeta Producer Html Compressor NuGet Package

A .NET port of Google’s HtmlCompressor library to minify HTML source
code.

Now you can compress and minify your html with inline css and javascript being minified as well!! Awesome! ;)

Hope someone finds this useful.

他是夢罘是命 2024-08-25 17:43:38

这是一个老问题,但我会扔掉我的解决方案,以防它对其他人有利。

我有一个使用正则表达式的“缩小”过滤器,它在很大程度上起作用。当涉及到在 pretextarea 标记中保留空格时,它失败了。几天前我因为这个而碰壁了,所以我花了大约三天的时间阅读其他人的尝试并尝试我的想法。最后,我决定使用 HtmlAgilityPack 解析 HTML 并从中删除空白节点。因为 pretextarea 元素中的空格不被 HAP 视为空格,所以它的结果对我有利,并且完全按照我的要求进行。一开始我确实遇到了麻烦,因为 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);
    }
}

This is an old question, but I'll toss in my solution in case it benefits someone else.

I had a "minification" filter using regular expressions that worked for the most part. It failed when it came to perserving whitespace in pre and textarea tags. I ended up hitting a wall a few days ago because of it so I spent about three days reading through what others have tried and trying out my ideas. In the end I settled on parsing the HTML using the HtmlAgilityPack and removing the whitespace nodes from there. Because whitespace in pre and textarea elements was not considered whitespace by HAP it worked out in my favor and did exactly what I wanted. I did have trouble in the beginning because the HTML was being sent in chunks, but I resolved it by buffering it until it was complete. Here's my code in case it's beneficial to someone else.

Do note that this filter works for me in my application (ASP.NET MVC 5). Ideally, minification should be done during publishing to avoid the need for filters like this. Lastly, @naivists in his answer states that GZIP compressing the response will have a better effect than minification, but I slightly disagree with him. Yes, it will, but minification does reduce the response ever so slightly on top of that. Where it really shines is when styling with CSS because now you don't have to worry about whitespace bumping and misplacing elements and having to use margin/padding/positioning trickery to correct it.

[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);
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文