Цель: Дать базовые понятия о факторах, влияющих на скорость загрузки сайта. Разобрать каждый этап загрузки. Дать понятие о способах ускорения за счёт оптимизации каждого фактора загрузки, на который можно повлиять.

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

Целевая аудитория: владельцы сайтов, web-студии, специалисты и любители. Постараюсь написать статью таким образом, чтобы она была доступна в понимании всем.

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

Мощность и качество устройства клиента, а так же скорость его интернета и удалённость от локации сервера


Мы можем купить клиенту нормальный компьютер и подключить ему высокоскоростной интернет и более не будем испытывать проблем с этим фактором (конечно же, я шучу). Хотя я бы определённо чаще посещал сайты, владельцы которых обновляли бы мне компьютер и оплачивали интернет. Кроме шуток, что мы на самом деле можем сделать, если у клиента слабый интернет и маломощное устройство?

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

2. Чем слабее устройство, тем дольше оно создаёт новые соединения с сервером, а значит, нам нужно сократить количество этих соединений. Зачастую владелец сайта даже не представляет, как тяжело грузится его сайт, и думает, что проблемы тормознутости явно не из-за сайта, а просто у клиентов медленный интернет. Нужно учитывать, что вы как владелец находитесь на своём сайте чаще других и всё содержимое сайта уже давно закэшировано браузером, а значит не подгружается при каждом переходе по страничкам(если конечно у Вас настроено кэширование статики в браузере клиента), а берётся из кэша. Соответственно не только экономится трафик, не нагружая каждый раз Ваш канал интернета, но и не создаётся соединений для загрузки этих файлов.

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

image

image

Загрузку можно разделить на несколько этапов, каждый этап загрузки страницы вашего сайта важен.

1. Время ответа сервера. Время выполнения этого этапа загрузки обычно называют «временем ответа сервера». Теперь расскажу, что происходит за это время и как это время можно сократить, если оно у вас запредельное и вообще, какое время ответа сервера считать запредельным.

Разобьём этот промежуток на подпункты:

1.1 Отправка запроса браузером клиента.

Скорость интернета и мощность устройства клиента, а также удалённость сервера, на котором расположен ваш сайт, от клиента и его загруженность — вот факторы, которые могут повлиять на этот этап.

Далее до того момента, как сервер отправит готовую страничку в ответ, проходит несколько этапов, и для каждого конкретного сайта этапы могут отличаться. Я возьму в пример сайт на php с БД MySQL.

1.2 Запрос принимается web-сервером, он находит в списке виртуальных хостов тот, что подойдёт под запрос и производит обработку виртуального хоста, в нашем примере сайт на php, значит web-сервер обратится к php для генерации странички, тот в свою очередь для наполнения странички данными обратится в БД. После формирования странички она будет передана web-сервером браузеру клиента.

Очень важную роль играет кэширование на каждом этапе, кэширование на уровне web-сервера, кэширование на уровне php (opcache), кэширование запросов в БД (memcache), могут быть и другие варианты кэширования, я привёл эти как наиболее распространённые. Это как раз тот этап на который Вы можете повлиять и этому этапу нужно уделить время.

Вот способы его ускорения.

  • Выбрать быстрый хостинг или даже лучше VPS, VDS или даже физический сервер. Если вы не компетентны в таком выборе, лучше попросите помощь у специалиста или спросите рекомендации от знакомых, которые уже пользуются теми или иными хостерами. Обратите внимания на то где расположен дата-центр хостера: идеально, если он будет располагаться в непосредственной близости от ваших потенциальных клиентов. Я лично использую зарубежные сервера, если только на сайт осуществляются DDOS-атаки, Российские хостеры предосталяют защиту от DDOS низкого качества, и тут уже приходится мириться с пингами и задержкой.

  • Правильная настройка сервера поможет ускорить ответ от него. Тут играют роль выбор более шустрого ПО и правильное его конфигурирование. Для web-сервера я использую Nginx, где по возможности использую hhvm совместно с php 7.1, выбор версии php, а так же hhvm по большей части ещё и зависит от кода вашего сайта: если сайт использует устаревшие функции, то вам или придётся обновлять его или довольствоваться старыми версиями, имеющими не столь высокую производительность. Ну и в качестве БД использовать MariaBD или даже Perсona, если у вас более крупный проект. Также не стоит забывать о защите: антибруты, фильтры от типовых атак, http-авторизация как дополнительная авторизация на всех админках, антиспамы, антивирусы и прочее.

1.3 Отправка сгенерированной странички клиенту и момент получения этой странички и будет завершающим этапом этой части загрузки страницы. Тут для уменьшения объёма отправляемых данных лучше всего использовать gzip сжатие.

Хочу сделать поправку, у меня на скрине ответ сервера для сайта Хабра равен 3,48 с — это плохое время, но Хабр тут по сути не виноват. У меня 3G интернет посредственного качества. Поэтому конкретно этот этап загрузки рекомендую отслеживать при помощи сервиса. Я использую для этого сервис проверки ответа сервера от Яндекс.

image

Код статуса HTTP должен быть 200.

Ответ сервера тут заметно меньше, чем на моём 3G интернете. В идеале время ответа сервера должно стремиться к нулю, но как минимум он не должен превышать 200 мс, хотя это лично мой критерий. Хотя нет, не только мой. Google PageSpeed если я не ошибаюсь тоже следит, чтобы ответ сервера не превышал 200 мс и, если сайт превышает рекомендованное время, то предупреждает, что нужно сократить ответ сервера.

Ну и в самом низу мы можем увидеть, что ответ сжат при помощи gzip.

Хабр прошёл первый этап загрузки на пятёрочку (нет-нет, я вовсе не подлизываюсь).

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

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

На что тут нужно обратить внимание.

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

Как же их сократить? В http/1.0 и http/1.1 для каждого отдельного файла создаётся отдельное соединение, значит наша задача сократить количество подгружаемых файлов на страничке.

  • Объединить все css в один файл и все js в один файл, эта процедура называется конкатенация.

  • Поместить мелкие картинки в закодированном виде прямо в css или в тело страницы чтобы для них не создавались отдельные соединения.

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

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

  • Перейти на http/2, данная версия протокола позволяет грузить все элементы в один поток не создавая лишних соединений. И самые догадливые уже подумали, так зачем тогда выполнять первые две рекомендации если можно просто перейти на http/2, сейчас поясню. На данный момент http/2 ещё поддерживается не всеми устройствами, поэтому часть клиентов продолжат пользоваться сайтом на предыдущих версиях протокола, так что эта рекомендация поможет ускорить загрузку страницы для свежих девайсов с актуальными версиями браузеров.

image

Вот тут наглядно видно на сколько меньше соединений создаётся при использовании http/2

2.2 Вес страницы и элементов, подгружаемых с неё.

  • Убрать лишние комментарии в коде.
  • Использовать сжатие.
  • Оптимизировать контент сайта, сжать и объединить css и js, сжать картинки и пр.

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

Модуль для web-сервера PageSpeed. Он есть и для nginx — ngx_pagespeed и для apache2 — mod_pagespeed. О том что он может делать, лучше подробнее почитать в официальной документации, его настройки очень гибкие. Я только отмечу, что он способен выполнять конкатенацию на лету что поможет сократить количество соединений и он же отлично жмёт контент, сокращая вес странички и её содержимого.

На этом этапе я могу поставить Хабру твёрдую 4 и то только за отсутствие http/2, хотя я бы наверное ещё сократил объём подгружаемых элементов и сделал конкатенацию.
Этот этап загрузки странички в идеале не должен превышать 2-3 сек(хотя предела совершенству нет конца и у меня есть клиенты, которые хотят быстрее даже при скорости загрузки меньше 1сек). Если у вас это время больше, вам стоит задуматься над рекомендациями, которые я дал выше.

3. Load — это тот момент, когда колёсико браузера перестало крутиться, то есть произошла полная загрузка страницы. Это менее критичный этап загрузки и он зачастую затормаживается сторонними чатами для общения с клиентами на сайте и прочими второстепенными элементами. Если вы выполните рекомендации, которые я дал выше, то этот этап тоже станет быстрее. Ещё хотел бы отметить что если у вас не высоконагруженный проект и при этом у вас VPS, VDS или физ. сервер, постарайтесь, чтобы вся статика грузилась только с вашего сервера. Размещение статики на сторонних сайтах и в CDN принесёт пользу только при высоких нагрузках, а для не нагруженных сайтов сыграет только в минус.

4. На этот этап можно не смотреть вообще, так как по сути страничка загружена и тут браузер всегда будет что-то подгружать, общаясь с сайтом.

5. Данной цифрой на скриншоте я обозначил место, где отображается количество загружаемых элементов на страничке и вес странички со всеми элементами. Нужно учитывать что если для ПК не проблема загрузить страничку в 2,5 Мб, то для мобильного браузера со слабым 3G это становится более проблематично. В частности у меня 3G интернет и Хабр у меня грузится не так быстро как другие сайты. Для мобильных устройств в идеале, чтобы страничка весила меньше 1 Мб. Тут или сокращать размер всего контента на страничках или делать мобильную версию.

P.S.


Плюсы загрузки контента со стороны:

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

Минусы загрузки контента со стороны:

  • Зачастую публичные CDN и сайты, на которых хранятся шрифты, картинки, css и js имеют высокую нагрузку, так как их используют сотни, а то и тысячи сайтов с разным уровнем посещаемости, в итоге выходит, что отдать со своего порой быстрее, чем экономить нагрузку.
  • Если вы используете http2 для снижения количества соединений, сторонние сайты вам их только добавят.

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

Надеюсь, данная статья оказалась для вас познавательной.
Поделиться с друзьями
-->

Комментарии (19)


  1. easyman
    27.07.2017 12:35
    +1

    В http/1.0 и http/1.1 для каждого отдельного файла создаётся отдельное соединение

    Это наброс на вентилятор
    HTTP 1.1 использует коннекшины повторно
    HTTP/1.1 defaults to the use of «persistent connections», allowing
    multiple requests and responses to be carried over a single
    connection. The «close» connection option is used to signal that a
    connection will not persist after the current request/response. HTTP
    implementations SHOULD support persistent connections.


    1. castomi
      27.07.2017 13:00

      Справедливое замечание, но тем не менее при использовании http/2 соединений создаётся меньше.


      1. easyman
        27.07.2017 13:37

        Не все так однозначно. У меня было такое, что по http 1.1 картинка из теста https://http2.akamai.com/demo загружалась быстрее, чем по http 2.


        1. castomi
          27.07.2017 13:54

          На счёт количества соединений всё однозначно, их меньше в http/2. На счёт скорости загрузки страницы могли сыграть роль разного рода факторы. К примеру:
          — наличие отсутствие ssl и его конфигурирование
          — поддержка конкретным браузером http/2 и корректность его работы на нём. Например раньше всё было не на столько гладко, а сейчас я ставлю http/2 на все сайты с ssl.

          Посмотрел ссылочку, разница и правда в пользу http/1.1, только есть одно «но», обрати внимания картинки в http/2 в данном тесте грузятся не параллельно, а последовательно. Вполне естественно что если контент грузится последовательно то на скорость загрузки будет влиять количество потоков, а в http/1.1 их больше. Тот кто делал этот тест хотел чтобы http/2 проиграл. Если бы картинки грузились параллельно то http/1.1 был бы медленнее.


          1. easyman
            27.07.2017 14:04

            В этом тесте всегда включен https.
            Http2 мультиплексирует несколько логических запросов/ответов в один tcp connection.
            Есть один stream, внутри него несколько запросов и ответов.


            1. castomi
              27.07.2017 14:22

              Я вижу что он включен всегда, я первую часть комментария не адресовал конкретно этому тесту.

              Вот скрин того как грузятся картинки с одного из подконтрольных мною сайтов. Загрузка идёт в одном потоке и начинается одновременно.
              image

              А вот скрин того как грузятся картинки в этом тесте.
              image
              Тут видно что хоть и поток так же один, но картинки грузятся последовательно. При такой подаче контента http/2 проиграет, но таким образом не подаётся контент нигде среди тех сайтов с которыми я работал. Поэтому я и сказал что тут явно хотели чтобы http/2 проиграл. Не знаю что это за сайт, но на нём даже настройка ssl проведена не совсем верно, промежуточный сертификат имеет не безопасную подпись.

              P.S. Конечно в каждом конкретном случае требуется индивидуальный подход к настройке, но могу сказать что в большинстве случаев http/2 будет показывать результаты лучше. Хотя как видно из теста исключения всё же есть, но чтобы учесть все индивидуальные случаи статьи тут не достаточно, сразу книгу надо писать.


              1. easyman
                27.07.2017 17:51

                тут видно что хоть и поток так же один, но картинки грузятся последовательно
                Параллельно? Можно, например, четные байты от одной, нечетные — от другой. Но быстрее суммарная загрузка вряд-ли отработает (но TCP congestion control, возможно, потратит меньше служебных данных!)

                Я не знаю, где на Ваших картинках можно посмотреть детали про tcp, я плохо понял, что там все должны увидеть в плане анализа tcp. Если у h2 или http/1.1 подвести мышку к ячейке из столбца waterfall, то видно момент «Queued at» и «Started at» у разных спрайтов разное в пределах одного протокола. Но никаких указаний на используемый tcp stream я не вижу, научите меня, пожалуйста, где смотреть тут! Обычно я для просмотра такой информации использую wireshark

                Есть интересное письмо на тему http2 в varnish cache (объясняют, почему не хотят имплементить http2. Уже заимплементили)

                По моей статистике этого теста, по http2 картинки грузятся быстрее. Попробуйте использовать другие устройства, другого провайдера, думаю, Вы измените мнение, что «тут явно хотели чтобы http/2 проиграл».

                Есть видео, где akamai рекламирует свою реализацию http2 push (я не уверен, что push может помочь http2 начать выигрывать у http1 ещё больше)

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

                На всякий случай, вот rfc7540.html. Вдруг я неправ.


                1. castomi
                  27.07.2017 18:28

                  >> Параллельно? Можно, например, четные байты от одной, нечетные — от другой. Но быстрее суммарная загрузка вряд-ли отработает (но TCP congestion control, возможно, потратит меньше служебных данных!)

                  Именно параллельно.

                  >> Я не знаю, где на Ваших картинках можно посмотреть детали про tcp, я плохо понял, что там все должны увидеть в плане анализа tcp. Если у h2 или http/1.1 подвести мышку к ячейке из столбца waterfall, то видно момент «Queued at» и «Started at» у разных спрайтов разное в пределах одного протокола. Но никаких указаний на используемый tcp stream я не вижу, научите меня, пожалуйста, где смотреть тут! Обычно я для просмотра такой информации использую wireshark

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

                  >> Есть интересное письмо на тему http2 в varnish cache (объясняют, почему не хотят имплементить http2. Уже заимплементили)

                  Может меня сейчас кто-то начнёт закидывать палками, но я не использую его. Поэтому это для меня как бы не имеет значения. Я всё проворачиваю в самом nginx. Не могу сказать на сколько верно я поступаю, надо будет на днях сравнить мой способ с Varnish. Отпишу по результату сюда в комменты, если результаты будут интересными даже дополню статью.

                  >> По моей статистике этого теста, по http2 картинки грузятся быстрее. Попробуйте использовать другие устройства, другого провайдера, думаю, Вы измените мнение, что «тут явно хотели чтобы http/2 проиграл».

                  У меня слабый инет, не с проста я вообще так увлечённо занимаюсь ускорением сайтов) Всё благодаря ему)))

                  >> Есть видео, где akamai рекламирует свою реализацию http2 push (я не уверен, что push может помочь http2 начать выигрывать у http1 ещё больше)

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

                  >> Производительность сайта зависит от многих факторов, включая режим работы MIMO.
                  На всякий случай, вот rfc7540.html. Вдруг я неправ.

                  Да ты прав, просто расставляешь акценты не так как я, мы оба по своему правы) Расстановка акцентов думаю зависит от того какие у кого проекты были за плечами, я в связи со своими проектами посчитал что их лучше расставить так, у тебя видимо чуть по другому. Не суть я думаю. Да и в любом случае я же не выключаю на сайтах http/1.0 и http/1.1 вот это было бы конечно не верно. Все три протокола работают параллельно, браузер сам выбирает какой использовать)


                1. castomi
                  28.07.2017 15:59

                  Varnish не ставят на работу с клиентами, его рекомендуют прятать за nginx, так что абсолютно не играет роли умеет он http2 или нет, ведь с клиентом общается не он, а nginx.


  1. Gryphon88
    27.07.2017 14:34

    Я бы добавил «Используйте активное содержимое страниц тогда и только тогда, когда это удобно в первую очередь пользователю». Не Вам, не из-за моды, а только тогда, когда будет падать юзабельность.


    1. castomi
      27.07.2017 14:40

      Я упомянул это, только не так явно.

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


      1. Gryphon88
        27.07.2017 14:48

        Я имел в виду более жёстко: иногда достаточно статики. Вот совсем статики. Если по клику выскакивает (извиняюсь, плавно выплывает) здоровая форма для заполнения, может стоить редирект на отдельную страничку именно с этой формой, а не тонну js на выскакивание и собственно заполнение? Или про чат-окна «напишите нам, специалист онлайн!»: если специалист гарантированно не онлайн, потому что в локации магазина полночь, может, это окно просто не грузить?


        1. castomi
          27.07.2017 14:58

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


  1. igurylev
    27.07.2017 14:37

    Маленькая поправка: Google PageSpeed ругается, если сайт грузится более 200мс, а не 300.


    1. castomi
      27.07.2017 14:38

      Писал на память, моя оплошность. Сейчас поправлю информацию в статье.


  1. den_golub
    27.07.2017 17:53

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

    такие вот вещи



    1. castomi
      27.07.2017 18:29

      Есть предположение что эта оценка влияет на поисковую выдачу, так что это точно не бесполезно.


  1. DrMeJI
    28.07.2017 16:18

    PageSpeed

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

    Не подскажите, такие проблемы возникают при непоавильной настройке модуля или плозого кода? Или эта штука вообще запрещена доя сложных сайтов и не работает на них?


    1. castomi
      28.07.2017 16:20

      У этой штуки очень жирная документация, когда Вы её просто включаете, то врубается стандартный набор фильтров, а там кроме него ещё 2 варианта набора фильтров + можно полностью в ручную конфигурировать. То что с дефолтными настройками бывают проблема для меня это не новость. Правда достаточно редко, всё таки дефолтные расчитаны на то что они подойдут максимальному количеству сайтов.