В интернетах множество статей по ускорению сайта с однотипными советами. На фрилансе цены на оптимизацию скорости загрузки прыгают совершенно случайно: один ставит 200 грн, другой — 12000 грн. Периодически в обсуждения залетают комментарии фрилансеров: «Купите мощный сервер». Давайте разберем ситуацию, пройдя путь от основ до конкретных советов фрилансерам и заказчикам, чтобы понять, почему такой разброс цен, и в каких случаях цена разумна.

Замечу сразу, статья не нацелена на:

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

Этапы загрузки страницы сайта:

  1. Соединение — в этом пункте идет соединение с доменом, определяются редиректы и кеш. На моей практике этот этап ни разу не влиял на скорость загрузки. Если вы используете современный хостинг не очень далеко от региона, на который нацелен сайт, то и у вас проблем с этим не будет. Например, для работы сайта в Украине, расположение сервера в любой стране Европы не критично.
  2. Ожидание — на этом этапе серверная часть сайта общается с базой данных и определяет, что именно передать браузеру. Время ожидания определяется аббревиатурой TTFB, что в переводе означает «Время до получения браузером первого байта». Это время очень критично и для SEO и для пользователей, т.к. все время ожидания посетитель будет видеть белый экран. Какой стек технологий лучше в плане низкого TTFB – это вечная дискуссия, но однозначно можно сказать, что CMS ощутимо проигрывают фреймворкам.1-4
  3. Загрузка — в результате ожидания сервер передает браузеру только plain-text; находясь на странице вы можете посмотреть его, нажав CTRL+U. Но скрипты, стили, шрифты, изображения и видео браузеру все еще нужно скачать. Закачка ресурсов для страницы и происходит на данном этапе. Нужно учитывать, что следующие этапы могут происходить параллельно с загрузкой, это и дает основной простор для оптимизации.2-1
  4. Выполнение скриптов js и построение структуры документа с учетом css. Скрипты и стили анализируются браузером в полном объеме, независимо от того, какая часть их кода будет фактически использована на странице. Чем меньше кода в файлах, тем быстрей браузер их обработает.
  5. Отображение документа — когда вид элементов определен, браузер рисует их. В этот же этап входит и адаптация размера изображений. Если мы укажем ссылку на картинку шириной 1600px, а она должна будет сжаться до 320px, то Page Speed скажет нам «ай-яй-яй» и попросит загрузить ее изначально в размере 320px, чтобы не тормозить отображение. В этих случаях отображение, как и скорость загрузки, ускоряет набор srcset под разные разрешения.

Разобравшись в этапах, вы сразу сможете понять, в какой области проблема у сайта. Например, нет никакого смысла в совете сменить хостинг, если TTFB = 400ms, а Рендеринг = 4000ms.

Владельцам сайтов

Оптимизация для цифр в ущерб пользовательскому опыту

Перед оптимизаций вам нужно определиться с целями:

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

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

SEO — поисковые боты индексируют то, что загрузилось в plain-text. Следовательно, важный для SEO контент не желательно переносить на отложенную загрузку средствами ajax, так как для поисковика такого контента просто не будет существовать.

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

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

Согласуйте метрики, по которым будете оценивать результат. Если оговорена оптимизация цифр – то какие они будут в итоге. Если оптимизация направлена на пользовательский опыт, то утвердите, сколько времени будет занимать прорисовка сайта (в консоли разработчика в процессе загрузки делаются скриншоты сайта, наложенные на временную линию). Даже приблизительная оценка может вас спасти от потерянных денег, так как без закрепленной цели работу нельзя оценить.

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

Дорабатывать старый сайт или сделать новый?

Закладывать оптимизацию скорости загрузки нужно еще на этапе дизайна. Выбор CMS, фреймворка, версии языков и библиотек — все это тоже сильно влияет на скорость, и очень проблематично правится после создания сайта. Например новые версии PHP могут дать уменьшение TTFB в 2-3 раза по сравнению с древними, но перенести старую версию Opencart на свежий PHP — это та еще задача. Если по нескольким оценкам стоимость нужного вам уровня оптимизации составляет половину стоимости разработки нового сайта — задумайтесь, возможно пришло время для нового сайта, созданного изначально по «Best practices»?

Разработчикам

Так ли прост проект, за который вы собираетесь взяться?

Перед тем как делать ставку/подтверждать условия проекта, нужно обязательно ознакомится с деталями, так как может всплыть следующее:

  • Хостинг просто не тянет размер базы данных — без переезда на другой сервер/тарифный пакет вы особо не сможете повлиять на скорость работы задника.
  • Ресурсы хостинга должны вытягивать базу данных, но возможности изменить ее конфиг нет, а база очень тяжелая — тут тоже патовая ситуация.
  • Архитектура базы данных изначально сделана нестандартно и без учета скорости работы запросов — можно изменить некоторые запросы, добавить индексы, но, когда для получения данных для страницы нужно перевернуть 2 млн строк в базе, особо не наоптимизируешь. Либо менять архитектуру, либо брать дорогой хостинг. И то, и другое: непрогнозируемые затраты, с которыми заказчик может быть не согласен. Особенно такой нюанс может всплыть у сайтов автозапчастей.
  • В базе данных остались внушительные куски чего-то прекрасного с прошлой версии сайта. Зачастую это все вырезается и чистится без проблем, но может сильно повлиять на время работы, т. к. в коде тоже может остаться связь со старыми ненужными столбцами базы.
  • Впечатляющая комбинация плагинов (модулей), хорошенько приправленных хардкодом. Это практически патовая ситуация, когда после выключения плагина рассыпается все остальное. Время работы может увеличиться в N раз. Особенно это актуально для плагинов, связанных с кешированием, которые были вручную «улучшены» и принудительно вшиты в код.
  • Критическая зависимость от внешних скриптов и стилей. Аналитики рекламы могут быть отложены при загрузке без проблем, но если часть контента завязана на внешнем сервисе, и его js и css тяжеловесны, вы никак на это не сможете повлиять.
  • Изначально тяжелый дизайн. Если страница чуть ли не полностью состоит из SVG — вам нужно быть готовым его рефакторить. В случае, если дизайн включает много графики, которую уже некуда сжимать (например прозрачные png в высоком разрешении), то вам придется вспомнить или освоить навыки работы с растровой/векторной графикой.
  • Скрипты и стили скомпонованы в единые файлы. При этом без исходников структуры на сервере. В этом случае время работы возрастает непрогнозируемо. По сути, нужно практически переделывать фронт, оставляя только код, который используется. Сюда же можно отнести использование множества тяжеловесных библиотек, например, одновременно подключены Bootstrap и Materialize, друг друга перекрывающие директивами «!important».
  • Задник нестандартный, при этом написан любителем головоломок. Вы можете провести много приятных вечеров, разбираясь, зачем написан десятиуровневый цикл и в каком именно месте он загружает процессор сервера на 100%.
  • Сложный, модифицированный фильтр — очень опасный компонент для оптимизатора. Чтобы его ускорить, нужно разбираться и с кодом, и с базой данных, и с бизнес-логикой. Этот момент обязательно нужно закладывать в цену, шанс быстрой правки минимален.
  • Правки нужно вносить сразу на продакшн версии — никогда этого не делайте и обсуждайте наличие версии сайта для разработки предварительно.
  • Доступ есть не ко всем компонентам сайта — FTP, SSH (часто нужен root), БД (иногда нужен root), админка (доступ админа, а не редактора), панель управления. Вы просто не сможете идентифицировать/исправить некоторые проблемы, если доступа не будет.
  • Оптимизировать нужно тестовую версию на одном сервере, а проверять результат на продакшене, к которому у вас нет доступа. В этом случае вы изначально в уязвимой позиции, т.к. не можете повлиять на результат в момент сдачи работы. В лучшем случае, потратите дополнительное время на настройку еще и продакшн сервера, в худшем — провалите проект, несмотря на то, что на тестовом сервере все будет ок.
  • Сайт все еще в процессе разработки, и его параллельно дорабатывают. Если в проекте этот момент не оговорен, и вы пойдете на поводу, оптимизируя постоянно добавляющиеся элементы, то можете стать бесплатным постоянным работником.

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

С чего начать оптимизацию сайта?

Перед началом работы внимательно посмотрите замечания из отчета Lighthouse. Он может подсветить проблемные места на сайте, с которых стоит начать.

TTFB

Можете начать с проверки конфига базы данных. О том как сделать оптимальный конфиг написаны целые книги, поэтому сжатая информация вам скорей повредит, чем поможет. Единственное, о чем нужно упомянуть – сразу проверяйте, сколько оперативной памяти разрешено использовать в конфиге базы данных. Ситуация, когда на сервере 64 Гб, а используется 128 Мб — одновременно и печальная и забавная.

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

Проверьте сколько % памяти и процессора «съедают» службы на сервере при загрузке сайта на различных типах страниц. При тестировании можете дать нагрузку параллельными запросами с помощью Screaming Frog, включив опцию эмуляции браузера, или любой библиотекой, которая поддерживает выполнение ajax запросов на странице и многопоточность. Тестировать многопоточно нужно для того, чтобы определить, не возникает ли «bottleneck» при большом количестве запросов из-за блокирования таблиц базы данных.

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

Бывает, например на Wordpress, с множеством опций товаров и мультиязычностью, что сайт в целом медленно шевелится из-за раздутой базы данных и множества «важных» активных модулей. В этом случае вас ждут только сложные решения и тяжелая работа. В небольшом проценте случаев может помочь создание программного кеша статических страниц, но имейте в виду, что динамические элементы, например языки, могут перестать работать. Еще у Wordpress есть специфика — он грузит все плагины на каждой странице, даже если они не используются. Может помочь Фильтр загрузки плагинов, ведь нет смысла загружать плагин контактной формы на всех страницах, если он используется только на странице контактов.

Если у вас есть доступ к серверу и полная свобода действий, то рассмотрите настройку Varnish и Memcached.

Загрузка

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

function Load_JS(source, callback) {
	var script = document.createElement('script');
	var prior = document.getElementsByTagName('script')[0];
	script.async = 1;
	script.onload = script.onreadystatechange = function( _, isAbort ) {
		if(isAbort || !script.readyState || /loaded|complete/.test(script.readyState) ) {
			script.onload = script.onreadystatechange = null;
			script = undefined;
			if(!isAbort && callback) setTimeout(callback, 0);
		}
	};
	script.src = source;
	prior.parentNode.insertBefore(script, prior);
}
function jQuery_Loaded() {	
	jQuery.getScript('/script_with_jquery_dependency.min.js', function (data, textStatus, jqxhr) {
		//script loaded
	});	
}
window.addEventListener('DOMContentLoaded', function(){
	Load_JS('/jquery-x.x.x.min.js', jQuery_Loaded);
});

Для отложенной загрузки css:

function Load_CSS(url) {
	var nCSS = document.createElement('link');
	nCSS.rel = 'stylesheet';
	nCSS.href = url;
	document.head.insertBefore(nCSS, document.head.childNodes[document.head.childNodes.length - 1].nextSibling);
}
window.addEventListener('DOMContentLoaded', function(){
	Load_CSS('/style.min.css');
});

Проверяйте, нет ли проблем с кешированием ресурсов после того, как отложили загрузку.

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

1.      Сделать асинхронную загрузку например с помощью webfontloader.

2.      Сделать пререндеринг css директивой font-display:swap или параметром display=swap в ссылке на Google шрифт.

Решение, включающее обе возможности не нашел, если кто-то поделится рецептом в комментариях – буду благодарен.

Очень желательно перенести загрузку css перед js, чтобы распараллелить рендеринг.

Лучше объединить множество мелких файлов в один. Один файл загрузится быстрей, чем 10 с одинаковым общим весом, так как перед загрузкой каждый раз выполняется соединение с сервером. То же касается и картинок: можете воспользоваться любым онлайн сервисом для генерации спрайтов, содержащих мелкие изображения.

Обязательно минифицируйте css и js, желательно используйте серверное автоматическое решение для экономии времени при дальнейшем редактировании файлов.

Термины gzip/deflate должен знать каждый оптимизатор, как и настройки кеширования с правильными заголовками ответа сервера для каждого типа файлов. Процедура включения этих функций занимает минимум времени, но нужно понимать, в каком окружении какие настройки использовать. Обратите внимание что Page Speed продолжает «ругаться», если кеширование настроено, но установлен срок меньше месяца. Если у вас используется и nginx, и apache, лучше настроить кеширование в nginx, так как это дает лучшие результаты.

Если блоки сайта за пределами первого экрана не важны для SEO, задумайтесь над переносом их на ajax.

Выполнение скриптов и Рендеринг

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

Отчет Coverage в консоли разработчика

Coverage — незаменимый отчет, который покажет сколько кода в js и css файлах используется на странице. При клике на файл можно посмотреть подсветку используемых блоков. Учтите, что отчет обновляется динамически при изменении разрешения и взаимодействии со страницей, не делайте выводы, пока не соберете все данные. С недавнего времени появилась возможность экспортировать json с результатами. Разобрать экспортированный json на js и css c вырезкой кода можно библиотекой chromeCoverageParser; для ее использования не обязательно знать python, достаточно знать как его установить и запустить скрипт.

Где и как можно обучаться языкам PHP и Python — курсы, книги, блоги
Иногда наши пользователи интересуются, где и как фрилансеры могут обучаться программированию. Где и какие курсы нужно пройти, чтобы начать работать программистом? Как повысить квалификацию, какие лучше почитать книги? Как учиться эффективнее — онлайн или оффлайн, в группе, индивидуально, самостоятел…

SVG – это масштабируемо и прогрессивно, но учитывайте, что svg бывают с разным уровнем сложности проработки деталей. На практике были случаи, когда файл png весил в 5 раз меньше чем svg и отображался значительно быстрей, без заметной разницы в качестве.

Не забывайте проверять в консоли разработчика как много ресурсов потребляет javascript. Греть устройство посетителя – это очень плохая практика.

Чтобы сделать сайт быстрым, ты сам должен стать быстрей

Забудьте о текстовых редакторах, используйте полноценную IDE, и приступайте к правкам только после загрузки на локальный диск всех файлов сайта (разве что кроме картинок и кешей). Сохраните копию сайта перед правками.

Большие текстовые файлы, например логи, лучше открывать в специально предназначенных для этого программах, читающих файлы построчно, например EmEditor.

Для разовой оптимизации изображений хорошо себя зарекомендовал tinypng.com, для WordPress у него есть плагин с бесплатным ежемесячным лимитом оптимизаций. Лучше оптимизировать изображения прямо на сервере, используя ImageMagick (уровень качества 80-85). Если нужно оптимизировать большое количество файлов в ручном режиме, делайте это программами с возможностью пакетной обработки, например с помощью FileOptimizer. SVG можно значительно уменьшить с помощью сервиса svgomg.

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

Всегда держите в голове правило 20/80. Оптимизировать можно бесконечно, но есть сроки и бюджет. Это здорово, если у вас получится выжать максимум из скорости работы базы данных, но вы просто провалите проект, если у вас на эту задачу уйдет весь срок работы, и вы не успеете коснуться остальных аспектов.

Подружитесь с терминалом SSH

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

Что в итоге?

Ускорение загрузки кажется ерундовой задачей, ведь некоторые проекты можно ускорить за час. Но для некоторых проектов сложно вписаться даже в 100 часов. Поэтому перед тем, как начинать проект по оптимизации более-менее крупного сайта, я рекомендую и фрилансерам, и заказчикам сначала выполнять аудит (лучше перекрестный) с написанием ТЗ. При такой схеме работы аудитор непредвзято подсветит проблемы и даст оценку, так как будет работать не бесплатно, заказчик сможет сам выбрать, в какие правки стоит вложить деньги на данном этапе; а фрилансеры, имея перед глазами ТЗ, смогут делать ставки не вслепую, и не завышать сильно сумму для подстраховки.

Желаю всем быстрых сайтов и легких правок!

Условия конкурса №5 «Фриланс глазами Профи»
Уважаемые наши пользователи, читатели блога и все, кто видит это сообщение! Мы объявляем грандиозный статейный конкурс для всех желающих. Длиться он будет 1 месяц с 4 ноября по 4 декабря. В этот раз, чтобы всем было интересно, и чтобы стимулировать авторов присылать статьи как можно скорее, мы реши…