В конце июня в Москве прошла конференция Bitrix Summer Fest, на которой было представлено много интересных и полезных докладов. Чтобы этот кладезь мудрости не пропадал, мы будем публиковать в нашем блоге материалы по выступлениям с конференции. И начать мы решили с доклада Антона Герасимюка, посвящённого оптимизации скорости загрузки страниц.
21 апреля Google поменял алгоритм ранжирования поисковой выдачи для мобильных устройств. Многие владельцы сайтов и администраторы получили письма, в которых сообщалось, что «ваш сайт не оптимизирован под мобильные устройства». И после 21 апреля на всех сайтах, которые перестали удовлетворять новым критериями, стал падать поисковый трафик с Google.
Инструменты Google
Для решения этой проблемы Google предложил нам три инструмента. Первый и основной инструмент называется Mobile-Friendly Test. С его помощью Google определяет, оптимизирован ли ваш сайт под мобильные устройства или нет. Этот тест проверяет четыре вещи:
- Наличие мета-тега
viewport
. Он указывает, каким образом страничка должна масштабироваться под разрешение мобильного устройства. - Размеры шрифтов. Они должны быть читаемыми.
- Размеры активных элементов. Это те элементы страницы, на которые пользователь может нажимать.
- Расстояние между активными элементами.
Работать с этим тестом очень просто. Он выглядит как отдельный сервис, в котором нужно ввести адрес конкретной страницы, после чего он выдаст список замечаний или сообщит, что не имеет к вам претензий.
Следующий инструмент встроен в Google Webmaster Tools. По сути, это тот же самый Mobile-Friendly Test, но здесь он уже сам обходит все ваши странички с периодичностью примерно раз в три дня. И тоже укажет на имеющиеся недочеты: слишком маленькие элементы, неудачно подобранные шрифты и т.д.
Но даже если ранее вы уже оптимизировали свой сайт под мобильные устройства, скорее всего, вы провалите этот тест. Дело в том, что многие сайты на «1С-Битрикс» используют специального вида файл
robots.txt
. А в нем запрещена индексация адресов, начинающихся с /bitrix
. В этой папке хранятся CSS, картинки, js-файлы. Поэтому когда Google-бот зайдет на ваш сайт, то считает этот файл и не станет качать эти ресурсы; а в результате посчитает, что страница не имеет дизайна. И на основании этого заявит о провале теста. Решить данную проблему очень легко, достаточно в
robots.txt
разрешить все адреса, начинающиеся с /bitrix
. Наконец, третий инструмент, предлагаемый Google, называется Page Speed Insights. Этот инструмент носит больше вспомогательный характер. Его основное предназначение заключается в поиске сделанных вами ошибок при оптимизации, когда вы стараетесь максимально ускорить загрузку и рендеринг страниц сайта. Page Speed Insights проводит замеры двумя способами. Сначала с помощью мобильного user-agent, а затем с помощью desktop user-agent. Результаты измерений отображаются в виде баллов по шкале от 0 до 100.
Вот как выглядят результаты для одного из наших тестовых сайтов, на котором развернуто наше новое решение для интернет-магазинов, адаптивная верстка сделана на bootstrap.
Page Speed Insigths присвоила сайту 90 баллов для десктопов и 75 для мобильных устройств. При этом хорошим результатом считается 85 баллов и выше. Обратите внимание, что сервис рекомендует удалить из первой части страницы JavaScript-код и CSS, блокирующий отображение. Дело в том, что все внешние ресурсы, находящиеся в теге
<head>
, блокируют рендеринг страницы. То есть чтобы браузер смог отобразить страницу, ему предварительно нужно это всё скачать, а JavaScript еще и исполнить.JavaScript
Давайте теперь посмотрим, как можно средствами «1С-Битрикс» решить обнаруженные Page Speed Insights проблемы. Нас долго просили сделать возможность перенести весь JavaScript в низ страницы. И наконец это произошло, и теперь в настройках главного модуля появилась специальная галочка «переместить весь JavaScript в конец страницы». Как это работает?
Если активировать галочку, то система находит на странице все JS-элементы и помещает их перед тегом
</body>
. Причем полностью сохраняется порядок перемещаемого кода. По нашей статистике, после подобного переноса 95% страниц сохраняют работоспособность. Сразу возникает вопрос: «А если какие-то скрипты мне переносить не нужно?» Для этого есть специальный атрибут
data-skip-moving=true
, который предотвращает перенос тега. Его можно указывать как для внутренних скриптов, так и для внешних. Однако остается еще 5% страниц, чья работоспособность нарушается после переноса JS. Дело в том, что поиск кода осуществляется по тегам
<script></script>
. И сложные конструкции, например, когда скрипты находятся в HTML-комментариях, система не обрабатывает. Это надо иметь в виду. Также обратите внимание на конструкцию document.write
, которую не рекомендуют использовать разработчики браузеров. Она выводит произвольный HTML-код в том месте, где была вызвана. Естественно, если мы JS принесем вниз, то этот HTML тоже будет выведен внизу, а не там, где требовалось. Для включения/отключения нашей волшебной галочки есть удобные методы. То есть вы можете использовать этот инструмент как для отдельных страниц, так и в рамках шаблона сайта.
\Bitrix\Main\Page\Asset::getInstance()->setJsToBody(true); //включить
\Bitrix\Main\Page\Asset::getInstance()->setJsToBody(false); //выключить
Вероятно, у вас уже возникли новые вопросы: «А что будет с JS, который находится в HTML-атрибутах? Например, в onclick или в onmouseover? И вообще, будет ли работать страница, у которой JS остался в атрибутах, а всё остальное перенесли вниз?» Здесь нужно помнить о том, что когда начнут загружаться находящиеся в конце скрипты, страница уже будет показана пользователю. Если пользователь кликает на какой-то элемент раньше, чем загружается соответствующий JS-файл, то будет
JavaScript exception
. Хотя пользователь не увидит этой ошибки, просто элемент никак не отреагирует на его действия. А если пользователь снова кликнет на элемент после загрузки скрипта, то всё заработает. Кто-то скажет, что JS не должно быть в атрибутах, потому что смешиваются верстка и JavaScript, правильнее использовать метод
addEventListener
. Перепишем предыдущий пример на jQuery. Тут надо понимать, что когда мы используем jQuery, либо функции нашей библиотеки BX, то мы навешиваем обработчики на событии
DomContentLoaded
. А это событие происходит только после того, как у вас загрузятся и выполнятся все JS на странице. То есть пока самый последний скрипт не отработает, это событие не произойдет. Поэтому, хоть мы и избавились от onclick’а в HTML, всё равно есть проблемы с юзабилити: когда пользователь кликает на элементе, чей скрипт еще не загрузился, то ничего не происходит. Что здесь можно сделать? Есть несколько вариантов.
• Оставить всё как есть и надеяться на очень быструю загрузку.
• Сделать какую-то альтернативу для подобных случаев. Например, отображение индикатора загрузки при нажатии на элемент с недогруженным скриптом, либо переход на другую страницу.
• Воспользоваться старым методом, который применяли в 2000-х, когда обращались к DOM еще до того, как произойдет событие
DomContentLoaded
. Естественно, с каким-то fallback: если элемент есть, то вешаем обработчик, если нет, то вызываем его на DomContentLoaded
.CSS
Итак, с JavaScript разобрались. Однако CSS также блокирует рендеринг страницы. Но убрать CSS нельзя, иначе страница лишится дизайна. В этой ситуации Google предлагает поместить стили прямо в код страницы с помощью тегов
<style>
. Но при этом делается оговорка, что эта рекомендация относится к маленьким CSS. Как определить, когда можно внедрить весь CSS, а когда нельзя? Чтобы ответить на этот вопрос, нужно вспомнить о так называемом «медленном старте», характерном для протокола TCP. Это означает, что когда клиент запрашивает какой-то ресурс, то сервер никогда не отдает максимальное количество пакетов. Вместо этого он отдает какое-то минимальное начальное количество пакетов, дожидается от клиента подтверждения об их получении, а потом отправляет следующий набор пакетов, увеличив их количество вдвое. Самая первая порция пакетов называется
Initial Congestion Window
(начальное окно перегрузки). В Linux, например, оно равно 10. То есть за первый roundtrip сервер отдает 10 пакетов. В старых версиях Linux ICW вообще равно 4. Каждый пакет имеет размер около 1,46 Кб, то есть первоначальный объем данных, отдаваемый сервером, не превышает 14,6 Кб. Поэтому, в идеале, нужно стараться уместить в этот объем всю страницу, сжатую с помощью gzip. Если же страница слишком велика, то Google обратит на это ваше внимание. В Page Speed считается приемлемым не более двух roundtrip на полную загрузку страницы.Что нам делать с CSS в этих условиях? Есть три варианта:
- Оставить стили во внешних файлах, и тогда на первом хите они будут замедлять отображение страницы. Зато на вторых хитах браузер будет брать этот ресурс из кэша.
- Вставить в тело страницы. В этом случае нужно сделать код стилей как можно лаконичнее, проанализировать невостребованные селекторы. Если вы используете bootstrap, то наверняка не задействуете и половины всех имеющихся в нем селекторов. Для этого есть удобный инструмент Audits в Chrome Dev Tools, который показывает неиспользуемые селекторы. Если размер стилей все равно получается слишком большим, то можно поступить следующим образом. Выделите те стили, которые отвечают за отображение первого экрана страницы, и вставьте их в ее тело. А все остальные поместите во внешний файл и подгрузите с помощью JS. Такой подход будет логичным с точки зрения Google, ведь в этом случае вы очень быстро покажете пользователю первую страницу.
- Увеличить значение
Initial Congestion Window
. Например, в «Битрикс24» мы сделали его равным 20, чтобы пользователю за один roundtrip приходили все необходимые CSS и JS.
Минификация и оптимизация
Также в «1С-Битрикс» появилась галочка «подключить минифицированные файлы». Что это значит? Если в папке c CSS- и JS-файлами есть файлы с одинаковыми названиями, но с суффиксом min, то они будут подключены вместо оригиналов. Правда, обязательно проверяется дата изменения оригинального файла. И если оригинал оказывается новее минифицированного, то он и подключается, как более актуальный.
У Page Speed Insights есть интересная особенность: он может очень сильно снизить балл за большие картинки, которые принудительно масштабируются до меньшего размера. Мы поставили эксперимент и прогнали наш тестовый сайт с тремя картинками шириной в 1000 пикселей, которые были отображены в 200-пиксельном контейнере. За это Page Speed Insights снял с нас 30 баллов. Так что обязательно проверяйте, не масштабируются ли у вас картинки на страницах. Кроме того, рекомендуется использовать специальные инструменты для сжатия графических файлов. Либо можно воспользоваться удобным инструментом, который встроен прямо в Google Page Speed — тест сам предложит вам ссылки для скачивания сжатых версий ресурсов.
Еще одно нововведение: галочка в CDN «Оптимизировать ресурсы». При включении CDN все картинки, CSS- и JS-файлы грузятся со стороннего сайта. А если активировать галочку «Оптимизировать ресурсы», то картинки будут автоматически сжиматься, а остальные ресурсы — минифицироваться.
И напоследок нужно упомянуть еще про несколько оптимизаций:
- Обязательно используйте gzip-сжатие, в противном случае столкнетесь с «медленным стартом» из-за раздувшихся на сотни килобайт страниц. Если у вас нет возможности настроить сервер, то можно воспользоваться для этого встроенным в «1С-Битрикс» модулем.
- Не пренебрегайте HTTP-кэшированием. Если вы используете нашу виртуальную машину, то gzip и HTTP-кэширование там уже настроены.
- Контролируйте время ответа сервера. В этом вам поможет модуль производительности. С точки зрения Google, должно пройти не более 200 миллисекунд от отправки первого HTTP-запроса до получения первого байта ответа.
В заключение
Подведем итог всему вышесказанному.
Для успешного прохождения Mobile-Friendly Test, во-первых, нужно сделать мобильную версию сайта:
- либо с помощью адаптивной верстки,
- либо через отдельный домен наподобие m.вашсайт.ru,
- либо выдавать разный HTML в зависимости от User-Agent.
Сам Google отдает предпочтение адаптивной верстке. К тому же это проще сделать, чем отдельный домен, разные версии сайта. Во-вторых, обязательно проверьте разрешения в
robots.txt
. С Page Speed Insights всё несколько сложнее. Обращайте внимание на блокировку ресурсов, находящихся в
<head>
, на размер страницы и внешних ресурсов, на время ответа сервера.И не забывайте про новые галочки в «1С-Битрикс», а также про возможности технологии «Композитный сайт».
Комментарии (28)
de_arnst
24.07.2015 14:41Все должно быть проще:
1. Вынесите стили и скрипты из папки /bitrix;
2. Минифицируйте все у себя, а не средствами битрикса;
3. Для скриптов, которые должны быть в доме страницы можно использовать:
inlineScripts.push(function() { //ваши методы } )
4. Обязательно включите gzip на сервере.
dom1n1k
24.07.2015 16:03-3Меня раздражает практика совать скрипты вниз (ну разве что за исключением счетчиков и рекламы).
Достаточно сказать им defer.
achekalin
24.07.2015 18:39+2Я за долгие годы так и не услышал ответ на один простой вопрос: зачем, если мы используем схему «nginx + apache», нам включать gzip на апаче, да не просто включать, а включать в виде модуля Битрикса (!), если именно nginx будет сжимать контент для юзера. Это как раз «рекомендованные настройки» и виртуальная машина, уж не знаю как сейчас, еще недавно шла именно с ними.
Другими словами, чтобы сделать сайт на битриксе быстрее и меньше нагрузить сервер, надо, против рекомендаций Битрикса, отключить модуль «Компрессия», отключить сжатие на стороне Apache его модулем, и включить сжатие на nginx — на выходе Apache и PHP не будут бессмысленно тратить CPU для того только, чтобы сжатое распаковал, а затем запаковал для отдачи дальше nginx.
Работа механизма минификации css и js тоже иногда удивляет. Также удивляет и привычка Битрикса приписывать версии статики в конец имен файлов — и ведь ее отключить не так чтобы совсем просто!
По-честному, оставьте всем заниматься своими делами. Битрикс уже давно стал продуктом, под который настраивают сервер, так что можно просто задать ТТХ машины, без которых Битрикс откажется работать. Если так, что все функции веб-серверов внезапно окажутся не помехой, а именно помощниками сайта: как пример, тот же gzip_static заметно поможет еще меньше тратить процессор на постоянное сжатие статических, неизменных файлов.
И таки да, есть еще и mod_page_speed от Гугла, который довольно легко и почти «из коробки» помогает малой кровью улучшить загрузку сайта у юзера. Если бы не версии файлов в URL-ах, он прекрасно бы работал на сайтах с Битриксом, а вот с указанными «версиями»…Rathil
25.07.2015 12:39-1Без обид, не работал с битриксом, я вообще не вижу смысла в связке Nginx + Apache. Меня целиком устраивает связка Nginx + FCGI
achekalin
27.07.2015 15:06Какие обиды. До недавнего времени рекомендованная Битрикс-машина шла именно с такой связкой. Естественно, многие сайты переезжают на nginx+..., но я говорю про дефолтные настройки машины, на которую ТП Битрикса ссылалась как на то, что «точно работает» — оно и правда работает, но может работать еще лучше путем очень нехитрых настроек.
Повторюсь, это особенно любопытно на фоне того, что Битрикс не назвать «легкой CMS», и под него сервера настраивают специально, так что написать в ТТХ, что «требуется nginx с включенными и настроенным модулями ngx_http_gzip_module и ngx_http_gzip_static_module» и убрать из поставки Битрикса модуль «Компрессия» было бы только разумно.
Тем более что в Nginx бинарные модули сжатия, уверен, более рассчитаны на нагрузку, чем (вроде бы) никогда не обновляемый модуль «Компрессия», написанный на php.
DjOnline
27.07.2015 11:04Как браузер посетителя поймёт, что статика изменилась, если убрать версионность? Браузер же не отправляет запросов на проверку изменений, так как включен вечный или долгий кэш.
achekalin
27.07.2015 12:28Вы не поняли. Битрикс «версионность» вводит как httр://domain.com/static/file.ext?ver=123 что никак не нравится ни mpd_page_speed, ни части прокси, ни даже браузерам иным. Версии предполагается в этом варианте указывать в параметре ver, который, по идее, надо еще как-то и вычислять при указании в коде страницы.
В то время как вариант httр://domain.com/static/123/file.ext (видите, куда частичка с номером версии скакнула — «каталогом» перед именем файла?) прекрасно работает, а на стороне сервера обрабатывается реврайтом. Кроме того, такой вариант можно сделать и в виде создания реального каталога, куда положить и простые, и gzip-нутые версии объединенных файлов статики, чтобы gzip_static делал свое дело — при этом обновление такого версионного каталога отлично возлагается на обработчик 404 ошибки, например, что убирает задачу обновления кеша из кода рендера самой страницы (при этом подкаталоги в /static/ можно будет удалять в любой момент, т.к. обработчик 404 всегда их восстановит).
Оно, конечно, не панацея, но как-то поэффективнее, на мой вкус и опыт, чем вариант, так насильственно пропихиваемый Битриксом.DjOnline
27.07.2015 13:19Да, согласен, у себя тоже делаю через static.123.js, не ожидал такого от Bitrix.
mvs
27.07.2015 13:41Категорически поддерживаю! В своё время писал об этой проблеме в ТП и получил вполне ожидаемый от Битриксов ответ:
Я передал пожелание в отдел разработки, но шансов что это будет реализовано крайне мало, так как это сломает сущесвующий функционал, в частности работу CDN.
Тогда же создал идею, если можете проголосовать — проголосуйте в поддержку.
nryzhonin
28.07.2015 16:30-11. Стандартная виртуальная машина идет с включенным сжатием на стороне nginx. В том числе включен модуль gzip_static, для отдачиуже сжатых копий объединенных файлов (Включается в настройках ядра)
2. Модуль БУС «Компрессия» необходим только в случае использования не оптимального хостинга. Где не доступны другие варианты сжатия контента. В случае нормального хостинга, его необходимо отключать.
3. При установки на виртуальную машину проекта, стандартный установщик отключает модуль компрессия через определение константы.
4. В чем конкретно вы видите преимущество вашего метода установки версионности статических файлов?achekalin
28.07.2015 16:40+1> 1. Стандартная виртуальная машина идет с включенным сжатием на стороне nginx. В том числе включен модуль gzip_static, для отдачиуже сжатых копий объединенных файлов (Включается в настройках ядра)
Молодцы! На апаче сжатие отключено? (под рукой свежей нет, в старой было включено, что явно избыточно).
> 2. Модуль БУС «Компрессия» необходим только в случае использования не оптимального хостинга. Где не доступны другие варианты сжатия контента. В случае нормального хостинга, его необходимо отключать.
Скажите, а ЗАЧЕМ он вообще идет? Как много хостингов в мире, где крутятся сайты на Битриксе, но где нет сжатия? :) Ну давали бы его скачивать отдельно, но в составе поставки-то?
> 3. При установки на виртуальную машину проекта, стандартный установщик отключает модуль компрессия через определение константы.
Сейчас — наверное. Но в прошлой версии машины, внезапно — ГОДАМИ!!! — этого не было. Сейчас машины под рукой нет, не проверю, увы.
> 4. В чем конкретно вы видите преимущество вашего метода установки версионности статических файлов?
Так написано же выше — есть софт, который крайне любит видеть расширения в конце адреса статического файла. Вы же так много сил прилагаете к совместимости с разнымии-всякими программами, это как раз тот случай.
Еще раз оговорюсь: Битрикс развивается, но иные модули (когда Компрессия переписывалась в последний раз? а джаббер из Корпортала? :) ) как сделаны, так и заброшены. Чем тянуть трупы, куда как было бы разумнее использовать то, что может дать стороннее (но почти везде существующее) ПО — веб-сервер, скажем.
И, знаете, так и хочется говорить — «наконец хоть это сделали». Говорил и писал об этом в вашу ТП уже лет пять :) что давало впечателния калибра болта, забитого на оптимизацию :)nryzhonin
28.07.2015 16:54-1На данный момент нет информации о каком либо заметном объеме проблем у стороннего ПО с генерируемыми нами ссылками. Если есть другая информация, поделитесь.
Что касается хостинга, использование не оптимального еще не редкость. Возможно в ближайшем будущем, модуль «Компресии» не будет устанавливаться по умолчанию.
wdmaster
25.07.2015 19:45Есть интересное решение.
И видео о том, как оптимизировать с помощью этой штуки.wdmaster
25.07.2015 19:49А также адаптированная для Google PageSpeed верстка на примере и ее тест на GooglePageSpeed.
ainu
Похвастаюсь результатом. Ссылку не даю, ибо реклама будет. Будет спрос — может статью напишу, как добиться. Но это не битрикс.
vladimirkolyada
Как этого добиться написано в комментариях к оценке вашего сайта. Получение 100% результатов без манипуляций с CSS невозможно. А самое главное — в этом нет необходимости, результат не оправдывает средства. Более того, яндекс метрика и иные сторонние скрипты сами руководят своим кэшем. Но, конечно, можно страдать и выдавать гениальные идеи:)
DanDare
При правильной верстке и небольшой оптимизации веб-сервера, добиться такого результата не особо сложно.
А для максимальной оптимизации лучше вообще использовать статику (благо, сейчас таких решений сотни), вместо CMS, но данное решение подходит не для всех сайтов.
ainu
Статика, к сожалению, не решает следующие вопросы:
tegArt
Эм…
ainu
Никто не мешает ничего вебмастеру. Просто превратить сайт из «динамичного» в «статичный» баллов гуглу не даст — я об этом. Это не панацея и даже не метод получения этих данных — я об этом.
По поводу первого пункта — одной из метрик гугла является расстояние между элементами в мобильной версии — чтобы пальцем однозначно попадать по ссылкам и не промахиваться. Это тоже приходится учитывать, чтобы получить 100/100, и перевод сайта с динамического на статический не приведёт к тому, что элементы встанут дальше друг от друга. Другими словами, добиться такого результата переводом на статику нельзя (это не необходимое и не достаточное условие).
tegArt
Думается, DanDare написал о том, что статикой легче манипулировать и подгонять ее под желания гугла, нежели генерируемые цмсками страницы. Опять же, написал, что данное решение подходит не всегда, просто как вариант.
По поводу первого пункта, да, я в курсе, что расстояние между активными (ссылки и тп) элементами влияет на удобство и учитывается в счетчике. К слову, как и размер шрифта. Я просто не понял и до сих пор не понимаю почему же "статика, к сожалению, не решает следующие вопросы". Тут по всем пунктам (кроме счетчиков) вообще без разницы о статике идет речь или нет :)
DanDare
Извиняюсь, за возможно неверную формулировку, но под «максимальной оптимизацией» я имел ввиду именно увеличение скорости загрузки сайта, а не увеличения количества баллов в Google Pagespeed
tegArt
Ну, тем не менее, при статике и скорости и баллов добиться легче :) Я, извиняюсь за выражение, докопался из-за
Ведь из чего статику сделаешь/сгенерируешь, тем она и будет. Статика из адаптивной страницы будет адаптивной и т.д. Чего тут статика не решает и причем тут она — не понятно.
father_gorry
Класть CSS в тело html-документа — не самая хорошая практика, хоть Гугл и дает за нее недостающие баллы.
ainu
Класть CSS в тело документа — за такое гугл даст 94-98 баллов. Чтобы было 100, необходимо, чтобы в теле документа был только css, отвечающий за верхние 700-800 пикселей страницы, а это гораздо меньше полного CSS.
prolis
Так а остальную часть css вы куда включили? В head нельзя — снимет баллы, в body нельзя, потому что не положено спецификацией.
rok
загрузка стилей JS-ом. Я ещё дополнительно делаю так: после первой загрузки страницы вешаю куку с номером версии стилей. Затем при последующих загрузках проверяю наличие куки. Если версия стилей не изменилась, включаю их в head. Тут и гугл не заподозрит обмана и реальная скорость загрузки первой и последующих будут оптимальными
Valery4
Есть интересное решение от Addy Osmani.
github.com/addyosmani/critical
Еще хорош uncss addyosmani.com/blog/removing-unused-css