[Перевод] Храните статические активы на своём хостинге
Одна из первых вещей, которую я рекомендую своим клиентам, чтобы ускорить веб-сайты, сначала покажется парадоксом: вы должны разместить статические активы на своём хостинге, отказавшись от сторонней CDN инфраструктуры. В этом коротком и, я надеюсь, очень простом посте я хочу обрисовать недостатки хранения ваших статических файлов «на стороне» и потрясающие преимущества размещения их на своём хостинге.
О чём я говорю?
Это обычное дело для разработчиков — обращаться по ссылке к статическим активам, таким как библиотеки или плагины, которые находятся на сайтах и CDN ресурсах. Классический пример — jQuery.
Здесь есть ряд очевидных преимуществ, но моя цель далее в статье — разоблачить этот подход, и показать, что недостатки значительно преобладают.
(Сначала рассмотрим преимущества).
• Это удобно. Это требует очень малых усилий для подключения файлов. Скопипастить строчку HTML кода, и всё готово. Легко.
• Мы получаем доступ к CDN. code.jquery.com поставляется StackPath, это CDN. Подключаясь к активам на этом ресурсе, мы получаем доставку CDN-качества, бесплатно.
• Возможно, файлы пользователей уже кэшированы. Если website-a.com ссылается на code.jquery.com/jquery-3.3.1.slim.min.js, и пользователь переходит отсюда на website-b.com, который также ссылается на code.jquery.com/jquery-3.3.1.slim.min.js, затем у пользователя будет этот файл в кэше.
Риск: Падение скорости и Сбои
Я не буду вдаваться в слишком большое количество деталей в этом посте. У меня есть целая статья по поводу жизнеспособности третьей стороны и рисков, связанных с задержками и перебоями. Достаточно сказать, что если у вас есть какие-либо критичные активы, связанные с провайдерами третьей стороны, и если провайдер страдает от сбоев и падения скорости или отключений, это довольно неприятная новость для вас. Вы тоже будете страдать от этого.
Если у вас есть какой-нибудь render-blocking CSS или синхронный JS, размещённый на сторонних ресурсах, идите и перенесите их в свою собственную инфраструктуру немедленно. Критичные активы слишком ценны, чтобы оставлять их на сторонних серверах.
Риск: Прекращение обслуживания
Это гораздо менее обычное явление, но что случится, если провайдер решит, что ему необходимо прекратить обслуживание? Это как раз то, что сделал Rawgit в октябре 2018 года, до сих пор (на момент написания статьи) грубый поиск по коду GitHub все еще даёт более миллиона ссылок на сервис, который сейчас находится в стадии закрытия, и почти 20 000 действующих сайтов продолжают ссылаться на него.
Риск: Уязвимости безопасности
Другая вещь, на которую следует обратить внимание, — это простой вопрос доверия. Если мы приносим контент из сторонних ресурсов на нашу страницу, нам приходится надеяться, что файлы, которые мы получаем, являются именно тем, что мы рассчитываем получить, и они делают именно то, что мы от них ожидаем.
Представьте себе вред, который мог бы быть причинён, если кому-нибудь удалось бы получить контроль над провайдером, таким как code.jquery.com и начать поставлять скомпрометированный или злонамеренный контент. Об этом страшно подумать!
Целостность Субресурсов
Надо отдать должное всем сторонним провайдерам, упомянутым до сих пор в этой статье, они делают всё, чтобы обеспечить целостность субресурсов (Subresource Integrity — SRI). SRI — это механизм, с помощью которого провайдер обеспечивает хэш (технически, хэш с последующим кодированием Base64) конкретного файла, который вы ожидаете и намереваетесь использовать. Браузер затем может проверить, что файл, который вы получили, является в точности тем, что вы запрашивали.
integrity="sha256-pasqAKBDmFT4eHoN2ndd6lN370kFiGUFyTiUHWhU7k8="
crossorigin="anonymous">
Ещё раз, если вы точно должны подключить к стороннему ресурсу статический актив, убедитесь, что действует SRI. Вы можете подключить SRI самостоятельно.
Расплата: Сетевые Согласования
Одна из самых больших и безотлагательных затрат, которую мы несём, — это стоимость открытия новых TCP соединений. Каждый новый ресурс, который нам необходимо посетить, требует открытия соединения, что может быть очень накладно: разрешение DNS, TCP рукопожатие, TLS согласование, всё это вносит свою лепту, и история усугубляется по мере задержек в соединении.
Я приведу пример, взятый прямо из собственной страницы Бутстрапа Getting Started. Они инструктируют пользователей подключить четыре файла.
Эти четыре файла находятся на трёх разных ресурсах, то есть, нам необходимо открыть три соединения TCP. Сколько это стоит? Ну, при достаточно быстром соединении, содержание этих статических активов на стороне стоит 311 мс, или 1,65х медленнее, чем при размещении их на собственном хостинге.
Связываясь с тремя различными источниками для обслуживания статических активов, мы в совокупности теряем ненужные 805 мс на сетевые согласования.
ОК, не так уж страшно, но Trainline, мой клиент, обнаружил, что при уменьшении задержки на 300 мс, посетители платят дополнительно 8 миллионов фунтов в год. Это довольно простой способ заработать 8 миллионов.
Только лишь переместив наши активы на свой домен, мы полностью исключаем затраты на дополнительные соединения.
Для более медленного соединения, с большей задержкой, история намного хуже. Сверх 3G, сторонняя версия приходит медленнее 1.765с. Я полагал, что имелось в виду сделать наш сайт быстрее.
При соединении с большой задержкой, суммарные сетевые затраты составляют чудовищные 5.037с. Чего полностью можно избежать.
Перемещение активов в нашу собственную инфраструктуру снижает время загрузки от 5.4с до 3.6с.
Если это недостаточный повод разместить ваши статические активы у себя, я не знаю, какой ещё привести.
Preconnect
Естественно, весь смысл моего выступления здесь заключается в том, что вы не должны размещать какие-либо статические активы на стороне, если способны сделать это у себя на хостинге. Однако, если у вас каким-то образом связаны руки, вы можете использовать Resource Hint preconnect, чтобы превентивно открыть соединение TCP c определённым источником (определёнными источниками): Более того, их развёртывание в качестве заголовков HTTP будет ещё быстрее.
Примечание. Даже если вы используете preconnect, размер потерянного времени уменьшится лишь чуть-чуть: вам всё ещё необходимо открыть соответствующие соединения, и маловероятно, что когда-либо затраты оправдаются, особенно для медленных соединений.
Расплата: Потеря Приоритезации
Вторая расплата приходит в форме оптимизации на уровне протокола, которую мы упускаем в момент, когда разделяем контент по доменам. Если вы используете HTTP/2, что следует делать, вы получаете доступ к приоритезации.
Все потоки (следовательно, ресурсы) с тем же самым TCP соединением, сохраняют приоритет, и браузер с сервером работают в тандеме, чтобы построить дерево зависимости всех этих приоритезированных потоков, чтобы мы могли вернуть критичные активы быстрее и возможно, задержать доставку менее важных.
Примечание. Технически, вcледствие сращивания соединений HTTP/2, запросы могут быть приоритезированы по отношению друг к другу по разным доменам, пока они разделяют один IP адрес.
Если мы распределяем наши активы по разным доменам, нам приходится открывать несколько уникальных TCP соединений. Мы не можем делать перекрёстные ссылки для приоритетов в этих соединениях, то есть мы теряем способность доставки активов определённым хорошо продуманным способом.
Размещая весь контент на одном хостинге, мы можем построить более сложное дерево зависимостей. У каждого потока имеется свой ID, так как они принадлежат одному дереву. Если мы обеспечиваем как можно больше контента с одного домена, мы можем позволить HTTP/2 делать своё дело и приоритезировать активы более полно в надежде на более быстрый ответ.
Кэширование
По большому счету, хосты статических активов, похоже, неплохо справляются с установлением долгоживущих директив max-age. Это имеет смысл, поскольку статические ресурсы на версионных URL-адресах (как указано выше) никогда не изменятся. Это делает очень безопасным и рациональным усиление разумно агрессивной политики кэширования.
Тем не менее, это не всегда так, и, самостоятельно размещая свои ресурсы, вы можете разработать гораздо более индивидуальные стратегии кэширования.
Миф: Кросс-Доменное Кэширование
Более интересным является возможность междоменного кэширования активов. То есть, если множество сайтов ссылаются на одну и ту же версию jQuery, размещенную на CDN, то наверняка пользователи уже имеют этот конкретный файл на своем компьютере. Что-то вроде однорангового обмена ресурсами. Это один из самых распространенных аргументов в пользу применения стороннего поставщика статических активов.
К сожалению, не существует опубликованных доказательств, подтверждающих эти утверждения: нет оснований предполагать, что это действительно так. И наоборот, недавнее исследование Пола Кальвано намекает на то, что может иметь место обратное:
Есть ощутимый разрыв между возрастом кэша ресурсов CSS и веб принтов 1-й и 3-й стороны. 95% шрифтов 1-й стороны старше 1 недели по сравнению с 50% сторонних шрифтов, которые имеют возраст менее 1 недели. Это дает веские основания для самостоятельного размещения веб-шрифтов.
В общем, кажется, что сторонний контент кэшируется хуже, чем собственный.
Еще более важно то, что Safari полностью отключил эту функцию из-за опасения злоупотреблений в отношении конфиденциальности, поэтому технология общего кэша не может работать на момент написания этой статьи для 16% пользователей во всем мире.
Короче говоря, хотя теоретически это хорошо, нет никаких доказательств того, что кросс-доменное кэширование каким-то образом эффективно.
Доступ к CDN
Еще одно широко распространенное преимущество обращения к поставщику статических ресурсов заключается в том, что он, скорее всего, будет использовать мощную инфраструктуру с возможностями CDN: глобальное распределение, масштабируемость, низкая задержка и высокая доступность.
Так как это абсолютно верно, если вы заботитесь о своей производительности, вам следует запускать свой собственный контент из CDN. С уровнем текущих цен на хостинг остаётся очень мало оправданий, почему вы не используете это для своих активов.
Другими словами: если вы думаете, что вам нужен CDN для вашего jQuery, вам понадобится CDN для всего.
Размещайте статические активы у себя на хостинге
На самом деле, есть очень мало причин оставлять свои статические активы в чужой инфраструктуре. Возможные выгоды часто являются мифом, и даже если нет, компромиссы просто не стоят этого. Загрузка ресурсов из разных источников происходит значительно медленнее. В течение следующих нескольких дней потратьте десять минут на аудит ваших проектов и возьмите все сторонние статические активы под свой контроль.