It’s no secret that people are fascinated by speed–fastest car, fastest runner, fastest computer processor, even fastest website. In today’s tech industry, optimizing your website via responsive web design is a must to achieve top speed and performance. This is especially true as a fifth of the world’s population accesses the internet via mobile devices. Because of this, websites need the ability to quickly adapt to a variety of devices.
Companies that chose not to go responsive face great adaptation costs and, ultimately, performance suffers. This can be attributed to three things: loading performance, rendering performance and programming performance. In this article I want to focus on how to avoid the most popular mistakes people make, but first, I want to introduce you to a few unwritten rules, which define when an application can be called “fast“:
Time for the First Byte: 200ms - 350ms
DOM Content Loaded: 1000ms - 2000ms
JS Load Event Fired: 900ms - 2200ms
Total Download Size: 1MB - 2MB
DNS Lookup: 10ms - 20ms
HTTP Requests per page: 50 - 75
Shedding the Excess Weight
You can have a huge application with a lot of code but you’ll find that in most of these projects, your biggest problem ends up being with the images. They increase load time and the HTTP requests count. If you use a high quality transparent PNG files it can be even more of a headache. That is, until you start to use appropriate tools and learn how to organize image sets.
The first step to organizing these images is to properly prepare them. While it’s easy to optimize JPEGs, people often complain there is no way to optimize PNG images because the quality decreases. However, take a look at the old, but free “Color Quantizer“ application. This is a great tool for optimizing PNG images without losing quality. The images look sharp after the correct optimization. With this tool you can even optimize images that are above half a megabyte, at least two times and the loss in quality will be almost undetectable.
A few examples of optimized images:
http://www.htc.com/www/smartphones/ - there are 12 phone images, from which we can rip-off for about 20KB per single item. Math is easy here: 12 * 20KB = 240KB
An awwwards winners: http://epic.net/mmxiv/ Optimized landing page image will lose about ~75KB.
The absolute winner - http://www.olympicstory.com/ 190KB loss from one image.
Another way to optimize images is through sprites. Sprites allow you to reduce the quantity of HTTP requests, which are one of the key points for fast web page loading. For sprite auto generation using SASS and Compass I would recommend a plugin, which was written by my colleague Paul Gabronis. It‘s called “Easy Sprites“ and believe me – it‘s super easy. This plugin will help to not only increase the speed of your website but to increase your productivity. If people are interested, they can also try SVG sprites: http://css-tricks.com/svg-sprites-use-better-icon-fonts/.
For very large images you should use JPG progressive format or pre-loader. This will help to not block page rendering when page content is still loading.
If, for any reason, you can‘t use sprite images, try inline Base64 images. This also can reduce quantity of HTTP requests. On the other hand inline images are a bit heavier than normal PNG files, so be careful with them. If you are using Compass, you can convert images to Base64 easily:
.test-class {
background:inline-image("test-image.png") no-repeat 0 0;
}
If you are using CSS and your IDE is Visual Studio, this extension will help: https://visualstudiogallery.msdn.microsoft.com/a56eddd3-d79b-48ac-8c8f-2db06ade77c3.
CSS Optimization
Magical CSS snippet:
transform:translateZ(0)
. Web browser developers often disagree on how things should be implemented, so it’s no surprise that there is no meeting of minds when implementing a GPU acceleration feature in web browser engines. If the Gecko engine chose to accelerate everything, then WebKit developers gave you the freedom to choose it on your own. This is logical, because:This will give you a freedom to allocate device resources and to set priorities.
This will help to save device battery.
translateZ(0)
, mentioned before, is a hack that allows you to force GPU acceleration on an element without changing it. But be careful with it–its default behavior is not dedicated for this. In the future there are plans to have assigned CSS property for this. For more about this feature you can read this explanation.Converting JavaScript: It’s beneficial to convert JavaScript animations to CSS transitions/animations. This is especially true when you animate multiple items at once. You can see the difference here. Don‘t forget, that Firefox has some issues when animating more than 150 items at one time with CSS transitions/animations.
Optimizing expensive CSS properties: Properties like box-shadow, gradient, border-radius, outline, opacity have some interesting rendering behaviors that can slow down your UI.
Here is an example how box-shadow is rendered, with three different scenarios:
A – element will be rendered only with box-shadow property.
B – element will be rendered only with border-radius property.
C – element will be rendered with box-shadow and border-radius properties (A + B).
Let‘s take a look at how render time changes:
A render time – 0.19ms
B render time – 0.16ms
C render time – 0.73ms
One more interesting thing is how
box-shadow
is rendered, then value changes:box-shadow: 1px 1px
= render time 0.28msbox-shadow: 1px 2px 3px red
= render time 0.16msbox-shadow: 1px 2px 3px 4px
= render time 0.76msThis doesn‘t mean that you don‘t have to use these properties, but keep in mind, if you have performance issues–this information can be essential. Read this AirBnb post for more detailed information.
Using automated tests to search for less performing selectors: Here is one of the best tests. It can give you selectors that decrease scrolling speed.
Keep Things Simple
If you are adapting to less popular browsers – IE8 and lower or other outdated browsers–you are just aggravating your work, web performance and patched places are becoming heavier until they became unbearable. While IE8 is still on the market, most users and developers will be happier to see default web components that perform faster and this will help to save you money.
Custom select: http://jsfiddle.net/TKE6g/
Custom checkbox and radio: http://jsfiddle.net/t7jCL/
Something else to keep in mind is that you should pick web fonts carefully. Remember to limit font families and variations. You can reduce web loading time by only using essential fonts that are commonly used.
Optimization Essentials
In order to stay up-to-date with your website performance, remember the following essential tips:
Minify your CSS files and reduce file quantity to a minimum. Combine media queries and print style sheets in one file.
Don‘t use @import rule in your CSS files.
JavaScript files should be loaded only before closing body tag. Only break this rule in very specific situations.
Minify your JavaScript and CSS files (for automated minification you can use https://www.npmjs.org/package/grunt-contrib-uglify and https://github.com/gruntjs/grunt-contrib-cssmin).
Load your CSS files only in the Head tag , as soon as possible.
Load resources from a CDN (Content Delivery Network). If you are using require.js, the CDN usage will look like this:
requirejs.config({ baseUrl: "Scripts", paths: { /\* Load jquery from google cdn. On fail, load local file. \*/ 'jquery': \['//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min', 'libs/jquery-min'\], } });
Other MISC optimization ideas to have in mind:
Instead of using default jQuery onresize event, use this one: http://www.paulirish.com/2009/throttled-smartresize-jquery-event-handler/
Practical example: http://jsfiddle.net/c9Dfm/
Loading an IFrame from a remote source it can be a big headache. Loading IFrame from websites like YouTube or Vimeo can slightly decrease performance and block local resources from loading. This snipped will help you to prevent such problems:
$(document).ready(function () { $('iframe').each(function() { $(this).attr('src', $(this).data('src')); }); });
Comparison
To further demonstrate the benefit of optimization, I want to compare two small applications. Both are the same applications, but the first is not optimized and the second has some basic optimization (web font variation reduction, combined JavaScript and CSS into one file, delayed IFrame loading, optimized images).
I made performance measurements and took the average after testing each application ten times. The source code of these small applications you can find here on GitHub.
Results:
Not optimized
HTTP requests: 88
Dom ready event fire: 2,24sec
Window loaded event: 8,21sec
Data transferred: 3,2MB
Basic optimization:
HTTP requests: 74 (-12 requests)
Dom ready event fire: 1,07sec ~53% lower
Window loaded event: 6,63sec ~20% lower
Data transferred: 2,2MB 32% lower
As you can see, even with very minimal optimization, the difference is quite large. I hope this article provided useful information for your web optimization. If you are interested in learning more, contact us.