На опыте

Как мы оптимизируем сайты

01 Мар 2019 / Миддлрид

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

Что такое техническая оптимизация сайта?

В данной статье мы рассмотрим несколько аспектов. Речь пойдет о распределении потока загрузки зависимостей, медиа-контента.

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

Если же у вас происходит задержка, более 10 секунд, то с большой вероятностью пользователь уйдет.

Условно загрузку можно разделить на несколько составляющих:

  1. До первых байтов — время задержки сервера. По сути мало от вас зависит, ну разве что конфигурация сервера, его ошибки, удаленное расположение и т.д.
  2. До первой визуальной информации — появился текст, вуаля, пользователь начал его просматривать. Картинка? Еще лучше.
  3. До начала взаимодействия — когда пользователь увидя информацию может прокручивать страницу.
  4. Время полной загрузки сайта (перестал крутится индикатор загрузки).

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

Алгоритм технической оптимизации сайта

Стандартный алгоритм предполагает:

Изменение размера изображений

Сжатие и кодирования их в сжатом формате, например jpg2000 или progressive jpg.

Сложнее с изображениями с прозрачностью.

Сжатие всех зависимостей кода

Процессы minify и uglify, когда весь CSS или JS код из многострочного читаемого превращается в нечитаемый (практически) код в одну строку.

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

Перенос всех зависимостей в конец кода

Т.е. сперва будет загружен контент в сыром виде, потом к нему применяются стили, затем JS код и так далее.

Сжатие конечного кода страницы HTML

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

Следует отметить, что оптимизация происходит и в бекенде. Но все, что происходит в бекенде остается в бекенде.

Как реализуем всю эту оптимизацию мы

Весь процесс, что описан выше у нас обычно входит в комплект разработки сайтов под ключ. Т.е. на выходе клиент получает завершенный продукт. Но это не значит, что сайт сразу становится супер-оптимизированным.

Для серьезной оптимизации сайта, надо регулярно улучшать этот показатель.

Просто минифицировать ресурсы и распределить их недостаточно. Чтобы действительно сделать легковесный сайт, надо как минимум:

  1. Включить gzip сжатие (страница упаковывается, передается и распаковывается на стороне клиента)
  2. Включить кеширование ресурсов, что позволит старым пользователям быстрее получать ресурсы из браузера. Старым пользователь считается после первого посещения с полной загрузкой кешируемых ресурсов.
  3. Интегрировать эти самые ресурсы в тело страницы.

Как вставить минифицированный код в тело страницы

В веб-разработке мы используем несколько языков и фреймворков. Среди них:

  1. Python в реализации Django
  2. PHP в различных ипостасях от чистого вида до WordPress\Laravel
  3. JS в виде Node.js в формате Gulp, Grunt, Jekyll

В каждом из них существуют свои нюансы, обусловленные возможностями языка. Проще всего в данном случае с PHP. Все, что нужно — заинклудить необходимую зависимость прямо в тело.

Вставка стилей в PHP

Чтобы реализовать это в PHP, необходимо использовать следующий код, к примеру:

<!-- Main CSS include -->
<style>
	<?php include 'style.css' ?>
</style>
<!-- Main CSS include END -->

Можно перестраховаться и использовать include_once для того, чтобы скрипт или стили не были вставлены еще раз.

Почему код должен быть минифицирован

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

Все это не сложно, если для сборки фронта использовать сборщики проектов, такие как Gulp или Grunt.

Некогда мы использовали Grunt, но затем перешли на Gulp в пользу простоты и расширяемости. Мнение сугубо субъективное, но рассматривать примеры мы будем на Gulp.

Распределение ресурсов зависимостей

Как распределить зависимости на наш взгляд

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

В некоторых случаях зависимости можно добавлять на лету для формирования частных случаев. К примеру, у нас на странице иконок в маркете использована интеграция стилей css, чтобы можно было отобразить их все.

В целом мы придерживаемся следующей последовательности:

  1. Начало загрузки документа <head>
  2. Интеграция важных стилей, к примеру описание шапки
  3. Загрузка контента с возможными интеграциями
  4. Инклуд остатка стилей (основная масса с типографикой и каруселями)
  5. Инклуд jQuery
  6. Инклуд Popper.js (если дальше будет Bootstrap)
  7. Инклуд Bootstrap-а
  8. Инклуд кастомного Javascript
  9. Загрузка внешних зависимостей, например FontAwesome
  10. Инклуд калькуляторов счетчиков типа Google Analytics

Практически все, что я описал выше было подготовкой к пониманию данного алгоритма, но следует оговорить некоторые моменты.

Почему мы откладываем загрузку JS как можно дальше

JavaScript может запускаться одновременно с загрузкой страницы. Но мы используем отслеживатели типа window.onload => () или document.addEventListener('DOMContentLoaded', function () {}) для корректной работы ресурсов.

Вторая конструкция предпочтительнее, хотя и выглядит страшно. В отличие от window.onload, может срабатывать несколько раз в коде.

Минификация изображений и отложенная загрузка

Манипуляций с кодом недостаточно для быстрой загрузки страницы. Ведь основной вес — это медиа. Даже сжатые и оптимизированные медиа-файлы.

Речь идет об изображениях. Обычно считают, что хватает выбора оптимального размера, либо с учетом перестройки для разных разрешений (медиазапросы), либо использование ресурсов для этих запросов:

<picture>
 <source srcset="big-image.png" media="(min-width: 600px)">
 <img src="little-image.png" alt="">
</picture>

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

Высококачественные изображения тормозят загрузку страницы. Лучший способ — отложить загрузку. Данный метод мы стали использовать не так давно и сначала не использовали плейсхолдеры.

Сейчас мы все проекты перетаскиваем на алгоритм загрузки:

  1. Загружается документ
  2. Собирается список изображений, что требуют загрузки
  3. Загрузка поочередно
  4. Выдача по факту загрузки изображения

Загрузка тяжелого изображения или с использованием низкоскоростного интернета выглядит плохо. Хорошо, если это progressive jpg, он загружается поэтапной прорисовкой. Другое дело обычный jpg, который загружается сверху вниз посредством развертки.

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

Это позволяет сделать наш скрипт ленивой загрузки изображений, который берет ссылки, создает экземпляры изображений и после их загрузки в этом «вакууме» «переносит» их на место, заменяя placeholder.

Заключение

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

← Ранее
Зачем вам нужен сайт
Актуальнее →
Процесс разработки сайта