Question

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?

Was it helpful?

Solution

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.

OTHER TIPS

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);
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top