Minify HTML output from an ASP.Net MVC Application

╄→尐↘猪︶ㄣ 提交于 2019-11-29 23:39:01
naivists

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.

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

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.

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.

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);
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!