Chapter 6. HTML optimization tips

This chapter covers

  • Positioning CSS and JavaScript in a web page for best performance
  • How CSS and JavaScript placement affects rendering
  • The impact of duplicate scripts
  • HTML5 optimization techniques

This chapter contains a collection of HTML best practices and tips that will improve the performance of your website. Some tips may seem like small changes, but they’ll go a long way toward improving the overall load time and responsiveness of your website. We’ll cover the optimal position in the HTML to place CSS and JavaScript, as well as the order in which they should appear.

You’ll learn a few HTML5 techniques and how you can apply these techniques to your application to achieve quicker load times. This chapter builds on the Surf Store application that you’ve been using thus far, and applies HTML5 techniques in different scenarios.

6.1. Where to position CSS and JavaScript in a web page to achieve the- e best performance

When you start building a new website, you may not be concerned with the order or location of the style sheets on your web page. However, their order and location play an important role in the way a browser renders a web page.

6.1.1. CSS

The position of CSS in an HTML document has less to do with download times, and more to do with how the browser reacts and renders the page. It’s all about perceived speed for the user!

Listing 6.1. Style Sheets located at the bottom of the page

In a typical HTML web page the JavaScript is located in the <head> tag of the document and the CSS is in the body of the page. Placing CSS at the bottom of a web page is not the optimal position because browsers block the rendering of a web page until all external style sheets have been downloaded. This means that if your style sheet is located at the bottom of a web page, it will block everything else from loading and you might see a blank white screen for a short while. This is not good. Figure 6.1 shows how the location of CSS on a web page affects the way a page renders.

Figure 6.1. A simulated waterfall chart showing the CSS at the bottom of the HTML document

It may seem as if the waterfall chart in figure 6.1 represents the best-case scenario for page rendering, but nothing will be visible on the web page until after the CSS has been downloaded and parsed. Putting the CSS near the bottom of the document prevents progressive rendering in many browsers. Progressive rendering means the web page begins to appear and the text can be read even before all the text or images have been completely downloaded. Most browsers block rendering to avoid having to redraw elements of the page if the CSS changes. Some browsers will even leave the user with a blank white page while they are waiting.

In fact, the best place to put your style sheets is in the document <head> tag. If style sheets are downloaded and parsed first, the browser is able to render the page progressively instead of blocking the rendering until the CSS has finished loading. By positioning the CSS in the document <head> tag, you’re also allowing the browser to begin displaying whatever content it has as soon as possible.

Listing 6.2 shows the CSS located in the document <head> tag in the Surf Store application. The same principle applies to inline style blocks, which can cause reflows and shifting of content. Reflow is the name of the web browser process for recalculating the positions and geometries of elements in a web page. Reflows block the browser while they try to recalculate the position of elements on a web page. The following listing is a web page from the Surf Store application, and you can see the small snippet of inline CSS that is necessary to include a visual header on the page. This inline style tag needs to reside in the document head for the best performance.

Listing 6.2. Style sheets located at the top of the page

Figure 6.2 shows the CSS positioned at the top of the HTML document. You may not notice faster download times by placing the CSS at the top of your web page, but this will at least allow the user to see something on the page while the rest of the page renders.

Figure 6.2. A waterfall chart showing the CSS at the top of the HTML document

6.1.2. JavaScript

The location and order of JavaScript can also have a positive and negative effect on the way a page is rendered. If CSS needs to be in the document head, you might presume that your JavaScript should go there too. In fact, the best place for JavaScript is at the bottom of a web page because JavaScript blocks the browser’s ability to download components in parallel. In other words, it blocks progressive rendering for all content in the web page that’s placed after the JavaScript. If you place the JavaScript at the bottom of a web page, the content above the script will be rendered faster.

This may seem like a contradiction. You moved your CSS to the document head to allow progressive rendering but you place your JavaScript at the bottom of the web page to allow progressive rendering. Why? So the JavaScript is guaranteed to be executed in the proper order. For example, if code that required the jQuery library is executed before the jQuery library is actually downloaded, all sorts of errors would occur.

Moving the JavaScript to the bottom of a web page means there is more content above the script, and that content will be rendered sooner rather than later. Browsers run JavaScript in a single thread, so if a script is executing, the browser might not be able to start other downloads. If you move the JavaScript to the bottom of the page, the other downloads on the page are allowed to complete without any blocks. It appears faster visually, but the download times also reflect a performance improvement. Figure 6.3 shows what a waterfall chart would look like if you placed the JavaScript at the top of the page versus placing it at the bottom of the page.

Figure 6.3. An image showing the differences in the way a page loads depending on where the JavaScript has been placed in the HTML. Note that the best place is at the bottom of the page.

In the top waterfall chart, you can see that the images and all other components are waiting for the JavaScript to finish downloading before they can start rendering. This isn’t ideal. The second waterfall chart shows what happens when you move the JavaScript to the bottom of the page. Downloads aren’t blocked, rendering takes place faster, and the user will be able to see and interact with elements on the page a lot sooner.

6.2. How the order of styles and scripts affects rendering

You’ve learned the optimal positions for CSS and JavaScript, but the order that these files are placed in an HTML page is also important. If you place them in the correct order, you’re making sure the browser can render the page faster and not block the download of any components while it’s doing so. As mentioned earlier, the browser will delay rendering any content that follows a script tag until it’s been fully downloaded. If you couple this with a browser not rendering a web page until the CSS has been parsed, the order of your style sheets and JavaScript can have a big impact on your page load times.

The next listing contains HTML with four components that need to be downloaded so the page will render. I have purposely positioned the JavaScript between the style sheets to show how this will negatively affect performance.

Listing 6.3. The order of external styles and scripts

The waterfall chart now might look something like figure 6.4

Figure 6.4. A waterfall chart showing the effect that placing JavaScript files between CSS files can have. The best place for CSS is in the head of the HTML document.

Notice that the second JavaScript file in figure 6.4 will only execute after the first JavaScript file has been downloaded. This also affects the second CSS file because it must wait until the second JavaScript file has finished downloading before it executes. Each component is forcing the next component to wait until the preceding component is finished downloading. It’s like being in a bank with only one cashier—you need to wait until the person in front of you has been assisted and finishes their transaction before you can be helped! The next listing contains updated code that shows JavaScript and CSS files in the correct order in a web page.

Listing 6.4. The correct order for external scripts and styles

Notice I’ve moved the JavaScript to the bottom of the web page, just before the close of the <body> tag. I’ve also kept the CSS in the document head. With the order of the external style sheets and scripts optimized, the waterfall chart for the previous listing might look something like figure 6.5.

Figure 6.5. A waterfall chart showing the CSS placed in the document head

Browsers run JavaScript in a single thread, so it’s understandable that while CSS and JavaScript are being parsed and executed, the browser is unable to start other downloads. But there’s no reason the browser can’t start downloading other resources while the CSS and JavaScript files are downloading. Now that the order of the JavaScript and CSS has been optimized, you can see in figure 6.5 that more downloads are able to occur in parallel. The two CSS files are being downloaded in parallel to the first JavaScript file and you no longer have any downloads blocking the other components on the page. Our bank now has a few more cashiers and the line isn’t as long!

6.2.1. The impact of duplicate scripts

Duplicate scripts on your web page will not only add extraneous components for the browser to download, but will also add extra JavaScript for the browser to execute. Even if you’ve added HTTP caching, redundant JavaScript will still take time to parse and execute. You may be a diligent developer and think that this will never happen to you; however it can happen to anyone, especially in a team development environment. You wouldn’t want all your optimization work to go to waste by having extra unnecessary JavaScript files in your application! Keep this in mind when reviewing your HTML.

6.3. HTML5

HTML5 is a hot topic, and web developers everywhere are beginning to embrace it. HTML5 is the latest generation of HTML, and since the previous version (HTML4), there have been syntactical changes in the structure of the markup. A few extra APIs that are accessed via JavaScript have been added to HTML5. The web is constantly evolving all around us, mobile devices such as tablets and phones are becoming more powerful and more aligned with desktop PCs. HTML5 was designed to help us progress our work in the ever-evolving world of the internet.

Some optimization techniques available in HTML5 will increase the performance and speed of your websites. In the next section, you’ll learn some of these techniques. Although many of them may not improve your PageSpeed or YSlow score, they will definitely benefit your users.

In the shift between HTML4 and HTML5, the general structure of the HTML is the same, but syntactical changes reduce the number of characters you need to include on the page. Less syntax obviously contributes to the overall improved page load time. If you have less HTML in the page, the page is a lot lighter and the user is able to download the request faster.

In previous versions of HTML you would specify the document type at the top of the page like so:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

HTML5 now allows you to set the document type in the following manner:

<!DOCTYPE html>

The same applies when you specify the encoding of your document. Older versions of HTML would be similar to the following:

<meta http-equiv="content-type" content="text/html; charset=utf-8">

HTML5 now allows you to specify it like so:

<meta charset="utf-8">

These changes might not seem like much, but you’re already starting to remove extraneous characters and reduce the overall page weights in your website. Another syntactical change introduced with HTML5 is the ability to exclude type attributes when you’re referencing resources on your web page. For example, you might have referenced a JavaScript file like this in an older version of HTML:

<script type="text/javascript" src="filename">

However, you no longer need to specify the script type.

<script src="filename">

This can be applied to style sheets and, in fact, all MIME types in your web page. You can simply exclude the MIME types in the type attribute. Each step toward character removal means that you’re reducing the size of the HTML page to be loaded.

6.4. A note on HTML5 browser support

Although HTML5 is starting to gain popularity and exposure across the internet, it’s still in its infancy in terms of overall adoption. You’ve covered a handful of great HTML5 techniques that can really improve your application’s performance, but you should always keep in mind that a lot of browsers don’t yet support some of these great HTML5 features.

With the right fallbacks in place, there is no reason why you can’t start using HTML5 today.

Modernizr (download at http://modernizr.com/) is a JavaScript library that detects HTML5 and CSS3 features in a user’s browser. It’s great if you need to quickly and easily determine the capabilities of a user’s browser, which then allows you to serve them the appropriate content.

Chapter 1 covered the performance cycle and the important role it plays when you’re making changes on your website. While you’re progressing through this chapter, keep the stages of the performance cycle (figure 6.6; repeated from chapter 1) and where you currently stand in mind. After applying any HTML5 updates to a website, it’s important to monitor any performance changes and monitor how they affect your users. As a developer, think about your users instead of simply adding HTML5 features. What do your analytics statistics look like? How many of your users are using updated browsers? How long does your JavaScript take to load? These are all important questions to ask yourself.

Figure 6.6. The performance cycle

6.4.1. HTML5 asynchronous JavaScript

At the beginning of the chapter you learned about the impact JavaScript has on web page loading times. JavaScript will block any other downloads on a page, and in some instances prevent the page from progressively rendering. Many a time you will see a blank page while a large JavaScript file is being downloaded and parsed, and it’s because it’s blocking the DOM. However, the clever folks at the W3C thought of a way to get around this.

Enter async, an attribute of the script tag, introduced in the HTML5 draft. This handy little attribute allows you to download JavaScript and execute it asynchronously without blocking the rendering of elements below it. Think of it as the browser’s ability to execute the code independently of anything else that’s happening on the page. The best part is it doesn’t block anything else. You simply need to include async in the script tag:

<script async src="filename"></script>

In theory, if you have two scripts in a web page and you’re using async, these two scripts can run at the same time and in parallel.

Another useful tag attribute is defer. It can be used in conjunction with async and has been supported in browsers for a while now. In order to use it, add the attribute to the script tag:

<script defer src="filename"></script>

The defer attribute is similar to async in most ways. The difference is when each script is executed. Each async script executes after it has finished downloading, which means it is not executed in the order in which it occurs in the page. The defer scripts are guaranteed to be executed in the order in which they occur in the page. The following listing shows an example of these tags being used in a web page.

Listing 6.5. An example of asynchronous JavaScript in action

The async attribute is included in the JavaScript tag. Figure 6.7 shows a waterfall chart for a web page, like that in the previous listing, which has script tags decorated with the async attribute. Notice that the JavaScript will still get executed in any order that the browser sees fit, even if the JavaScript appears at the bottom of the page. The async attribute allows the browser to parse the HTML and decide when and how to download and execute the JavaScript. This has also occurred independently of the other downloads on the page.

Figure 6.7. A waterfall chart for JavaScript that is run using the HTML5 async attribute

There are still some things you’ll need to take into account when you’re using async and defer. The scripts aren’t guaranteed to run in the order they appear in the document, which is their default behavior when async isn’t present. You’ll need to exercise caution when using these two attributes because they might lead to code dependency issues. For instance, if you use jQuery or any other JavaScript library on your web page that’s used by other scripts on the same page, you might find that the script that’s dependent on the library is run first. This can cause the scripts to fail. Figure 6.8 represents a typical JavaScript error you might come across in this situation.

Figure 6.8. A JavaScript error that occurred as a result of the async attribute and a code dependency

Depending on your HTML, the usage of async or defer can bring a boost to the JavaScript performance of a web page. It can get a little tricky when the JavaScript on the web page has dependencies, so keep that in mind.

6.4.2. HTML5 Web Workers

JavaScript runs in a single-threaded environment, so multiple scripts can’t run at the same time. It also means expensive, long-running tasks may block UI rendering. It would be a whole lot easier if you could write JavaScript asynchronous tasks that are both fire-and-forget and won’t block the UI of a web page.

Fortunately, there is an API that allows you to run scripts in the background, isolated from the web page. This API is known as Web Workers. Workers use thread-like messaging and they are perfect for keeping your UI fresh, snappy, and responsive. What is the difference between simply decorating your script tag with the async attribute and using HTML5 Web Workers? HTML5 Web Workers actually run in a thread that is owned by the browser. I like to think of HTML5 Web Workers as Thread or ThreadPool classes from .NET’s System.Threading namespace for the front end.

Thankfully, HTML5 Web Workers allow you to run tasks in parallel, and this makes full use of multiprocessor computers. Figure 6.9 illustrates how HTML5 Web Workers run in parallel to the UI thread, allowing the main browser to continue as normal, not blocked by the JavaScript.

Figure 6.9. Web Workers are able to run in parallel to the main browser thread.

Web Workers are perfect for fire-and-forget tasks. If you have a long-running task that you want to run in the background without affecting the main page, using a Web Worker would be ideal.

Using Web Workers can also be useful if you need to make sure a snippet of script executes even if the user navigates away from the web page. For example, if a user on your site navigates to another web page, you might find that a long-running script can’t finish executing and you could lose your JavaScript objects. If you use a Web Worker, script execution happens in another thread, so you can guarantee that it will execute properly.

Next you’re going to implement a basic, long-running AJAX example in the Surf Store application. As you progress through this example, remember that this Web Workers exercise is merely intended to give you a better understanding of Web Workers. The example you’re using is not a real-world scenario, and you’ll need to think about how to apply this to your application first!

6.4.3. Browser support for HTML5 Web Workers

You’re about to run code samples in both MVC and Web Forms. Surprisingly, there is a decent amount of support for Web Workers, but some of the major browsers (including older versions of Internet Explorer) are still playing a bit of catch-up. Firefox, Chrome, Safari, Opera, and Internet Explorer 10 all offer support for Web Workers. For more information, caniuse.com is a useful website for determining which browsers support Web Workers and any other HTML5 features. If the browser you’re targeting doesn’t yet fully support Web Workers, you could fall back to using traditional methods for executing long-running scripts.

6.4.4. HTML5 Web Workers in an ASP.NET MVC application

Remember that the original sample code for each application can be downloaded at https://github.com/deanhume/FastASPNetWebsites. Once it is in place, open the MVC project in the chapter 6 source code under the folder HTML5 Web Workers. In your Solution Explorer, navigate to the Layout View. Add the code from this listing.

Listing 6.6. Using Web Workers in a Layout View

You added the JavaScript just before the closing <body> tag, because this code will run asynchronously but you don’t want to block other component downloads on the page.

Remember that the order of scripts and styles can affect page rendering! Next, add a new JavaScript file called Worker.js to your Scripts folder in the project. You’ll use this Worker.js file to create the code the HTML5 Web Worker will execute. Figure 6.10 shows the location of the newly created Worker.js file in the Surf Store application for this chapter.

Figure 6.10. Adding a new JavaScript file to the Scripts folder in an ASP.NET MVC application

Inside the JavaScript file (Worker.js), add the code in the following listing.

Listing 6.7. The JavaScript file of a Web Worker

The Worker.js file contains code that will make an AJAX request to a controller in the MVC application. You’re going to update a set of statistics on the server with this code and it will return a message to the main calling script once the code has completed. You’re not passing any parameters in this example, but these could just as easily be added onto the request. Web Workers use a method called postMessage to return a result to the thread that called it. Whatever you return in this postMessage will be returned to the original thread. Next, you’ll need to add the controller that’s going to simulate intensive server-side code.

Add this new controller to the application and call it StatisticsController. This controller will contain the code that will execute and update the statistics on the server. The code in listing 6.8 is simple, but it’s used to simulate what could happen if the server needed to perform intensive calculations or long-running database calls. In the case of the code in the example listing, it’s updating the statistics for the website in the database which is an expensive call if done regularly. If you fire up the application, you’ll notice that you can continue using the web page and nothing has blocked the UI. You’ll receive an alert message once the operation that was running in the background has completed.

Listing 6.8. The JavaScript file of a Web Worker

In figure 6.11, the image of the Network tab on the developer tools shows us a similar result.

Figure 6.11. The Web Worker in the Network tab in an ASP.NET MVC application

In the Network tab, Worker.js is shown to take only 48 milliseconds. However, it actually took 5 seconds. It only took 48 milliseconds for the browser to parse the initial JavaScript and hand it off to run in parallel. The Web Worker allowed it to run in the background and it had no effect on the page’s UI. Through the clever use of JavaScript threads this brilliant HTML5 feature has drastically sped up the load time and responsiveness of the web page.

6.4.5. Web Workers in an ASP.NET Web Forms application

Adding HTML5 Web Workers to your ASP.NET Web Forms application is easy. In fact, adding Web Workers to even the most simple HTML page can be done in no time. In this example, you’re going to see how a Web Worker makes a call to an AJAX-enabled WCF service.

First, open the Web Forms project in the chapter 6 source code under the folder HTML5 Web Workers. In your Solution Explorer, navigate to the Site.Master page. Add the code in this listing outside of the <body> tag.

Listing 6.9. Using Web Workers in a Master page

We added the JavaScript outside of the <body> tag because even though this code will run asynchronously, we still don’t want to block other component downloads on the page. Remember that the order of scripts and styles can affect the page rendering! Next, add a new JavaScript file called Worker.js to your Scripts folder in the project. Figure 6.12 shows where the newly created Worker.js file is located in the Surf Store application.

Figure 6.12. Adding a new JavaScript file to the Scripts folder in an ASP.NET Web Forms application

Inside the JavaScript file, add the following code:

Listing 6.10. The JavaScript file of a Web Worker

The Worker.js file contains code that is going to make a request to an AJAX-enabled WCF service in the Web Forms application. Once it’s completed, it will return a message to the main calling script. In this example, you’re not passing any parameters through, but these could easily be added onto the request. Web Workers use postMessage to return a result to the calling thread. Whatever you return in this postMessage will be returned to the original thread. Next, you need to add the AJAX-enabled WCF service that is going to simulate long-running server-side code.

Add this new AJAX-enabled WCF service, shown in the following listing, to the application and call it Statistics. This WCF service will contain the code that will execute and update the statistics on the server.

Listing 6.11. The server-side code of an AJAX-enabled WCF service

This code is simple, but it is used to simulate what could happen if the server needed to perform intensive calculations or long-running database calls. If you fire up the application, you’ll notice that you can continue using the web page and nothing has blocked the UI. You’ll receive an alert message once the operation that was running in the background has completed. The Network tab in browser developer tools (figure 6.13) shows us a similar result.

Figure 6.13. The Web Worker being downloaded and executed in an ASP.NET Web Forms application

In the Network tab, the Worker.js is shown to take only 48 milliseconds. However, it actually took 5 seconds. This is because it took only 48 milliseconds for the browser to parse the JavaScript and pass it off to run in parallel. The Web Worker allowed it to run in the background and had no effect on the page’s UI. Through the clever use of JavaScript threads this brilliant HTML5 feature has drastically sped up the load time and responsiveness of the web page.

6.5. HTML5 application cache

Another great feature introduced in HTML5 is the application cache which allows you to run your web application offline. If the application cache is utilized properly, you won’t need a network connection to browse the pages in a website. This feature may not be applicable to every application that you write, but you can harness it to improve the speed and load times of certain pages in a web application. This technique does seem like a great concept—but how does it actually help you improve the speed of an application? The user could access all the resources that they need from the application cache instead of the server and, in turn, the page would load a lot faster.

A web browser that uses the HTML5 application cache to implement offline applications will read a list of URLs from the manifest file, download the resources, cache them locally, and automatically keep the local copies up-to-date as they change. Figure 6.14 represents the flow of events that take place in the HTML5 application cache.

Figure 6.14. The HTML5 application cache workflow

The HTML5 application cache enables a website to function without a network connection, and it can be extremely useful when a user on a mobile connection suddenly loses signal. This feature feels like something you should have been able to do for years with web pages, and now it’s finally been implemented as part of HTML5. Another advantage of using the application cache is it acts like the HTTP caching that you learned about in chapter 4. If used correctly, the browser only needs to download new content instead of fetching resources it already has.

Using the HTML5 application cache in an ASP.NET application is an easy process. Each time you use the application cache, you will need to reference a cache manifest file. This file is a simple text file that lists the resources the browser should cache for offline access. The manifest file can be located anywhere on your web server and contains a list of the things you’ll want to store in the application cache.

In order to know which files to cache, the HTML5 application cache will look inside the manifest file. This file will contain a simple list of the files that you want to cache. A typical manifest may look similar to the output in this listing.

Listing 6.12. A typical cache manifest file
CACHE MANIFEST
index.html
stylesheet.css
images/logo.png
scripts/main.js

You could always link to a static manifest file on your server, but I quite like to use the power of ASP.NET to return a dynamic manifest file. A dynamic file gives you much more control over the individual files you want to cache, and also allows for tighter control of updating the cache. You’re going to look at an example in both ASP.NET Web Forms and ASP.NET MVC that easily allows you to harness the power of this great HTML5 feature. By using a dynamic manifest file, the browser will continue to use the cached version of the resources until the manifest file has changed or been updated.

A manifest file is made up of three sections: CACHE, NETWORK, and FALLBACK. Each section has a specific purpose:

  • CACHE— This section contains the list of files to cache. Files listed in this section will be explicitly cached after they’re downloaded for the first time.
  • NETWORK— Files listed in this section require a connection to the server. Resources in this section are never cached and are not available offline.
  • FALLBACK— This section contains a list of files that can act as a fallback if a user has no connection or the file is inaccessible.

You’re about to look at examples in both ASP.NET MVC and ASP.NET Web Forms that will give you a better idea of how the HTML5 application cache works.

6.5.1. HTML5 application cache considerations

Remember that any pages you add to the manifest attribute will be cached in the browser: this includes the page itself! You can’t cache the resources and not the page because it isn’t designed to work that way. Think of the HTML5 application cache as extreme HTTP caching. The disadvantage of using the application cache is it doesn’t play well with server-side dynamic pages. If you keep your own website in mind, the pages you would add to the application cache would normally be the static pages or pages that don’t change very often. If you add the manifest attribute to your Master Page or Layout View, you’ll cache your entire application and won’t notice any changes when you refresh. Consider adding this to pages that aren’t updated dynamically.

Note

Using the HTML5 application cache in your projects can make debugging your application a nightmare, so if you’re reloading your page and you’re only seeing the cached version, you’ll need to make a change to the manifest file in order for the browser to fetch the new version. Alternatively, you’ll need to clear the application cache for the site. Check your browser for the particular settings in order to clear the application cache.

6.5.2. HTML5 application cache in an ASP.NET MVC application

Now you’re going to run through the Surf Store application and update it to use the HTML5 application cache. This will cache certain components on a page within the user’s browser and enable dramatically faster load times. You’re going to use the power of ASP.NET and make the Application Manifest file dynamic so you have more control over the items that you’re caching.

To enable the application cache you’ll need to include the manifest attribute on the HTML tag on the view that you wish to add to the application cache. Because the entire HTML page will be cached itself, you’re going to use pages that don’t change often, such as the About or Contact page. You’re going to use an MVC Controller to dynamically generate the manifest file and check the contents of the files that are being referenced. Update the Contact view in the project to reflect the code in the following listing.

Listing 6.13. Referencing the manifest file

In the listing you’ve updated the HTML tag to reference the MVC Controller. You’ll use this controller to dynamically generate the references to the files that you’re going to store in the browser. Now you’ll create your dynamic manifest page. First, add a new controller and call it AppCacheController. Then add a new method on your controller called Index, so the MVC route will map to /AppCache. Notice in the following listing how the MVC route matches up to the manifest link that you supplied on the HTML tag.

Listing 6.14. The AppCacheController

Next, add a view for that ActionResult. This view will contain the contents of the manifest file, shown next.

Listing 6.15. The dynamic manifest file

In chapter 5 you learned about file revving, a technique that appends a query string to the end of a filename to make sure a fresh version is retrieved every time a file changes. You’re going to apply the same technique to the manifest file, because you only want it to be updated when the contents of the referenced files change.

In the previous code you’ll notice a method called AppendHash() on the end of the filenames. This method will read the contents of the file referenced and only change the hash that’s appended if the contents of the file change. This makes the application cache entirely dynamic because there’s no need to update your manifest file every time a resource (CSS, JavaScript, and so on) file changes. This forces the browser to request a new version of the file.

Using the developer tools in a browser is the best way to inspect the application cache. If you open the web page in Google Chrome and navigate to the Console tab in the developer tools, you’ll notice something similar to figure 6.15.

Figure 6.15. The browser creating an application cache and downloading the contents in an ASP.NET MVC application

In figure 6.15 the browser is downloading the items referenced in the manifest file you created. You can also use the Chrome developer tools to inspect the exact items that have been stored in the application cache (figure 6.16).

Figure 6.16. The resources stored in the application cache in an ASP.NET MVC application

By navigating to the Resources tab and choosing Application Cache, you’ll be able to inspect the files that have been added to the application cache. In figure 6.16 you will also notice that a hash string has been appended to the end of the filenames. This means AppendHash is working correctly, and if the contents of the static files were to change, the application cache would fetch the updated versions based on the new hash key.

Every time a user who’s had an application cache created in their browser reloads the page and requests the same resources, it will be fetched from the browser’s cache and never hit the server. Now the web page can be accessed while they’re offline.

6.5.3. HTML5 application cache in an ASP.NET Web Forms application

Using the Surf Store application, you can easily update the code to use the HTML5 application cache. You’re going to use the power of ASP.NET Web Forms and make the application manifest file dynamic so you have more control over the items you’re caching. In order to enable the application cache, you need to include the manifest attribute on the HTML tag on the page you wish to add to the application cache. Because the entire HTML page will get cached, you’re going to use pages that don’t change often, such as the About or Contact page. In order to dynamically generate a manifest file, you’re going to use an ASP.NET Web Forms page. Open the Contact view in the project to reflect the code in the following listing.

Listing 6.16. Referencing the manifest file

You’ve updated the HTML tag to reference a Web Forms web page. You’ll use this ASPX web page to dynamically generate the references to the files that you’re going to store in the browser. Next, create your dynamic manifest page. First, add a new web page and call it AppCache.

Listing 6.17. The dynamic manifest file

In chapter 5 you learned about file revving, which appends a query string to the end of a filename to ensure a fresh version of a file is retrieved every time a file changes. You’re going to apply the same technique to the manifest file, because you only want it to get updated when the contents of the referenced files change.

In the previous code you’ll notice there is a method called AppendHash() on the end of the filenames. This method will read the contents of the file referenced and only change the hash that’s appended if the contents of the file change. This makes the application cache entirely dynamic because there’s no need to update your manifest file every time a resource (CSS, JavaScript, and so on) file has changed. This will force the browser to request a new version of the file.

Using the developer tools in a browser is the best way to inspect the application cache of your Web Forms application. If you open the web page in Google Chrome, you will notice something similar to figure 6.17.

Figure 6.17. The browser creating an application cache and downloading the contents in an ASP.NET Web Forms application

In figure 6.17, the browser is downloading the items that are referenced in the manifest file that you created. If you refresh the page, you’ll see the browser will simply retrieve the files it needs from the application cache.

Using the HTML5 application cache in your ASP.NET Web Forms application can be an effective way of improving the load time of your web pages.

6.5.4. Application cache support

By adding these changes to your application you’re ensuring the user’s browser will no longer retrieve the files from your server, but will instead fetch them from its own cache (figure 6.18). This can be a good thing and a dangerous thing. Use the HTML5 application cache wisely! It’s important to remember that using the HTML5 application cache might not suit your situation, depending on the purpose of your web application. If you have a dynamic website that relies on constantly providing your users with fresh content, this might not be the best solution for you. Instead, only use it on pages that don’t change often or pages that won’t be affected by this level of caching.

Figure 6.18. The events that take place in a browser when an application cache is requested in an ASP.NET Web Forms application

6.6. Summary

There are some important best practices that should be applied to your HTML in order to achieve the best load times from your web pages. This chapter answered a few vital questions about how resources should be placed in a web page’s HTML, and you’ve covered some pretty cool HTML5 features. When used correctly, HTML5 can be harnessed to improve your web page’s performance. HTML5 doesn’t require as many HTML attributes in order for the browser to interpret and display its resources, so you can use fewer characters in your web page’s HTML. That’s great because fewer characters equal faster download times.

Another great feature of HTML5 is Web Workers. You can use them to execute long-running JavaScript code in a separate thread of your browser. This feature is great if you need to pass large amounts of data to the server side or if you need to perform intensive number crunching on the client. The HTML5 application cache can also bring performance benefits to your website. It is designed to allow you to run your web application offline and can be harnessed to improve your application’s load time.

In the next chapter, we’re going to take a look at image optimizations and how you can squeeze those precious bytes out of your images to substantially speed up your page load times.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset