1

I have a ASP.NET MVC project in Visual Studio 2013.

I would like to automatically insert the content of a minified CSS stylesheet (minified using Web Essentials VS extension) into a style tag on an MVC layout page when building the project.

EDIT - This is for reducing render blocking effects above the fold for first time load (see Optimize CSS Delivery)

How can I do this?

Aldracor
  • 2,133
  • 1
  • 19
  • 27
Graham
  • 1,497
  • 2
  • 16
  • 36
  • Out of curiosity, why do want it just before the build? Is there a special reason you cannot just manually place a `` tag in die documents head? – Marco Jun 08 '15 at 12:57
  • It's an optimisation requirement. The style content is solely for content rendered above the fold and needs to be placed in the page head to reduce HTTP requests. On the release version of the page, the content in this style tag is minified, and editing it manually if changes are needed is a pain. Hence it would be very useful to have the content inserted straight from the minified file in JS. – Graham Jun 08 '15 at 13:28

3 Answers3

2

In case anyone is still looking for an answer.

I created a HTML helper like below:

public static class CriticalCssHelper
{
    public static MvcHtmlString CriticalCss(this HtmlHelper html, params string[] paths) 
    {
        var style = new TagBuilder("style");

        foreach (var path in paths)
        {
            var filePath = HttpContext.Current.Server.MapPath(path);
            style.InnerHtml = File.ReadAllText(filePath);
        }

        return new MvcHtmlString(style.ToString());
    }
}

And in your *.cshtml file you can just use like this:

@Html.CriticalCss("~/Content/css/CriticalCss/layout.min.css")

PS. This might also help for pagespeed optimisation: Minify HTML output from an ASP.Net MVC Application (a little off topic, however are related as it minifies inline css as well)

Community
  • 1
  • 1
Aldracor
  • 2,133
  • 1
  • 19
  • 27
1

You could try to use the Minification feature of ASP.NET 4.5

In App_Start folder, add BundleConfig.cs class to specify the location of CSS files:

public class BundleConfig
{
  public static void RegisterBundles(BundleCollection bundles)
  {
     //For Css
     bundles.Add(new StyleBundle("~/Content/BundlesCSS").Include(
                        "~/Content/mycss1.css",
                        "~/Content/mycss2.css"));
  }
}

And in the View, add this line of code to render CSS:

<%:Styles.Render("~/Content/BundlesCSS")%>

You can also disable this feature at development time by setting the value of debug attribute in Web.config file:

<system.web>
    <compilation debug="true" />
</system.web>

See more detail: Bundling and Minification

Minh Nguyen
  • 2,106
  • 1
  • 28
  • 34
  • Minification through bundling isn't what I need. See second comment on the original post (Jun 8, 13:28) – Graham Nov 04 '15 at 10:57
  • @Graham: It is not a good practice to embed CSS content into html file as it will increase the size of html page every time the user requests that page. By seperating CSS files into another request, you can reduce the html size and also benefit from caching CSS files in subsequent requests. – Minh Nguyen Nov 04 '15 at 12:40
  • That's not strictly true. Adding in critical CSS to the HTML will reduce the number of HTTP calls on initial load meaning that the page will load quicker. See Google PageSpeed recommendations for more info. – Graham Feb 09 '16 at 08:08
0
    public static String EmbedCss(this HtmlHelper htmlHelper, string path, string tagId = "")
    {
        // take a path that starts with "~" and map it to the filesystem.
        var cssFilePath = HttpContext.Current.Server.MapPath(path);
        // load the contents of that file
        try
        {
            var cssText = System.IO.File.ReadAllText(cssFilePath);
            var minifier = new Minifier();
            cssText = minifier.MinifyStyleSheet(cssText);
            var styleElement = new TagBuilder("style");
            if (!String.IsNullOrEmpty(tagId))
            {
                styleElement.Attributes.Add("id", tagId);
            }

            styleElement.SetInnerText(cssText);
            return styleElement.ToString();
        }
        catch (Exception ex)
        {
            // return nothing if we can't read the file for any reason
            return null;
        }
    }