Chapter 11. Performance

One often-heard criticism of responsive design is that responsive websites tend to have poor performance—that is, they take longer to load and render.

For many responsive websites out there, that’s true, but it’s not because responsive sites are inherently slow; it’s because those sites were not developed with performance as a goal. There are a lot of techniques to make websites lighter and faster.

In this chapter, we’ll first talk a bit about why performance matters, and why performance should be a consideration as you’re designing a website.

Then we’ll go through, step by step, what happens as a web page is loaded and rendered in a browser, so you’ll have a better understanding of all the things that are going on and what can go wrong.

Next, we’ll look at how to test the performance of your site, to figure out what the areas are.

Finally, we’ll go into detail about what you can do to improve the performance of your website. Some of the areas we’ll look at are cleaning up your code, minimizing HTTP requests, compressing files, enabling browser caching, and removing JavaScript that blocks loading.

Note

One of the best resources for addressing performance on your website is Google’s PageSpeed Tools (https://developers.google.com/speed/pagespeed/). Some of the suggestions in this chapter are based on Google’s PageSpeed Insights Rules, and used according to terms described in the Creative Commons 3.0 Attribution License (http://creativecommons.org/licenses/by/3.0/).

Why Performance Matters

Studies have shown that users judge the visual appeal of a website in less than a fraction of a second, which is why first impressions are important. But what if a user’s first impression is 5–10 seconds of a blank screen, before she sees anything?

A 2012 study by Strangeloop of Alexa’s top 100 retail sites[6] discovered that the median load time for first time visits to those sites was 7.14 seconds.

Seven seconds doesn’t seem like a lot, but when you’re staring at a blank screen, it can seem like forever. Try counting to seven seconds right now to see how long it feels. Even if users bother to wait, the first impression they’ll have of the website is that it wasted their time. No matter how good it looks, that first impression will always remain in their minds.

But more likely than not, they won’t wait. Users expect a site to load in a couple of seconds. In a 2012 study by Econsultancy, 74% of mobile users abandoned a site after waiting five seconds for it to load.[7]

However, the most important metric isn’t how fast your website actually is, it’s how fast the user perceives it to be. Metrics can tell you how long it takes to load and render every part of a web page, but if users see things on their screens before the whole page is done loading, it’s going to seem faster.

Besides what your users experience on the website, there’s a less obvious—but just as important—reason to optimize the performance of your site: it will give you better placement in search results.

In 2010, Google announced that site speed would be a factor in its search engine ranking algorithms, for both desktop and mobile: slow sites would be penalized in search rankings. The reasoning was that site speed affects the user experience, and a faster site means a better-quality site—one that users will prefer over a slower site.

Performance as Design

Because performance is so essential to the user experience of a site, it needs to be considered a design element, rather than just a technical specification.

That means that from the start of a project, performance should be part of the project documentation, such as proposals, statements of work, and deliverables.

Designers and developers need to work together throughout the process. Otherwise you have designers coming up with great ideas but having no idea of the performance cost, and developers blindly implementing those ideas because that’s what they were provided with. Often, small tweaks to the design can dramatically change performance, but there needs to be room in the process to make those tweaks.

It’s easier to include the client in decisions involving performance if they’ve been told all along how important it is.

Connections

It’s easy to blame responsive design, but the truth is, we’ve just gotten into the habit of building bloated websites.

In the two decades since the Web came along, computers have swiftly been getting faster and more powerful. And our Internet connections, in our homes and offices, have just as swiftly increased in speed (many times over).

Our computers can do all sorts of magic things, so we want our websites to do magic things too.

As we’re designing or developing sites, we’re generally sitting in front of computers with pretty speedy connections in our offices or homes. It’s easy to forget that not everybody is using such a fast connection.

Remember dial-up? It seems archaic to even think about it. That screechy noise we had to listen to every time we connected to the Internet... It took a little while for everything to load, but we didn’t mind too much, because that was the only option. And it wasn’t even that slow, because websites were so much lighter a decade ago.

Today, only about 3% of Americans still have dial-up Internet access at home. That’s hardly anybody, right? Well, there are 300 million people in the United States, so 3% is only... 9 million. Hmmm. Well, perhaps that’s a few people we need to worry about. But forget about them for a moment, because the real issue we want to talk about is mobile Internet access.

While devices of all sizes have gotten more powerful, our connections—at least some of them—have gotten slower. So now what?

Balance

The issue is striking a balance. There are all sorts of amazing things you can do with HTML, CSS, and JavaScript to make your website look incredible and do incredible things.

But the goal of a website isn’t to look good, it’s to provide information and interactivity. And if your visual effects are slowing down your site so much that they’re getting in the way of the main goal, then you need to reexamine what you’re doing.

The Bloated Web

The first thing that needs to be pointed out is that slow performance isn’t an issue that’s unique to responsive design—it just tends to get noticed more on responsive sites because we’re paying attention to how they perform on mobile devices, which generally have slower connections.

Over time, websites have gotten more and more bloated.

According to the HTTP Archive, which compiles statistics based on thousands of the most popular websites, in the past two years the average page weight has increased from 807 KB to 1,492 KB.[8] That’s nearly a megabyte and a half of data being downloaded to view just one page on a website!

Of course, that includes everything that’s needed to render the web page: HTML, CSS, JavaScript, images, web fonts, Flash, and so on.

Whether or not your website is responsive, there are many things that you can do to make it faster, and most of what we’ll discuss in this chapter is applicable to all websites, not just responsive websites. Even if your site isn’t responsive, there will likely be people visiting it using mobile devices and slow connections, so do your best to make it as fast as is feasible.

It’s not that simple, though. Responsive design is just a tool, and whether or not using responsive design produces a good website is up to the designers and developers who work on the site.

Simply taking a desktop design and adding responsiveness to it will frequently result in bloated code. That’s why you’re often better off starting at the beginning and designing carefully and thoughtfully.

Note

To learn more about improving the performance of responsive websites, read Tim Kadlec’s article “Responsive Responsive Design” (http://24ways.org/2012/responsive-responsive-design/).

How Web Pages Are Loaded and Rendered

To understand all the things that affect the performance of a web page, we must look at everything that happens when a web page is rendered. Rendering is the process by which the browser reads the HTML, CSS, and other resources, and then displays a web page in the browser window.

This explanation is a bit simplified so that you can understand it without being an IT expert, but it covers all the major bits that have an impact on performance. It’s long, but bear with me.

Later in the chapter, we will go into how each part of the process affects performance, and what you can do to improve performance, but to start out, it’s necessary to understand how all the different parts of the process fit together and what order everything happens in.

Latency

First, you’re at your browser, either on your desktop/laptop computer or a mobile device. You type in a URL, or click on a link.

Latency is the amount of time it takes to connect to the Internet provider.

If you’re on a stationary connection (such as a broadband connection at your home or office), you don’t have to worry about this because you’re continuously connected to the provider.

But if you’re on a mobile network, there is a limited amount of bandwidth at any given point in time, so you don’t have a continuous connection; you’re only connected when you’re actively requesting or sending information to the Internet.

So, your mobile device needs to connect to the network in order to load a web page. To do this, the device contacts a local cellular tower and says it wants to start a connection.

Under ideal circumstances, the tower will reply right away and set up the connection. But circumstances aren’t always ideal, so this process could end up taking several seconds—and we haven’t even started loading the web page yet! Unfortunately, you (the website owner/developer) can’t do anything to speed up this part of the process for users, but you need to know that these delays can exist.

The speed of the original connection (latency) depends on how many devices are trying to get a connection at the same time. For example, if you’re at a major sporting event, or in a large city, it may take longer to connect because so many other people are trying to connect at the same time.

DNS Request

Once the connection is established, the browser sends out a request to the DNS provider, which is usually the Internet provider.

DNS (the Domain Name System) is what translates the URL into an IP address so the browser knows where to find the website. The DNS provider sends back the correct IP address, and then the browser knows where the website is hosted.

The browser is looking for the site located at a particular URL, such as http://www.example.com. However, websites are actually identified by the numerical IP address, such as 192.0.2.0, of the server they are hosted on.

Redirections

A URL doesn’t necessarily go directly to an IP address, though. Sometimes you have a URL that redirects to a different URL. For example, if you type www.washpost.com in your browser’s address bar, the text will actually change to www.washingtonpost.com as it loads the site.

The redirection happens as part of the DNS process before the browser is told the IP address of the actual website.

This is relevant to performance, because any redirects can add time to the loading process. This applies not only when you redirect from one domain to another, but if you redirect to a different subdomain on the same site, such as if you have it set up to add www to a URL (so example.com would change to www.example.com).

Having one redirect in the process, such as for the www, isn’t a big deal, but sometimes URLs are set up in a convoluted way so that there are multiple redirects to get to the actual site. This can increase the loading time of your pages.

HTTP Request

Once the browser finds out the IP address of the server where the website is located, the browser sends an HTTP request to the server, requesting that the server send the page located at the URL.

The HTTP request also contains additional information in the HTTP header (think of this as the metadata of the request). One of the key parts is the user agent, which identifies the requester’s operating system and browser.

In some cases, the website is set up so that the server will send back a different website based on the information contained in the user-agent string.

For example, if the website’s server knows that it’s a mobile browser making the request, it may send the mobile version of the website (an m-dot site) instead of the regular website. Unfortunately, the user agent cannot always be relied on as always correct, although it’s fairly accurate.

Sending the HTML File

When the server receives an HTTP request, it sends a response, which consists of an HTTP header along with the file requested (in this case, the HTML file).

In the response, the HTTP header may contain additional information to be used by the browser. One important bit is whether the browser is permitted to cache the resource, and how long it can be cached. This is information provided by the website’s server (you can adjust these settings on your site’s server), not information that is part of the HTML file.

You can see HTTP headers using the Developer Tools in Google Chrome, as in Figure 11-1. Go to the Network tab, and click on any resource in the first column. On the right panel, you’ll see the HTTP headers for the request and the response.

Decompression

Often, files such as HTML, CSS, or JavaScript will be compressed using gzip so that the file size is smaller and they will download faster.

When the browser sends its request, one of the HTTP headers tells the server whether the browser can accept compressed files (most modern browsers can). If the browser can accept a compressed file, that’s what the server will send. Otherwise, it will send an uncompressed file, which can take a bit longer.

Once the browser receives the compressed file, it will unzip the entire file right away.

The HTTP headers for The Washington Post website, viewed using the Google Chrome Developer Tools.
Figure 11-1. The HTTP headers for The Washington Post website, viewed using the Google Chrome Developer Tools.

DOM

The next thing that happens is that the browser parses the HTML, creating a Document Object Model (DOM). Essentially, the DOM is a representation of the web page as it will be displayed. The DOM starts out being the same as the HTML for the page. But if you have JavaScript events that change the content of the page, the changes will be made to the DOM, not to the HTML.

For example, you might have a script that allows you to click a “more” link to view additional text directly on the page. The HTML for the page doesn’t contain the additional text, and when you first load the page, neither does the DOM. But after you click the “more” link, activating the script, the additional text will be added to the appropriate place in the DOM and will be displayed on the page.

You can find a more detailed explanation of the DOM in Chris Coyier’s “What Is the DOM?” (http://css-tricks.com/dom/) on CSS-Tricks.

Rendering the <head>

Once the DOM is ready to go, the browser starts to render the HTML document. It goes one element at a time, starting with the very first element in the <head>.

External resources

Each time the browser gets to an element that’s a link to an external file (e.g., a CSS or JavaScript file), it loads the file.

Parallel loading

Each external CSS or JavaScript file requires a separate HTTP request (i.e., a request to the server).

Although older browsers can only load one file at a time, newer browsers can download more than one resource at the same time. This makes the process go a bit faster, but it can only do a few files at once, not all of them if you have a lot.

If the browser has cached the resources, they may not need to be loaded at all. Most of the time, when you load a web page, the browser will cache (or save locally) resources such as images, CSS files, and JavaScript files, so they don’t have to be downloaded again as you browse to other pages on the same site, or if you return to the site within a set period of time. This means the first page a user visits on a site will generally take longer to load than any subsequent pages, as nothing has been cached yet.

The amount of time particular files are allowed to be cached for is set on the website’s server, and can range from 24 hours up to a year.

Single-threaded execution

JavaScript is single-threaded, which means the browser can only execute (run) one file at a time.

Each <script>, starting with any that are in the <head>, is executed as it’s encountered. This includes both inline scripts and external scripts, which cannot be executed until they’re done being loaded.

At this point, as scripts are being executed in the <head>, the user is still looking at a blank page, because the browser has not gotten to the <body> HTML yet.

Rendering the <body>

Only after the browser has finished with the <head> can it start rendering the <body>.

It starts at the top and renders one element at a time. The browser needs to know what each element should look like, and where it will go on the page, so it looks at the CSS to figure out what to do.

Loading HTML images

When the browser gets to an <img> element, it starts loading the image file. For a large file, this might take a while, so the user may see an empty spot in the design until the image finishes loading.

It used to be common practice to specify the height and width attributes of each image in the HTML tag, to “reserve” a blank space of the correct size where the image is supposed to go. But in responsive design, your image may be different sizes depending on viewport width, so it’s no longer appropriate to do this.

The trade-off is that once the image finishes loading, the browser will only then know the dimensions of the image, and may have to reflow some of the page (move things around in the layout) to make a space for the image.

Loading background images

When the browser gets to an element that has a background image applied via CSS, it will start loading that image.

More JavaScript

You might also have JavaScript in the <body>, either as an external file or an inline script. The browser cannot render the page and execute a script at the same time. So, if it encounters a <script> within the <body> element, it will stop rendering while it executes the script, and then continue on with the rendering.

onload Events

After everything in the page has been loaded and rendered, the document executes any onload JavaScript events. onload simply means that the event will be triggered as soon as the page is finished loading.

Measuring Performance

You can test the performance of your website with some online tools that will give you an estimate of how long it will take your pages to download.

Mobitest (http://mobitest.akamai.com/m/index.cgi), from Akamai, is a great tool that can help you figure out how fast your website is. You enter the URL of your page, choose from a few different mobile devices, and request a test run. Everything goes through a queue, so you’ll have to wait a little bit, but when it’s done you’ll find out the average load time of the page in seconds and the average page size in KB, as you see in Figure 11-2.

The results of a speed test in Mobitest.
Figure 11-2. The results of a speed test in Mobitest.

For example, a test of Yahoo.com on an iPhone 4 had a load time of 5.41 seconds, and an average page size of 853.49 KB. Testing Google.com on the same phone showed a load time of 2.9 seconds and a page size of 359.47 KB.

You can also click on “View HAR file” to see a waterfall chart that shows the order the page assets load in, and how long it takes each asset to load. This will let you know if there are particular page assets causing a problem—for example, if a third-party add-on is significantly slowing down your site. Mobitest works like a proxy server, testing your site using a real phone, so it should give you pretty accurate results.

YSlow (http://developer.yahoo.com/yslow/) is another tool for analyzing page performance, as you can see in Figure 11-3. It is a browser add-on, or a bookmarklet for desktop or mobile browsers. When it analyzes a site, it will grade specific areas where problems commonly arise, and offer you suggestions for optimizing your site. For example, it might point out if you are making too many HTTP requests, or if you could save some KB by minimizing your CSS.

YSlow shows the grades for specific performance areas you should address.
Figure 11-3. YSlow shows the grades for specific performance areas you should address.

Other tools include WebPagetest (http://www.webpagetest.org) and Pingdom Website Speed Test (http://tools.pingdom.com/fpt/).

Cleaning Up Your Code

The first few things we’ll look at to improve your site’s performance are ways to clean up your code and make it take up less space.

Use Straightforward Code

This seems obvious, but write your code as straightforward as possible.

Don’t add a class or ID name in order to apply a style to an element if you can apply the style without it. For example, don’t do this:

<header>
<ul id="navigation">
...
</ul>
</header>

If there’s only one <ul> in your <header>, you don’t need an ID, and you can apply styles like this:

header ul { ... }

That one is pretty obvious, but extra classes/IDs have a tendency to work their way in during the coding process, and you many not realize they’re unnecessary until you go back and look at the code later.

Take advantage of the cascade to avoid repeating CSS. For example, if most of the text on your site uses a certain font, apply the font-family to the <body> element, rather than separately to <p>, <li>, and so on. Then you’ll only need additional CSS for the exceptions.

Go back and clean up your stylesheets. You probably have styles in there that apply to something on your site that no longer exists.

Although it’s best to keep your code straightforward while you’re writing it, it’s hard to predict what’s going to be necessary or not, so make sure to go back at the end to look for any pieces you can take out.

Minification

We add a lot of empty space as we write code, because it makes it much easier to read, but the browser doesn’t need all those extra spaces, line breaks, and indentions.

Minification is the process of removing these unnecessary characters from your files. For example, instead of:

p {
    font-family: Georgia, serif;
    font-size: 1.1em;
}
li {
    font-family: Helvetica, sans-serif;
    font-size: 1.2em;
}

the browser only needs to see this:

p{font-family:Georgia,serif;font-size:1.1em;}li{font-family:Helvetica,sans-serif;font-size:1.2em;}

In this example, I was able to remove 10 spaces, 2 tabs, and 7 line breaks—nearly 15% of the characters!

Of course it would be incredibly difficult to have to write your CSS like this, with no spaces. And you can’t simply search for and replace all the spaces and line breaks in a document—some of them actually do need to be there (e.g., applying a style to nav li wouldn’t work if the browser saw navli).

Thus, there are tools called “minifiers” that you can use to minify your CSS, JavaScript, or HTML files before uploading them to your web server, removing comments (unnecessary for the browser) as well as whitespace.

There are a few ways to make this happen.

First, for a very small site with infrequent edits, you could minify each file individually before uploading it to your web server. If you want to minify one page at a time, there are several websites that can do this via a simple form—try CSS Minifier (http://cssminifier.com) or YUI Compressor (http://refresh-sf.com/yui/), or search online for a “CSS minifier” or “JavaScript minifier.” But for many sites, minifying the files manually would be too much extra work.

If only one person is working on a site, it’s easy—if all your files are saved on your own computer, you can use a preprocessor or an app such as LiveReload (http://livereload.com) or Mixture (http://mixture.io) to minify your files before uploading them to a server, allowing you to always edit the original file with spacing and comments intact.

If you collaborate on files, it’s a little trickier, as everyone will have to work from the same original files, rather than downloading the files from the server to get the latest versions.

You could set up your server to automatically minify files on the fly, by using a tool like Minify, which works on PHP, but the extra processing time tends to offset the benefit of sending a smaller file, so it’s not recommended.

Minimizing HTTP Requests

An HTTP request is what happens each time the browser needs to request that the server provide a file.

Each file, such as an image, stylesheet, or web font, requires a separate HTTP request. For each one, the “round trip” from the browser to the server and back may take a small fraction of a second on broadband, or up to a full second on a mobile connection.

One of the most effective ways to improve the performance of your website is to minimize the number of HTTP requests that are made to the server. You can do this by combining your CSS, JavaScript, or image files.

You also need to make sure any third-party code embedded on your site (e.g., social media widgets, ads, or analytics) isn’t requesting a large number of files.

Concatenation

One easy way to reduce HTTP requests is to call fewer CSS and JavaScript files by using concatenation to combine them.

Again, it might be more convenient for the developer to separate everything out into separate files that serve different purposes, but because each file requires a separate HTTP request, this can increase the load time of the page.

If you decide to have multiple files for development purposes, you can combine the multiple files into one or two files before uploading them to the server. Many of the same apps that you use for minification will also do concatenation, such as YUI Compressor (http://yui.github.io/yuicompressor/) or Minify (https://code.google.com/p/minify/). You can also use something like QuickConcat (https://github.com/filamentgroup/quickconcat), which works sever-side if you’re using PHP.

And obviously, some files can’t be combined—for example, if you’re using media queries in stylesheet links to target different stylesheets to different screen sizes, or if some stylesheets are only called on certain sections of the site.

And of course it would be easier to simply decrease the number of stylesheets by combining the code in a few files rather than many. You can use comments to separate sections for easier reference, and use a minifier to strip out the comments for the live version.

However, don’t go overboard. Browsers do have the ability to download a few files at once in parallel, so having a couple of CSS files may be better than one very long one.

Third-Party Code

Anything that’s being downloaded from another domain can cause a delay. This might include embedded videos, maps, ads, or analytics.

The main issue is that every additional domain adds another DNS lookup during the process of loading the page. This is avoided if all the content is coming from the same domain.

A secondary issue is that you’re relying on someone else’s site to provide the content. If that site is slow—or not available—your site can get held up or stuck while trying to load the assets.

One of the most common culprits here are social media widgets—you know, those little icons for Facebook, Twitter, and other sites, with a “Share This” link.

These are often implemented on the page using third-party software that allows you to track how many users click on each action, on any given page. The problem is that usually they are made up of a ton of code.

Figure 11-4 shows what the social media widget looks like on The Washington Post website.

The social media widget from The Washington Post website.
Figure 11-4. The social media widget from The Washington Post website.

It looks simple enough, but part of the problem is the “More” link at the bottom, which includes links to several other social media sites. The code is not optimized—each option is a <div> and a <span> inside a <li>, along with several classes and an onClick event.

That’s not to mention all the icons, which at least are in only one image sprite, although it’s a whopping 22 KB.

Think about whether you really need such a complex widget. Users will still be able to share your content without it. Oliver Reichenstein wrote a great blog post called “Sweep the Sleaze” (http://ia.net/blog/sweep-the-sleaze/) on the Information Architects Inc. website that details the reasons why social media widgets don’t add value to your website.

But if you do need to keep widgets like this, which are usually made of JavaScript, definitely think about whether their loading can be deferred to after the page has rendered (later in this chapter we’ll talk more about deferring JavaScript). Sure, it will pop up on the page a second later, but users generally will at least have started reading the page before they make a decision to share.

Note

If you really need that social widget, check out SocialCount (http://filamentgroup.com/lab/socialcount.html) from the Filament Group. It’s a jQuery plug-in that lets you add social widgets in a way that won’t take a big bite out of your performance. The JavaScript and CSS are only 3 KB.

Image sprites

Image sprites, as we looked at in detail in Image Sprites in Chapter 6, are a way to reduce the number of files to download by combining several small images into one large image.

This is most effective when the images are related to each other (e.g., a set of icons that are displayed together).

Server Stuff

The next few things we’ll look at have to do with server settings, so if you’re a designer, they may not be areas that are directly under your control—and whoever does have control may not realize they’re important to the performance of your website. But that doesn’t mean you can ignore them. It’s definitely worth figuring out who you need to talk to so that these changes can be made.

Avoid Redirects

An HTTP redirect is when a user loads a page from a URL that is different from the actual URL of the page, and the browser is redirected to the correct URL. This is something that would be configured on your web server, such as by using .htaccess in Apache, or by using functionality in your content management system (CMS).

The most familiar kind of redirect is when a website can be accessed from alternate domains. For example, if you type www.newyorktimes.com into your browser, once the page loads, you’ll see in the address bar that you’re actually viewing www.nytimes.com.

You may also use redirects when the URL of a page has changed and you want to make sure users who go to the old URL will still get to the correct page, or if you want users directed to a particular subdomain of the site.

On sites with separate mobile and desktop versions, it’s common to use redirects to get users to the correct version of the page for their device—for example, a redirect from www.example.com/pagename to m.example.com/pagename. (One of the advantages of responsive design is that you don’t have to worry about this type of redirect.)

Obviously, there are many occasions when you need to use HTTP redirects. But keep in mind that they do have a performance cost.

Especially make sure that any files used by your website, including images or stylesheets, are being called using the correct URLs. As a start, use relative links (/images/file.jpg) rather than absolute links (http://www.example.com/images/file.jpg) when linking to files on the same domain.

If URLs on your site change during a redesign, change the actual links on the site whenever possible, rather than using redirects to get users to the right place.

Avoid having more than one redirect chained together.

File Compression

Compression can be used to reduce the size of all the files being sent.

Most web servers are able to use the gzip format to compress files before sending them to the user’s computer. When a browser requests a page, it will tell the server whether it can process compressed files. The server will send compressed files to browsers that can handle them.

You can use GIDZIPTest (http://www.gidnetwork.com/tools/gzip-test.php) to check whether a web page is compressed and, if so, to compare the file sizes. For example, if I test the front page of The Washington Post website, I see that it is gzipped, with a savings of 69.5% (300 KB to 92 KB).

You can enable server compression as a configuration on your web server. For example, Apache sites use mod_deflate (http://httpd.apache.org/docs/current/mod/mod_deflate.html). Your web hosting provider may offer this as a setting on your control panel, and it may be enabled by default. If you’re on a shared host, you may not have the ability to turn compression on and off.

All of your HTML, CSS, and JavaScript files should be compressed.

Browser Caching

A lot of the files that are downloaded to display a web page will be reused as the user browses to other pages on the site. This includes stylesheets, images, JavaScript files, and fonts.

Browser caching means that the browser can temporarily store these files on the user’s computer for a specified period of time, so that as the user visits other pages on the site, or if she comes back to the site another day, the browser doesn’t have to reload those files.

Not only can this decrease the load time of a page by reducing the amount of data that needs to be downloaded, but it also decreases the bandwidth required to download the page, which is helpful to mobile users who have plans with limited bandwidth, or have to pay per MB.

Browser caching doesn’t necessarily happen automatically. The browser doesn’t decide what to cache; rather, your web server has a set of rules that tell the browser if and when it’s all right to cache certain files.

How you set up browser caching depends on the type of web server you have. For example, in Apache you would edit the .htaccess file.

Your hosting may have browser caching turned on by default. If you aren’t sure, you can use Google’s PageSpeed Insights (http://developers.google.com/speed/pagespeed/insights/) to check.

You can set different expiration times for different types of files. For example, you could specify that .jpg files expire after one month. The browser would then save any .jpg files, and not try to reload them until a month after the first time they were downloaded.

Choosing how long to allow files to be cached depends on the types of the files, and how frequently you update those file types on your site. For example, you probably don’t change image files on your site often, so it would be safe to allow them to be cached for a long time. If you do need to change an image file, such as changing to a new version of the site logo, you could simply give the replacement image a different filename, so the browser would be forced to download it.

If you change your stylesheets very frequently, you may want to give them an expiration of one day. That would allow the user the benefit of not having those files redownloaded as he browses the site, but changes would show up for the user within 24 hours after you make them.

Keep in mind that the browser’s cache is likely limited in size, so if a user visits a lot of websites, not all assets with long expiration times will actually be stored for that long. This is especially an issue on older mobile devices, which have very limited caches. But even with minimal cache storage, files will be kept in the cache during the user’s current visit to the site, decreasing the load times of every page except the first one visited.

Generally, static resources should have an expiration of at least a week, and longer if possible. The maximum allowed is one year. Only assets that change many times a day, such as the front page of a news website, should be set with no caching at all. Even allowing a few hours of browser caching on frequently changing resources can decrease the load times of a website.

JavaScript

If you aren’t familiar with JavaScript, you need to understand a bit about how it works. The first sections here, What JavaScript Does and How It Works, give a little background. If you’re already familiar with JavaScript, feel free to skip to the following section, Blocking Javascript.

What JavaScript Does

You already know that your website is built in layers, starting with HTML for the content, and then a second layer, CSS, for presentation.

The third layer is JavaScript, which is for interaction, or behavior. It’s an optional layer—you can create a perfectly good website without any JavaScript at all, as long as you are only building something for users to read and look at, and perhaps have only basic interactions with.

Some of the common things that JavaScript is used for are validating form field entries, allowing the page to load new content without reloading the whole page, and the animation of page elements.

JavaScript is a client-side programming language. That means that all the JavaScript code has to be loaded by the browser (the client), and the browser does all the work of making things happen. This is in contrast to a server-side language like PHP, which does things to the page on the server before it is even sent to the browser.

How JavaScript Works

JavaScript can be included in either your HTML page, or as a separate file with the .js extension (linked from a <script> element in either the <head> or the <body>).

After the browser loads an HTML document, it starts at the very top of the <head> and loads/renders/executes each element as it encounters it. So, if the first element in the <head> is a link to a CSS file, it loads the file before moving on to the next element.

When the browser encounters JavaScript—either a link or an inline script—it loads and then executes the script before moving on to the next element.

So, if you have scripts in your <head>—either inline or links to separate JavaScript files—the browser will execute these scripts before it even gets to the <body>, and before it starts putting content on the screen! That means your users will be looking at a blank screen while the scripts run.

However, that doesn’t mean that when this JavaScript executes, it’s actually making anything happen.

Most JavaScript is triggered by an event. For example, you might see onclick—that means that whatever that bit of JavaScript does, it’s not going to happen until the user clicks on a specified element. onload means that the JavaScript does its thing when the page is done loading. Another example is having a script that validates form fields when the user clicks the submit button.

Much of the JavaScript in a web page is simply getting everything set up for something that will happen later, via an event like onclick.

Unfortunately, these scripts can cause a lot of problems, because depending on where on your page you add or link to JavaScript, it can block the rendering of the page, slowing it down considerably.

Additionally, the way that browsers work means that the browser can’t be rendering the page and executing a script at the same time. So although a browser can kind of do more than one thing at once (it’s complicated...), if it encounters a script, it has to stop any rendering while it’s executing the script.

Blocking Javascript

JavaScript that blocks the loading of page is sometimes called blocking JavaScript.

Because the browser has to run the JavaScript as it encounters it, the browser may be forced to run all the JavaScript before it renders the HTML and CSS, even if doesn’t need most of the JavaScript until after the page has finished loading.

If you aren’t sure whether any of your JavaScript is blocking rendering, try Google’s PageSpeed Insights (http://developers.google.com/speed/pagespeed/insights/), which will tell you if your site has any blocking elements. See Figure 11-5 for an example.

PageSpeed Insights will tell if you if any of your JavaScript is blocking the rendering of the page.
Figure 11-5. PageSpeed Insights will tell if you if any of your JavaScript is blocking the rendering of the page.

To keep your JavaScript from blocking the rendering of the page, you should make sure that as the browser loads and renders the page, it’s only loading the JavaScript that’s necessary to display what the user will first see on the page. All other JavaScript should be loaded after the page is rendered.

Load above-the-fold code first

If JavaScript is needed to display the section of the page that is “above the fold” (i.e., visible on the screen before the user scrolls down), that script should be loaded right away, as the page is loading.

Other JavaScript can be deferred, as we will address in the next section. This would include any scripts that are only needed after the page loads (such as for onclick events) or scripts that apply to content that’s far down the page.

Think carefully about whether each script is actually needed right away, and whether deferring it is an option.

With responsive sites, you may have JavaScript polyfills or feature tests that make your site work on older browsers (i.e., making media queries work in older versions of IE). These scripts need to be in the <head> because they’re necessary to render the pages in those browsers.

Inline scripts

If you have small scripts, they can be included inline in your HTML, so that the browser will not have to load additional resources.

The trade-off here is the lack of caching. If you include the script inline, it will need to be loaded every time the page is loaded. So this might not be a good idea for large scripts, or for scripts that are needed on every page of your site, but if you have something special just on the front page of your site that needs JavaScript, including the script inline may be a good idea:

<head>
    <script type="text/javascript">
        ...
    </script>
    ...
</head>

If your site only has a little bit of JavaScript, it’s generally best to include it inline instead of adding a file that needs to be downloaded.

Delay loading

For all the other scripts that the page won’t need until later, you can delay loading until after the page is rendered by moving them to the end of the page, right before the </body> tag.

These scripts will no longer be blocking the page rendering. Only after the last HTML on the page is rendered will these scripts start to load and then execute.

Defer execution

Something a little trickier is using the defer attribute on your <script> element. If you use this on a JavaScript link in your <head>, the browser will still load the file when it first encounters it, but will defer executing the file until after the page is rendered.

This is a Boolean attribute, which means if the attribute defer is present it’s turned on, and if the attribute is not present, it’s turned off:

<script type="text/javascript" defer>
    ...
</script>

This will work in all current browsers except Opera Mini. See “Can I use defer attribute for external scripts?” (http://caniuse.com/script-defer) for more details.

Note that this only works on external scripts (links to JavaScript files), not on inline code.

Generally, you’re better off just moving your JavaScript to the end of the HTML document. There’s no point in having the JavaScript load before the page is rendered if you aren’t planning to have it execute until after the page is rendered.

Asynchronous loading

Something new in HTML5 is the async (asynchronous) attribute.

When you add this as an attribute to your <script> element, the browser will go ahead and start loading the JavaScript file when it first encounters it in the <head> or <body>, but the difference is that the browser will not put all the other loading and rendering on hold while it waits for that particular script to load and execute.

Instead, it will load the script at the same time it is loading other resources (if appropriate), and then will execute it at the first chance it gets (i.e., when it’s done loading).

Note that this only works on external scripts (links to JavaScript files), not on inline code.

This is also a Boolean attribute, so if the attribute async is present it’s turned on, and if the attribute is not present, it’s turned off:

<script async src="example.js">
    ...
</script>

This is supported in the most recent versions of all browsers except Opera Mini.

Generally, if you are putting a script in the <head> because it’s needed to render the page, you should consider including the async attribute, with one exception: don’t use async if you have multiple scripts that need to execute in a particular order, such as if one is dependent on another. Each one will render as soon as it’s loaded, but they may not finish loading in the same order as you placed them in the <head>, and therefore they may not execute in that order.

One scenario where you would particularly want to use async is when you’re loading JavaScript files from a third-party source (such as when you have embedded content like a map or ads). That way, if there is an issue with loading files from the other website, it won’t keep everything else on your site from loading.

Loading only necessary code on each page

Additionally, you should make sure you’re not having every page load all the JavaScript for the site if it’s not needed on that page.

This is pretty common—the <head> will link to all the script files used on the site, even if certain ones are only used on the front page, or in particular sections of the site like ecommerce pages.

Although caching means that the script files won’t be loaded over and over, the first page the user visits on the site will be much slower because all the script files will have to be downloaded.

Using HTML/CSS instead of JavaScript

Something that you might not be aware of: with HTML5 and CSS3, you can do a lot of things with plain HTML/CSS that you used to need JavaScript to do.

For example, if you have a form with a date field, you used to need JavaScript to create a little pop-up calendar where the user can pick a date. In HTML5, there’s a new date input type that automatically creates a calendar based on browser default styles, without the need for any JavaScript (although it’s not supported in all browsers yet).

You can also use CSS to do things like make an image change to a different image when you hover over it.

In most cases, using HTML or CSS instead of JavaScript will help your performance. It can save loading a lot of code—creating and styling a calendar pop up is pretty involved, but if the browser already knows how to make the calendar, you only need <input type="date">.

However, HTML and CSS are not always a better choice. For example, you can do some pretty detailed animations using purely CSS—but sometimes the same effect can be created in JavaScript with less impact on performance. You need to look at each situation individually to decide the best approach.

And sometimes, using JavaScript for some fancy effect might be not worth the performance trade-off at all. Remember that performance is part of your design, too.

JavaScript Libraries

Using JavaScript libraries or frameworks can be another cause of bloat on your site.

A JavaScript library is a collection of prewritten JavaScript that makes it easy to write scripts for your website. Basically, it sets up a bunch of common functions that you can use on your site, so you only have to write a single line of JavaScript, rather than having to write all the JavaScript from scratch.

There are many different JavaScript libraries, with the best known being JQuery (http://jquery.com). A JavaScript framework is similar to a library, only with more capabilities.

The problem with adding a JavaScript library to your website is that you may only be using a small part of its functionality—but you’re stuck with all the other code in the library that you don’t need.

If you’re using a JavaScript library on your website, look at whether you really need a whole library. You can now find a lot of micro-libraries or micro-frameworks, which are much smaller (generally 5 KB and under) and only contain the code to do one particular task. Visit the Microjs (http://microjs.com) site, which has collected a list of hundreds of them, and allows you to search for exactly what you need.

Another option, of course, is to just write the JavaScript you need, instead of relying on someone else’s prewritten code.

CSS

As mentioned earlier, the first step with CSS is to minimize the amount of CSS you need. Use straightforward code and don’t repeat things unnecessarily.

CSS can also block rendering of the page. The browser will wait until all the CSS files are loaded before it starts rendering the page. It needs the CSS to know how and where to render each element.

One thing that you can do to speed up the loading of stylesheets is to use <link>, which will allow stylesheets to load at the same time, rather than @import, which will make them load sequentially.

Another thing you can do is delay the loading of CSS that isn’t needed for the initial page load (above the fold) by moving it to the end of the page, right before the </body> tag, just as you can do with JavaScript.

And if you have a lot of style rules that are only applicable to certain sections of the site, put those styles in a separate stylesheet that is only loaded on those pages.

CSS Frameworks

Using a CSS framework can cause a similar problem to using JavaScript libraries—you end up with a lot of code that you don’t actually need. Frameworks take into account all the possible things that a site might need to do, and they include code for all of that. As such, they’re far more complex than is needed for most websites that use them.

If you use a framework, such as Bootstrap or Foundation, to build your site, be aware that this is an issue.

The CSS in frameworks is generally easy to follow, so you should be able to go through and pull out broad sections of CSS that you know you won’t be using.

For example, if your website doesn’t contain any data tables, you can remove all the CSS referring to tables. Of course, you can always add this CSS back in later if you decide to add tables to your site.

You can save some more code, although with a bit more of a time investment, by going through and removing any specific classes you aren’t using on the site.

Tip

Move any unused framework CSS to a file named unused.css and keep it on the server with your other CSS files, so you’ll have this code handy if you do need to add any of it back in. It doesn’t matter how much code is in this file, because it won’t be downloaded with the rest of the site.

Additionally, make sure you aren’t duplicating CSS rules. The framework will provide values for pretty much everything. If you need to change something, such as the font-size for <h1>, don’t just add that CSS on the end. Instead, find the <h1> in the framework stylesheets and replace the value. Adding a separate declaration at the end not only adds unnecessary code, but it also can create confusion for developers who are trying to edit the stylesheet later.

Finally, although frameworks can come in very handy if you need to get a site up quickly, or if you need to create a website using staff that aren’t experienced developers (e.g., for nonprofits, small businesses, or hobby projects), you’re never going to get a site that’s as lean as one that is created from scratch.

Hosting

Where you host your website can certainly affect the loading time of your site.

If you only spend a few dollars a month for budget hosting on a shared server, your site is likely to be slower than if you are paying big bucks for a dedicated server and a better data connection. But more expensive doesn’t always mean better. Shop around, and look at customer satisfaction ratings for the various hosting companies.

Additionally, if your hosting plan has a bandwidth limit, the provider may throttle the speed of your site after you pass the limit (or disable your site entirely).

Content Delivery Networks (CDN)

You can use a content delivery network (CDN) as part of your web hosting solution. When using a CDN, instead of having all of your website files hosted on one web server, copies are hosted on servers at data centers in various geographic locations. When content is requested from your website, the requests are routed to the most optimal servers, based on physical location, current web traffic patterns, and so on.

This can increase the performance of any site, although it is most particularly useful for live, streaming content, or for sites with a high volume of traffic.

A site may choose to host only part of its content on a CDN. For example, a high-traffic ecommerce site may host all of its images on a CDN, because the site is very image-heavy, but host the rest of its content on regular hosting.

You can purchase CDN service either as an add-on from your web host, or from a separate company, typically an Internet service provider (ISP). Prices can start as low as $10/month for very small websites, up to thousands of dollars each month for very large sites.

Content Management System

Your content management system (CMS) might also be slowing down your site. This is more of an issue with enterprise CMSs than with basic CMSs like WordPress or Drupal.

Unlike just sending a plain HTML page when requested, a lot more has to happen for a CMS to send a requested page to a browser. Your entire website is contained in a database. A bunch of queries will run to piece together all the separate elements of the page on the fly—navigation, content, plug-ins.

Ideally it will happen very quickly, but a lot of things can go wrong and add delay.

Studies have shown definite performance differences among CMSs, so you should research performance when choosing a CMS.

If you already have a CMS, check all the settings to make sure you’ve done everything you can to improve performance.

Always make sure you have the most recent version of your CMS and any plug-ins—outdated software is likely to run slower, and may cause conflicts that add delay.

Conditionally Loading Content

You know that you need to make the same content available to all users, no matter what devices they’re using. But that doesn’t mean all the content needs to be available on the same page at the same time.

For example, you may have supplemental content that in a wide-screen view would easily fit in a sidebar. However, on the narrow-screen view, you don’t want to take up a big chunk of screen space displaying the content—but you still want to give the user the option to view it.

That’s where conditional loading comes in. This technique uses JavaScript to query the width of the browser window, similar to a CSS media query, and then only run a function to display the content if the screen is a minimum size.

Note

It’s acceptable for users to see different content depending on the size of their screen, as long as they can access the content in another way—in this case, the small-screen users just need to click a link to see the headlines.

Jeremy Keith described this technique in “Conditional Loading for Responsive Designs” (http://24ways.org/2011/conditional-loading-for-responsive-designs/) on 24 Ways.

Using the example in Keith’s article, let’s say you want to provide links to current Google News stories about your topic, which is cats.

On the small screen, you don’t want to include all the news stories, so you can start with a simple link to the Google News search results for your topic:

<div id="newsresults">
    <a href="http://www.google.com/
    search?q=cats&tbm=nws">Search Google News for Cats
    </a>
</div>

You would then add a JavaScript function at the end of the page that would replace the contents of that <div> with the Google Search results (check out Keith’s article if you want to see the code to do that), but only if the page is wide enough:

<script>
if (document.documentElement.clientWidth > 640) {
    searchNews('cats'),
}
</script>

If the viewport is wider than 640 pixels, the searchNews function will run and will change the newsresults <div> to display totally different HTML, with titles, links, and descriptions for several news articles, as you see in Figure 11-6.

Example of conditional loading.
Figure 11-6. Example of conditional loading.

One thing you need to keep in mind is that this only works if the browser can run JavaScript. But that’s not a huge deal, because those users who don’t have JavaScript will just get the default (small-screen) content—i.e., the link instead of the list of stories. They won’t actually be missing anything.

Another thing to be aware of is that unlike CSS, which will continually re-render the page if conditions change, your JavaScript function will only run once. So if the width of the viewport changes, such as if the device is turned from portrait to landscape view, this part of the layout will not adapt to fit the new viewport size, in the way that CSS would via media queries.

And of course, using this functionality means that the small-screen users are loading a bunch of JavaScript that they don’t need. But if that saves them from loading a larger amount of content that doesn’t need to be on the page, it may be a good trade-off.

Reflows and Repaints

Once the browser is totally done rendering the page, there’s still more that can happen.

Sometimes the visual appearance of an element will change after the page is loaded. A simple example is when the color of a link changes on hover. When the browser needs to make a change like this, it’s called a repaint.

Other times, the layout of the page will change. For example, when the user changes the size of the browser window (or rotates the device from portrait to landscape), flexible elements will change size, and their contents, like text, will move around to accommodate the change. A layout change is called a reflow.

When we talk about “performance” in the context of responsive design or mobile websites, we’re generally referring to the amount of time that it takes the page to load. But changes to the appearance of the page after it’s loaded can also go slowly or quickly, depending on how the code is written.

These examples are pretty simple, and the user will likely feel like the changes happened immediately. But there are many other things that cause repaints and reflows, such as when you have complicated CSS animations on the page, or when you are manipulating the page with JavaScript, and there may be a noticeable delay before such changes are completed.

This isn’t specific to responsive websites, and it’s fairly technical in nature and beyond the scope of this book. But in the context of designing for mobile devices, you need to be aware that mobile devices tend to have less processing power than desktop computers, so repaints and reflows may be significantly slower and can cause issues that you didn’t encounter while developing the site on your desktop computer.

To learn more about this topic, check out Nicole Sullivan’s blog post, “Reflows & Repaints: CSS Performance Making Your JavaScript Slow?” (http://www.stubbornella.org/content/2009/03/27/reflows-repaints-css-performance-making-your-javascript-slow/).

RESS

RESS stands for responsive design + server-side components, and it’s a bit controversial. This is the idea that you can make a site that uses responsive design, but also uses server-side solutions to only send the code and files that are needed by any particular device.

So, although you only have one set of code for a site, and that code will allow the site to respond to all viewport sizes, certain parts of the site may be implemented differently depending on the device used to view it. Luke Wroblewski describes RESS in detail in his 2011 article, “RESS: Responsive Design + Server-Side Components” (http://www.lukew.com/ff/entry.asp?1392).

To understand how this might work, imagine a responsive site that has a drop-down navigation on small screens, and a horizontal nav on wide screens. The HTML is the same for both, but media queries allow you to apply different CSS depending on screen size, to make it look different on the screen.

With RESS, the server would check whether the device is mobile or not, and send a different snippet of HTML and/or CSS for the navigation to mobile and nonmobile devices. So, each device would only get the code that it needs, compared to responsive design, where every device has to download all the code, whether it’s needed or not.

RESS requires using backend programming (such as PHP), not just HTML/CSS/JavaScript, so it’s more difficult than basic responsive design.

Besides detecting whether or not a mobile device is requesting the page, a server can also detect features, and send different code based on that. You can also do feature detection with JavaScript using Modernizr (http://modernizr.com).

Example of RESS

The University of Notre Dame website uses RESS, in addition to responsive design, to serve different content to desktop and mobile users.

The desktop version of the site has each of the main sections all on one page—About, Academics, Admissions, and so on. You can see on the left of Figure 11-7 the top of the page for the desktop site, with the Admissions section just below the main section. If you resize your desktop browser to 320 pixels and load the site, as in the center image, you still get all that content, although media queries have rearranged everything into one column. The image on the right shows what you get when the site is loaded on a smartphone—that’s all of it.

Mobile phones are served an entirely different version of the University of Notre Dame’s website.
Figure 11-7. Mobile phones are served an entirely different version of the University of Notre Dame’s website.

On the mobile phone, you still get access to the main sections, such as Admissions, but now each is on a separate page instead of further down the main page. And you don’t have content parity, because much of the desktop site is missing on the smartphone version.

I personally don’t like sites where all the content is on one page and accessed by anchor links, making it seem like there are separate pages when there really aren’t. It’s easy to get lost on the page, and if you want to share particular content, you can’t simply copy the URL from the address bar of your browser, because it’s the URL of the home page. (This page doesn’t even use real anchor links, which would give you an add-on at the end of the URL that would allow you to link to a particular section of the page, such as #admissions.)

I’m glad they aren’t giving all that content on one page to mobile users, because it would be impossible to navigate through the page on a small screen. But I don’t think they need to give desktop and laptop users all that content on one page either. Not only is it confusing, but it means a heavy page weight, and not everyone with a laptop has a fast connection—especially students who are toting their laptops around campus and may or may not be getting a good WiFi signal.

Summary

Website performance needs to be thought of as part of a website’s design, because it has a big effect on the site’s user experience. You’ll do a better job of optimizing performance if you are thinking of it from the start of a project, rather than trying to fix performance issues at the end.

There are many tools you can use to measure performance, which will show you specifically what is slowing down your site and tell you what you need to fix.

To start off, write good code—HTML, CSS, and JavaScript. Your code should be straightforward and not repetitive. You can use minification to decrease the size of your files, removing extra unnecessary space.

One of the most effective ways to improve the performance of your website is to minimize the number of HTTP requests that are made to the server. You can do this by combining CSS, JavaScript, or image files. Third-party code may also be making excessive numbers of HTTP requests, so double-check any plug-ins or other code you’ve added to your site.

Looking at server settings, start by setting up your site in a way that avoids unnecessary redirects. You can also check your server settings to make sure you’re compressing files and allowing for browser caching.

JavaScript can have an impact on your site’s performance, especially if your JavaScript is blocking site loading. You can fix blocking issues by inlining scripts, or delaying loading or execution of JavaScript.

Make sure to only load the JavaScript and CSS you need on any particular page, and replace scripts with HTML/CSS where possible.

Your hosting can also affect performance. Make sure the company and plan you choose for your hosting has a good reputation for performance. You can use content delivery networks to speed up your site, and make sure your content management system isn’t slowing it down.

Conditionally loading content can help with performance, as can using RESS (responsive design + server-side components).

Good performance comes from putting a lot of thought into how your site is put together.



[6] Strangeloop’s Fall 2012 “State of the Union: Ecommerce Page Speed & Web Performance” (http://www.strangeloopnetworks.com/resources/research/fall-2012-state-of-the-union/success/).

[7] David Moth, “Mobile Websites and Apps Optimization Best Practice Guide,” Econsultancy, October 23, 2012 (https://econsultancy.com/blog/10936-site-speed-case-studies-tips-and-tools-for-improving-your-conversion-rate).

[8] For more information, see “Interesting stats” (http://httparchive.org/interesting.php?a=All&l=Jul%2015%202011) from the HTTP Archive.

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

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