First project using Helix coming up. In our previous project we've used HTTP/2 on the CDN, so we have adopted a lot of new best practices.
One of the most important new best practices in HTTP/2 is that number of requests is no longer an issue. Instead of bundling all components styles and scripts into one big styles.css
and scripts.js
we only include the styles and scripts that are needed to support the components that are present on the current page. This results in lighter page weight (which is good) and more requests (which is no longer an issue).
In the last project we have used what Kern Herskind called "inside out rendering" (http://herskind.co.uk/blog/sitecore/2014/11/off-piste-with-sitecore-mvc/) to place the components scripts and styles inside <head>
or before </body>
.
With that approach, a sample component looks something like this:
<!-- language: html -->
@model Sitecore.Mvc.Presentation.RenderingModel
@{
Section.AddHead("<link rel='stylesheet' href='" + @GulpAsset.GetSrc("components/headerComponent.css") + "' />");
Section.AddBeforeBodyEnds("<script src='" + @GulpAsset.GetSrc("components/headerComponent.js") + "' ></script>");
}
<header class="headerComponent">
[a lot of HTML]
</header>
A page where several components are included would render like this. The thing to note here is that stylesheets renders inside the <head>
-element and scripts are rendered just before </body>
. Just like it should.
<!-- language: html -->
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>About us</title>
<link rel="stylesheet" href="//cdn.customer.com/ui/css/headerComponent-[hash].css" />
<link rel="stylesheet" href="//cdn.customer.com/ui/css/mainNavigationComponent-[hash].css" />
<link rel="stylesheet" href="//cdn.customer.com/ui/css/editorialComponent-[hash].css" />
<link rel="stylesheet" href="//cdn.customer.com/ui/css/footerComponent-[hash].css" />
</head>
<body>
<header class="headerCoponent">
This is the header component
</header>
<nav class="mainNavigationComponent">
<ul>
<li><a href="/home">Home</a></li>
<li><a href="/about">About</a></li>
</ul>
</nav>
<div class="editorialComponent">
<h1>This is an amazing page</h1>
<p>Bacon ipsum dolor amet beef ribs tenderloin chuck short ribs sirloin, picanha porchetta ham.</p>
</div>
<footer class="footerComponent">
Some footer content
</footer>
<script src="//cdn.customer.com/ui/js/headerComponent-[hash].js"></script>
<script src="//cdn.customer.com/ui/js/mainNavigationComponent-[hash].js"></script>
<script src="//cdn.customer.com/ui/js/editorialComponent-[hash].js"></script>
<script src="//cdn.customer.com/ui/js/footerComponent-[hash].js"></script>
</body>
</html>
The benefits from doing like this is that a cshtml view, its styles and scripts are very closely tied together, both via file names/namespace and sitecore wise.
If you include the component on a page you can be confident that the styles and scripts will follow. One huge disadvantage is that this approach does not work with Sitecore HTML cache. The second time a user requests this page with Sitecore HTML cache enabled the scripts and styles won't render. So that "kinda sucks".
This boils down to: Is there a better way to solve this using Helix principles? How do I link in the components JS and CSS inside the .cshtml and at the same time being able to use the Sitecore HTML cache?