Static sites: tuning and optimization

    static sites

    We continue the cycle of publications about static sites based on our cloud storage (see previous publications here and here ). Today we will discuss in detail the issues of their fine-tuning and optimization.

    The main criterion for the excellent work of the site from the point of view of the user is, of course, the speed of loading components. If the site, for one reason or another, takes too long to load, this inevitably leads to the loss of visitors who are bored of waiting. To make the site fast and convenient, you need to do some work to optimize it.

    Below we will give a number of recommendations with which you can increase the speed of a static site located in our repository.

    Tip 1. Use the power of CDN


    We already wrote about connecting to our cloud-based CDN storage from Akamai . CDN stores all static content (images, text files, JS, CSS and so on) on caching servers scattered around the world (see map here ).

    When accessing a web page or its resources, the request will be processed by the caching server geographically closest to the client. Using CDN helps to increase the speed of loading the site for both stationary and mobile devices.

    By default, all data is cached in the CDN for 24 hours. Recently, a new feature has been added to the repository, with which you can clear the CDN cache at any time:

    Cdn cache

    To do this, just go to the tab shown in the figure and enter in the form the addresses of the pages whose cache you want to clear. The cache will not be cleared immediately, but about 15 minutes after the form is submitted.

    Tip 2. Don't forget about caching settings.


    Any web page includes many different elements: images, scripts, style files, and so on. The first time a user visits a page, he receives all these elements by completing a series of HTTP requests. To avoid reloading a large number of files, caching is used.

    The caching model used in the HTTP protocol is based on the so-called validators - special headers used by the client to ensure that the cached document is still relevant. Thanks to the validators, the client can check the status of the document without transferring the entire cached copy to the server. In turn, the server transmits a document in the response only if the validator received by it indicates the presence of an outdated copy in the client’s cache.

    Validators are divided into strong and weak. Strong validators appeared in HTTP / 1.1. They are called so because they change whenever the file changes. These include the so-called ETags (entity tags). An ETag is an identifier for the contents of a document; it changes if at least one bit in the document changes. As an identifier, for example, an MD5 sum of the contents of a document can be used. When a client requests a document from the server, the ETag value is sent in the response, for example:

    HTTP / 1.1 200 OK
    Server: Selectel_Storage / 1.0
    Accept-Ranges: bytes
    Last-Modified: Mon, 18 Aug 2014 12:25:38 GMT
    X-Timestamp: 1408364738.80296
    Content-Type: image / jpeg
    Content-Length: 458073
    Access-Control-Allow-Origin: *
    Access-Control-Expose-Headers: Last-Modified, ETag, X-Timestamp
    ETag: "ebef3343a7b152ea7302eef75bea46c3"
    Date: Wed, 20 Aug 2014 11:52:48 GMT
    

    Upon repeated request of the same document, the saved validator value is transferred already in the If-None-Match header:

    GET / HTTP / 1.1
    Host: example.org
    If-None-Match: "ebef3343a7b152ea7302eef75bea46c3"
    

    If the document has not been modified, then in the response the server will return only the headers and the 304 Not Modified code. Otherwise, the server will return the code 200 and transfer the new version of the document, as well as the new ETag value for it.

    In our repository and ETag is generated immediately after downloading the file. It is an MD5 hash of content. If the content changes, then the ETag changes.

    Validators are called weak, which do not necessarily change with every change to the file.

    An example of a weak validator is the Last-Modified header. The value of this header is the date the file was last modified. In our storage, it is installed automatically. If you specify a date no earlier in the If-Modified-Since header when requesting the one currently in the Last-Modified header, then 304 Not Modified will also be the answer.

    Strong validators can be used in any context. Weak validators are used in a context that is independent of the exact contents of the file.

    For example, both types of validators can be used in GET requests with a condition (If Modified Since or If None Match). However, when downloading files in parts, only strong validators can be used - otherwise the client will receive the file in an inconsistent form.

    Tip 3. Pay attention to the Cache-Control header.


    To set the expiration date in the browser cache for a copy of a file whose original is in the repository, the Cache-Control header with the max-age directive is used. Thanks to this header, you can significantly increase the speed of loading the site - if the file is cached, the browser will instantly display content from the cache without making a single request to the site.
    The file storage time in the cache is indicated in seconds:

    Cache-control: max-age = 7200
    

    In the above example, it is 7200 seconds (2 hours). Typically, CSS, JS, and image files are cached in this way. It is advisable to cache them forever, and when you change the content, change the links to them in HTML. In RFC 2616, it is recommended that you specify a caching time not exceeding 1 year for such files:

    Cache-control: max-age = 31536000
    

    If you want a specific file not to be cached, but always given “fresh”, the following value is set for the Cache-Control header:

    Cache-control: no-cache
    

    It indicates that the item should not be cached at all and that the client should request it each time the storage is accessed (the file loading time will increase in this case, since the file body will have to be downloaded).

    Another way that you can always get a file in the current version is to add a checksum to the file name.

    If the contents of the file change at least one bit, then the checksum will also change. If there were no changes, the browser uses the file from the cache. When you change the file, the link to it will change, and a new version will be downloaded.

    You can get the checksum using standard md5sum or sha1sum utilities, as well as using special utilities.

    You can also add an arbitrary set of characters to file links - for example, a time stamp (http://example.com/script.js?timestamp_here),– and update the links each time the site is deployed. When using this method, however, there is no guarantee that the browser will not make unnecessary requests: even files whose contents have not been changed will have a different link (the entire link together with the query parameters is the caching key), and Download them again.

    For HTML pages, it is preferable to set the cache-control header to no-cache. If you need to urgently change something on the page, and the client has already cached this page (modern browsers do this by default), then the client may not see the changes made at all.

    This is especially important when using CDN: Akamai CDN caches files by default for 24 hours without corresponding headers. You can, of course, clear the cache (see above), but you still have to wait at least 15 minutes after sending the corresponding request. Setting the no-cache value will help to avoid possible problems - the page will always load in the current form. Browsers in this case will still use If-None-Match (or If-Modified-Since) headers, and a page that has not been changed will not load again.

    In some cases, the caching time of HTML pages is best indicated based on the frequency of changes. For example, if the news page on the site is updated every hour, then for max-age you can set the value to 3600 (1 hour).

    The value of the Cache-Control header (as well as other HTTP headers) in our repository can be set via the web interface:

    static site

    Via the web interface, header values ​​are set only for the container as a whole. Header values ​​for individual files can only be set via the API or using third-party clients.

    Instead of Cache-Control, you can use the Expires header. Its value indicates the date in RFC 1123 date format, after which the file ceases to be relevant (for example: Tue, 31 Jan 2012 15:02:53 GMT). Until this date, the browser will not make requests to the site, but will receive a file from the cache. After this date, the file will be downloaded again.

    Tip 4. Use gzip compression


    Using compression, you can significantly speed up the loading of the site. Starting with HTTP / 1.1, clients report supported compression methods in the Accept-Encoding header:

    Accept-Encoding: gzip, deflate
    

    In the server response, information about the compression method used is transmitted in the Content-Encoding header:

    Content-Encoding: gzip
    

    One of the most popular and most commonly used methods today is, of course, gzip. With its help, you can significantly reduce boot time. Gzip works especially well with text files: HTML, CSS, JS. Due to compression, the size of text files (and, accordingly, the volume of transmitted traffic) is reduced by an average of 5-10 times. This allows you to significantly increase page loading speed, which is especially true for mobile clients with a slow connection.

    It makes no sense to use gzip for image files: compression does not help to significantly reduce their size, but often even increases it.

    Akamai CDN uses gzip for most text files by default.

    Tip 5. Minify JS and CSS


    Minification refers to the removal of extra / optional characters from a file in order to reduce its size and reduce download time. Due to this, the file size is reduced on average by 1.5-3 times. Today, the practice of minifying not only JS and CSS, but also other types of files (HTML, image files, etc.) is widespread.

    For minification, special tools are used, in particular:


    With the help of minification, you can not only remove insignificant spaces and line breaks (in CSS and JS they are optional), but also perform more complex operations. For example, in JS, a function of the form:

    function summ (first_param, second_param) {
      return (first_param + second_param);
    }
    

    You can turn it into function s (a, b) {return (a + b)} and then use s instead of summ everywhere in the code, while completely preserving the logic of its operation. You can see how the JavaScript minification procedure works on the page http://lisperator.net/uglifyjs/ in the section Open Demo.

    Tip 6. Use Concatenation


    Modern browsers make an average of 6 concurrent requests per domain. If the site contains many small files, its loading time may be delayed - this is especially noticeable with a slow or unstable connection.

    Concatenation can help here - combining several files of the same type (for example, JS or CSS) into one. It allows you to reduce the number of requests and thereby increase the page loading speed.

    Concatenation can also be used to speed up image loading. It can be done in two ways: by embedding data in a URL and using sprites.

    Data injection is carried out using a special type of URL - data: URI. The URI (Universal Resource Identifator) can be used both in the src attribute of the img tag and in the background image URL in CSS.

    There are online tools for converting images to data: URI (see, for example, here and  here ).

    A sprite is a collection of images combined into one image. For the formation of sites using various software tools. Using CSS, you can access the required area of ​​a large image and put it in the right place on the site.

    Sprites help increase download speed, but it should be noted that working with them is often fraught with difficulties. To make even a small change to the sprite, you will need to make the related changes to the CSS.

    In modern tools for building projects on JS ( Brunch , Grunt , Gulpand others). minification and concatenation procedures can be automated. In order to perform all necessary operations with files with one command (including the final deploy to the server), it is enough to create a small configuration file that describes the order and properties of the assembly.

    For those who want to know more


    Features of the development and configuration of static sites is an extensive topic, and in the following publications we will definitely continue it. For those who want to study this topic more deeply both in theory and in practice, here are some useful links:



    We will answer all questions and comments in the comments. For our part, we promise to talk about current trends in the development of static sites in one of the next publications.

    Readers who for one reason or another cannot post comments here are welcome to join our blog .

    Also popular now: