Современный пользователь интернета привык получать информацию быстро. По этой самой причине веб-разработчики постоянно ведут борьбу с лишними секундами, а то и долями секунд, которые тратятся на загрузку страницы. Так что же нужно сделать, чтобы страницы быстро загружались и корректно работали? Давайте разберемся.

Объединить CSS- и JavaScript-файлы в один

Когда во время загрузки страницы браузер находит в коде страницы ссылку на CSS- или JavaScript-файл, он посылает серверу параллельный запрос на загрузку этого файла. Однако количество одновременных запросов к одному и тому же сайту сильно ограничено, поэтому если внешних ресурсов много, они загружаются по очереди.

Если в качестве сервера вы используете Apache со включенными модулями mod_filter и mod_include, вы можете использовать их для объединения CSS и JavaScript файлов в один. Допустим, вы подключаете три JavaScript-файла, вот так:

<script src="scripts/1.js"></script>
<script src="scripts/2.js"></script>
<script src="scripts/3.js"></script>

Создадим новый файл, назовем его script.combined.js. Поместим в него следующее:

<!--#include file="1.js" -->
<!--#include file="2.js" -->
<!--#include file="3.js" -->

Пути в атрибуте file указываются относительно файла, содержащего директиву #include. Теперь нужно внести изменения в файл .htaccess:

<FilesMatch "\.combined\.js$">
  Options +Includes
  AddOutputFilterByType INCLUDES application/javascript application/json
  SetOutputFilter INCLUDES
</FilesMatch>

<FilesMatch "\.combined\.css$">
  Options +Includes
  AddOutputFilterByType INCLUDES text/css
  SetOutputFilter INCLUDES
</FilesMatch>

Готово, теперь просто подключаем файл script.combined.js вместо трех файлов, которые подключались раньше.

Объединить изображения в спрайты

Допустим, все скрипты и стили объединены в два больших файла, но как же быть с графикой? На загрузку тридцати маленьких иконок браузер потратит немало времени, ведь для каждой иконки отправляется отдельный запрос, а ограничения на количество одновременных запросов все еще в силе.

Изображения, используемые в стилях, можно объединить в одно и использовать свойство background-position для отображения необходимой части. Такое изображение называется спрайтом. Помочь в этом деле могут такие сервисы как spritecow и stitches.

Перенести подключение JavaScript-файлов в конец страницы

Любой JavaScript-файл во время своей загрузки блокирует дальнейшую обработку веб-страницы. Связано это с тем, что JavaScript может содержать директивы document.write(), дописывающие содержимое веб-страницы на лету. Конечно, современные браузеры поддерживают атрибут async, указывающий, что файл может быть загружен асинхронно. Но у подключения файлов в конце страницы есть еще один важный плюс. Обычно после подключения JavaScript-библиотек идет их инициализация. Для полноценной инициализации нужно, чтобы документ был полностью загружен, поэтому обычно ее помещают внутрь обработчика события domready. На jQuery это выглядит так:

$(document).ready(function () {
    // Здесь инициализация
});

Ничего плохого в этом нет до тех пор, пока у пользователя современный браузер. Но в старых браузерах вместо события domready используется событие load, которое срабатывает только после загрузки всех внешних ресурсов, включая изображения. Если же поместить все JavaScript-файлы в конец страницы, прямо перед закрывающим тегом, то необходимости в использовании события domready более не будет, ведь в этот момент весь документ уже загружен. А сама инициализация теперь будет выглядеть вот так:

(function () {
    // Та самая инициализация
})();

Оборачивая инициализацию в анонимную функцию, мы избегаем засорения глобального пространства имен лишними переменными.

Использовать gzip-сжатие и кеширование

Очевидно, что чем меньше размер файла, тем быстрее он будет загружен. Сегодня сжатие CSS- и JavaScript-файлов с помощью gzip — обычная практика. Но, как любят говорить западные специалисты, самый быстрый запрос — это тот, который не был отправлен. Все внешние ресурсы, включая графику, должны кешироваться. Для этого достаточно отправлять вместе с файлами правильные заголовки. Вот как это предлагают делать в популярном нынче HTML-шаблоне HTML5 Boilerplate:

<IfModule mod_mime.c>
  # Audio
    AddType audio/mp4                                   m4a f4a f4b
    AddType audio/ogg                                   oga ogg

  # JavaScript
    # Normalize to standard type (it's sniffed in IE anyways):
    # http://tools.ietf.org/html/rfc4329#section-7.2
    AddType application/javascript                      js jsonp
    AddType application/json                            json

  # Video
    AddType video/mp4                                   mp4 m4v f4v f4p
    AddType video/ogg                                   ogv
    AddType video/webm                                  webm
    AddType video/x-flv                                 flv

  # Web fonts
    AddType application/font-woff                       woff
    AddType application/vnd.ms-fontobject               eot

    # Browsers usually ignore the font MIME types and sniff the content,
    # however, Chrome shows a warning if other MIME types are used for the
    # following fonts.
    AddType application/x-font-ttf                      ttc ttf
    AddType font/opentype                               otf

    # Make SVGZ fonts work on iPad:
    # https://twitter.com/FontSquirrel/status/14855840545
    AddType     image/svg+xml                           svg svgz
    AddEncoding gzip                                    svgz

  # Other
    AddType application/octet-stream                    safariextz
    AddType application/x-chrome-extension              crx
    AddType application/x-opera-extension               oex
    AddType application/x-shockwave-flash               swf
    AddType application/x-web-app-manifest+json         webapp
    AddType application/x-xpinstall                     xpi
    AddType application/xml                             atom rdf rss xml
    AddType image/webp                                  webp
    AddType image/x-icon                                ico
    AddType text/cache-manifest                         appcache manifest
    AddType text/vtt                                    vtt
    AddType text/x-component                            htc
    AddType text/x-vcard                                vcf
</IfModule>

<IfModule mod_expires.c>
    ExpiresActive on
    ExpiresDefault                                      "access plus 1 month"

  # CSS
    ExpiresByType text/css                              "access plus 1 year"

  # Data interchange
    ExpiresByType application/json                      "access plus 0 seconds"
    ExpiresByType application/xml                       "access plus 0 seconds"
    ExpiresByType text/xml                              "access plus 0 seconds"

  # Favicon (cannot be renamed!)
    ExpiresByType image/x-icon                          "access plus 1 week"

  # HTML components (HTCs)
    ExpiresByType text/x-component                      "access plus 1 month"

  # HTML
    ExpiresByType text/html                             "access plus 0 seconds"

  # JavaScript
    ExpiresByType application/javascript                "access plus 1 year"

  # Manifest files
    ExpiresByType application/x-web-app-manifest+json   "access plus 0 seconds"
    ExpiresByType text/cache-manifest                   "access plus 0 seconds"

  # Media
    ExpiresByType audio/ogg                             "access plus 1 month"
    ExpiresByType image/gif                             "access plus 1 month"
    ExpiresByType image/jpeg                            "access plus 1 month"
    ExpiresByType image/png                             "access plus 1 month"
    ExpiresByType video/mp4                             "access plus 1 month"
    ExpiresByType video/ogg                             "access plus 1 month"
    ExpiresByType video/webm                            "access plus 1 month"

  # Web feeds
    ExpiresByType application/atom+xml                  "access plus 1 hour"
    ExpiresByType application/rss+xml                   "access plus 1 hour"

  # Web fonts
    ExpiresByType application/font-woff                 "access plus 1 month"
    ExpiresByType application/vnd.ms-fontobject         "access plus 1 month"
    ExpiresByType application/x-font-ttf                "access plus 1 month"
    ExpiresByType font/opentype                         "access plus 1 month"
    ExpiresByType image/svg+xml                         "access plus 1 month"
</IfModule>

Этот код для веб-сервера Apache, но ребята из HTML5 Boilerplate подготовили конфигурации и для других веб-серверов.

Минифицировать JavaScript и CSS

Один из самых эффективных способов уменьшить размер CSS- и JavaScript-файлов — минифицировать их. Под минифицированием имеется ввиду удаление всех лишних символов, используемых для форматирования. Помимо этого, многие современные минификаторы умеют переименовывать локальные JavaScript-переменные в односимвольные, за счет чего минификация становится еще более эффективной. К сожалению, читаемость результирующих файлов практически нулевая, поэтому внесение изменений в такие файлы — задача, мягко говоря, не из простых. Если же вы все-таки решите использовать минификаторы, то могу порекомендовать Online YUI Compressor.

Разместить дополнительные ресурсы на собственных CDN

CDN — (от англ. Content Delivery Network — сеть доставки контента) сеть отдельных серверов, используемых для распространения статических ресурсов. У каждого сервера в сети CDN свой адрес, что позволяет обойти ограничения на количество одновременных запросов к одному сайту, ведь с точки зрения браузера сайтов множество. Если на ваших сайтах много внешних ресурсов, например фотографий пользователей, то вам пора задуматься об использовании CDN.

Использовать Google CDN для подключения распространенных JavaScript-библиотек

Google предоставляет веб-разработчикам возможность загружать несколько самых распространенных JavaScript-библиотек прямо со своих серверов. Помимо высокой скорости и безупречной надежности их серверов, у такого способа подключения библиотек есть еще одно преимущество: очень многие сайты в интернете уже используют CDN от Google. Это значит, что с большой долей вероятности запрошенная библиотека уже есть в кеше браузера пользователя. Со списком доступных библиотек и документацией по Google CDN можно ознакомиться здесь.

Указать заголовок Content-Type с корректной кодировкой

Прежде чем обработать веб-страницу, браузеру необходимо знать кодировку, в которой эта веб-страница представлена. Часто для этого используется примерно такой meta-тег:

<meta charset="utf-8">

Использование такого тега требует от браузера отложить обработку страницы до той поры, пока этот тег не будет найден. Избежать задержек в обработке страницы позволит заголовок Content-Type. Так как заголовки в ответе на запрос к серверу идут до содержимого страницы, браузер сможет начать обработку содержимого сразу же. Современные веб-серверы отправляют заголовок Content-Type автоматически, поэтому им достаточно указать корректную кодировку. В сервере Apache это выглядит так:

AddDefaultCharset utf-8

 

Кому-то может показаться, что пара секунд — не так уж и долго для веб-страницы, но практика показывает, что если страница не готова в течение секунды, пользователь может закрыть ваш сайт и никогда на него не возвращаться. Поэтому не стоит пренебрегать всеми способами оптимизации, которые позволяют сэкономить хотя бы доли секунды.