Build Single Page Apps – Part 5 – HTML 5 and ASP.NET Web Optimization
posted by John with 13 comments
Single Page Apps (SPA) are all the rage, and while it’s exciting to talk about the JavaScript we use in the SPA, the HTML is just as important. If HTML5 tags are used, then its important to make sure that you prepare for a graceful degradation if you want older browser support. Also, the HTML shell should handle this and pull in scripts as efficiently as possible.
You can read more about this and other topics in a few weeks when Pluralsight will be releasing my new course titled “Building Single Page Apps (SPA) with HTML5, ASP.NET Web API, Knockout and jQuery”. Til then, I’ve decided to journalize the creation of the course in a few posts. You can catch up on the previous posts in this series here:
More on the Code Camper SPA
Part 1 – The Story Begins (What is the Code Camper SPA?)
Part 2 – Client Technologies
Part 3 – Server Technologies (the Data Layer)
Part 4 – Serving JSON with ASP.NET Web API
Part 5 – HTML 5 and ASP.NET Web Optimization
Part 6 – JavaScript Modules
Part 7 – MVVM and KnockoutJS
Part 8 – Data Services on the Client
Part 9 – Navigation, Transitions, Storage and Messaging
Part 10 – Saving, Change Tracking, and Commanding
Part 11 – Responsive Design and Mobility
HTML Best Practices
Staring at a blank canvas can be terrifying for developers. Come on, admit it .. as exciting as it is to start a new project, sometimes its just daunting to think “how do I get started?” The good news is that when starting with an HTML app there is help to get you going. And using best practices for HTML is actually quite simple. 2 of my favorite tools to get started are HTML5 Shiv and HTML5 Boilerplate. In my course I chose HTML5 Boilerplate and it offers these (and many more) benefits:
1) Tips on where to put your scripts in the HTML page
2) Mobility and responsive design help
<!-- Mobile viewport optimized: h5bp.com/viewport --> <meta name="viewport" content="width=device-width">
3) CSS baseline for styles (check out the style.css included in the template)
4) Helps make your app work well across multiple browser brands and versions with modernizr
<!-- All JavaScript at the bottom, except this Modernizr build. Modernizr enables HTML5 elements & feature detects for optimal performance. Create your own custom Modernizr build: www.modernizr.com/download/ --> <script src="js/libs/modernizr-2.5.3.min.js"></script>
5) Tips for scripts using CDNs and fallbacks
<!-- Grab Google CDN's jQuery, with a protocol relative URL; fall back to local if offline --> <script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"> </script> <script> window.jQuery || document.write( '<script src="js/libs/jquery-1.7.1.min.js"><\/script>') </script>
There is so much more in HTML5 Boilerplate and I highly recommend you check it out. Its fun to download the full version of it which includes tons of comments on what the features do.
ASP.NET Web Optimization
When building an app you may end up with a lot of JavaScript and CSS files. Some you write yourself and others you include from popular libraries like jQuery or Knockout . You want to make sure you get those scripts and CSS to your browser as quickly and efficiently as possible. That’s where bundling and minification can make a huge impact.
The good news here is that there are many options, there is one backed right into the latest version of ASP.NET called ASP.NET Web Optimization (available on NuGet). With this tool you can bundle your JavaScript (or CSS) into a few bundles. So instead of the browser making 40 requests for 40 files (if that is what you have), you could have the browser request 2 files (your bundles). Bundling is simply concatenating your files together.
The other half of this equation is minifying your files, which cuts out whitespace and does some other tricks to shorten the contents of the files. In some cases these can greatly reduce the file size and thus make the request take a lot less time to get to the browser. Once the scripts are optimized, you can bring them to the browser via a regular script tag reference or through ASP/NET’s special Styles.Render and Scripts.Render syntax as follows:
@Styles.Render("~/Content/mycss") @Scripts.Render( "~/bundles/myjs" )
These are just a few of the feature of ASP.NET Web Optimization. You can see more about this feature in my course, as I use it to create a few key bundles for my scripts and CSS.
Next up I’ll explain some tips to kick off the SPA with JavaScript.
Martin on said:
What I really think is worth mentioning, is that @Styles.Render(..) will be replaced with the fitting html-tags for all bundles files, when bundle optimization is turned off. So for easier debugging it is advised to use @Styles.Render(..) instead of manually including your bundle-resource.
john on said:
Martin – Agreed. Using the “Render” syntax has advantages including that it create the script tags for you and helps create the versions.
ügyvyitel on said:
would you please post a link about SPAs?
I understand that this is a new&changing technology but it would be nice to inform about it.
thank you
Patrick on said:
Can’t wait for the pluralsight course, it’s like waiting for Batman 3 before it was released
How does bundling play with RequireJS? Didn’t requireJS requires for one object per js file?
john on said:
Patrick – Thanks for the comment.
RequireJS has a “friend” r.js which can do the optimization. It is a little more effort to not use r.js and instead use your choice, which is what I chose (ex: ASP.NET Web Optimization). So I don’t use require.js to request the files (which it can do), I use it for the loading and dependency resolution.
john on said:
Patrick – You can avoid the object per file if you define IDs for them.
Pat Capozzi on said:
I have been looking everywhere for the meaning of the @Styles.Render syntax.
Exactly what does @Styles.Render(“~/Content/mycss”)
do???
I am guessing that it includes some css files in the /content directory but what files and why?
Thanks for any direction on this.
john on said:
Pat
It’s part of the ASP.NET Web Optimization features. Check out the “Optimizing the Single Page” module in my SPA course … its free for the next 48 hours!
http://pluralsight.com/training/Courses/TableOfContents/spa
AsherBritt on said:
Really,nice combination between html5 and Asp.net.html5 is best and newest version in html.so it is many advantage for use it.
Oleg on said:
Hello, John! You do an awesome job! Thank you for that!
ASP.NET Web Optimization seems absolutely fine for SPAs, but what about page specific assets in multipage web applications? Does a separate bundle have to be created for each page per asset type (e.g. one for css, one for JS) in global.asax? Or, perhaps, new page specific bundles can be registered “inline” in the view itself?
Would shed some light on this, please?
John on said:
Hi Oleg,
How you design the bundles really depends on how you want to render your pages. If you want multiple pages, each with their own assets, then a bundle per X is fine. If you use MVC and have a master layout, then you can create a bundle for the assets that need to be available to all pages, then on each page, you can create a simple bundle per page. But really, it depends on how much you are getting out of the bundle.
Oleg on said:
Thank you for your quick reply John!
I didn’t specify details in my question. I do understand that bundling and minification make sense when many assets are linked to the page, which is not usually the case, since most of those assets are shared between all pages and referenced from the master layout.
My desire is to be able to create bundles per page (that needs specific ones) not only to reduce bandwidth but also simply to make javascript, for example, less readable. I hoped ASP.NET Web Optimization would provide developers with the effortless way of doing it.
From what I know about this bundling and minification technique is that if you want to have page specific bundles, you have to register them on application start (e.g. in global.asax) and then reference them from the page.
It would be great to be able to specify something like this per page:
@section Javascript
{
@Scripts.RenderBundle(
“~/Scripts/js1.js”,
“~/Scripts/js2.js,
“…”)
}
Jovana Milutinovich on said:
This article is translated to Serbo-Croatian language by Jovana Milutinovich from Webhostinggeeks.com.