perfScan - Секреты быстрых сайтов
1.37K subscribers
53 photos
56 links
Делюсь секретами как создавать быстрые сайты и ускорять существующие.

По всем вопросам: @fenixru - помогаю ускорять сайты.

При использовании материалов канала обязательно указание авторства.

Поддержать автора: https://pay.cloudtips.ru/p/4ad68fa9
Download Telegram
⚠️ Сегодня говорим про CLS - продолжаем серию публикаций про Core Web Vitals.

🟢 Зеленая зона: до 0.1
🟡 Желтая зона: от 0.1 до 0.25
🔴 Красная зона: более 0.25

Cumulative Layout Shift - это ключевой показатель Core Web Vitals, который отвечает за визуальную стабильность страницы во время загрузки и использования страницы. Вот это "во время использования" вызывает у людей больше всего вопросов. Вы можете замерить показатели всех страниц в Lighthouse и везде иметь CLS равный 0, но при этом по Core Web Vitals показатель будет далеко не идеальным, а возможно и вообще в красной зоне.

Все дело в том, что это динамический показатель, и снимается за все время посещения страницы, а не разово, как например LCP, или FID. Тоесть во время загрузки смещений может не быть, но при взаимодействии со страницей могут происходить смещения, которые будут зафиксированы и повлияют на показатель CLS в Core Web Vitals. Однако стоит оговориться, что смещения должны быть неожиданными, например, если происходит добавление элементов сразу после клика на кнопку, и при этом происходит смещение, то эти оно не будет являться неожиданным, так как перед ним следовал клик пользователя. Сразу договоримся, что далее мы говорим именно о неожиданных смещениях, и устранять мы будем не все смещения, а только неожиданные. Неожиданными являются те смещения, перед которыми в течение 500 миллисекунд не происходило взаимодействие пользователя с интерфейсом сайта.

⚠️ Отмечу, что CLS - это самая частая проблема по метрикам Core Web Vitals, и встречается даже у очень быстрых сайтов.
👍7🔥2👏2
🧩 Давайте рассмотрим основные проблемные моменты, почему они происходят и как их устранить.

Возможно смещение контента при загрузке отложенных изображений. До момента загрузки, в src изображения находится заглушка, а после грузится изображение большего формата, и как следствие сдвигает весь контент ниже этого элемента. Для того, что исправить это, просто укажите у изображений width и height. Если изображения масштабируются уже в браузере, нужно указать ширину и высоту оригинальной картинки, для определения aspect-ratio, далее меняете размер уже через стили.

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

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

Бесконечная прокрутка - еще один частый кейс когда происходит CLS. Здесь все просто: если используете бесконечную прокрутку уберите футер, потому что до него, во-первых, никогда не доскроллят, во-вторых, он постоянно будет сдвигаться и приводить к увеличению cls. Можно показывать футер только когда пользователи доскроллят до конца. Главное сделать так, чтобы ниже подгружаемого контента ничего небыло, что могло бы смещаться.

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

💬 Пишите, если у вас есть затруднения в решении проблемы с CLS.
👍13🔥2👏2
В какой зоне находится показатель CLS по Core Web Vitals у вашего проекта?
Anonymous Poll
48%
🟢 Зеленая
31%
🟡 Желтая
20%
🔴 Красная
👍6🔥2👏2
🥳 Вот и заключительный день нашей недели Core Web Vitals. Напомню, мы рассмотрели LCP, FID, и CLS. Даже в рамках двух постов в день получилось очень поверхностно, потому что когда писали статью, она не влезала даже в 3 поста Telegram.

Давайте кратко пробежимся по оставшимся трем, которые собирает Google и выводит в Google Pagespeed Insights. Это FCP, INP и TTFB. На самом деле это большая тема, и про улучшения каждого из показателей мы сделаем еще не один пост, так как и методы меняются и поведения браузеров и новые метрики также появляются.

FCP - отрисовка первого контента, это время между событием TTFB и началом отрисовки контента на странице.

🟢 до 1.8 секунд
🟡 от 1.8 до 3 секунд
🔴 более 3 секунд

Для улучшения показателя нужно снижать блокировку отрисовки. Стили делим на Critical и обычные, и inline грузим только критические, остальные подключаем асинхронно, js откладываем при помощи defer или другими методами.

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

🟢 до 200 мс
🟡 от 200 до 300 мс
🔴 более 500 мс

Для улучшения показателя добавляем стильные скелетоны при клике на кнопку без ожидания ответа сервера. И оптимизируем сам Javscript. Разбиваем задачи на более мелкие и упрощаем. Отказываемся от поддержки устаревших браузеров.

TTFB - Время до получения первого байта от сервера. Зависит от времени выполнения скриптов, сети и нагрузки магистралей. Больше всего зависимость от времени выполнения скриптов на сервере. Чем проще задачи - тем быстрее.

🟢 до 500 мс
🟡 от 500 до 1000 мс
🔴 более 1000 мс

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

На следующей неделе рассмотрим несколько практических методов для улучшения показателей производительности. Хороших выходных!

💬 Пишите, была ли вам полезна информация этой недели?
👍11🔥3🤯21👏1🤩1
❗️ Я много раз писал, что самая ресурсоемкая операция - это установка нового соединения. Сегодня мы обсудим отложенную загрузку внешних скриптов. В отличии от отложенной загрузки изображений, внешние скрипты откладывают по первому действию пользователя, например движению мыши, клику, ресайзу, скроллу, и тд. Это повышает оценку Google PageSpeed Insights. Получаем значительное улучшения показателей, но давайте рассмотрим, что же произойдет, когда пользователь пошевелит мышкой или сделает клик.

Обычная реализация: задается функция, которая создает элемент <script> со стороннего домена, или выполняет код. Далее эта функция вызывается на действие пользователя. Самые частые ошибки здесь:

1. Функция выполняется на каждое действие пользователя. Каждое смещение мыши или клик добавляют на страницу элемент, что неправильно, так как это нужно сделать всего один раз.
2. Элемент добавляется один раз, но прослушиватели остаются. Это лучше, чем предыдущий пункт, но также влияет на быстродействие. Удаляем события после срабатывания.
3. Все скрипты выполняются на одно и то же действие и буквально одной кучей. Системы синтетических замеров не увидят, но у пользователя основной поток будет заблокирован при первом же действии. Нужно разносить по времени, и постоянно смотреть во вкладку Performance в Google Chrome.
4. Загружается слишком много скриптов, что приводит к блокировке основного потока при загрузке с медленных устройств. Избавляемся от ненужных скриптов.

Появление чата можно отложить по времени на 15 секунд смело. Аналитику можно отложить на любое первое действие пользователя и по таймеру через 2-3 секунды. Да, погрешность будет, но выполняться скрипты начнут только у тех пользователей кто не закрыл вкладку на первой же секунде.

⚠️ Чтобы полностью избавиться от негативного влияния внешних скриптов, нужно ПОЛНОСТЬЮ убрать их с сайта. Любой сторонний скрипт нужно добавлять, предварительно замерив как это влияет на быстродействие сайта. Если не сильно, то можно откладывать по предложенному ниже примеру.

Пример на CodePen
👍15🔥5👏21
А что если отложить весь JS?

Привет 👋. В прошлой статье я писал о том, как отложить внешние скрипты. И кто-то мог задаться вопросом: а что если отложить вообще весь JS? Да, мы встречали такие проекты при работе. Сразу скажу, что от проекта к проекту отличались методы отложенной загрузки и выполнения скриптов. Однако мы немного подумали, и вообще сделали конфиг для nginx, который откладывает выполнение всех js на странице в автоматическом режиме. Что-то похожее делает Rocket-loader у Cloudflare, но грузятся и выполняются скрипты только при первом действии пользователя.

Как это работает, nginx на своей стороне дописывает к скриптам type="text/psscript" и скрипт перестает выполняться браузером. Далее при помощи JS создаются новые элементы script, которые загружаются в нужном порядке, и загрузка начинается после срабатывания события.

⚠️ Важно: для того, чтобы скрипт работал правильно, нужно сделать так, чтобы первый экран отображался одинаково как с включенным так и с выключенным JS. Особенно это касается слайдеров, попапов и тд. И этот может существенно испортить другие показатели по Core Web Vitals, а относительно полезно только для синтетических тестов. Однако кому-то может помочь решить "нерешаемую" задачу.

🧩 Конфиг nginx
JS-файл

Как заставить это работать: Конфиг в секцию server, js в корень сайта с тем же именем.

💬 Пишите ваши мнения в комментариях
👍8🔥3👏1🤔1
❗️ Как вы уже знаете, установка соединения очень ресурсоемкая операция. Но что делать, если есть внешний скрипт, который по тем или иным причинам нельзя отложить по времени или первому действию. Например очень часто таким скриптом становится яндекс-метрика. Я постоянно пишу в аудитах и говорю в прямых эфирах, что критичные внешние скрипты можно проксировать через свой домен, но до этого момента никогда не приводил пример такого проксирования. Пора исправить эту ошибку.

Проксирование метрики через свой домен позволяет снизить число установленных соединений, и как следствие ускорить инициализацию при первом запуске проекта. Для корректной работы nginx дожен быть собран с поддержкой sub_filter. В коде метрики нужно заменить https://mc.yandex.ru/ на /proxy-yandex/

Для того, чтобы все заработало, добавляем содержимое файла в секцию server в конфиге nginx нужного хоста. В конфиг внесено два хоста mc.yandex.ru и mc.yandex.com, однако в разных странах подключение может производиться с региональных доменов, например mc.yandex.md, поэтому проверяйте и вносите необходимые домены в конфиг по такому же шаблону. Например: sub_filter 'mc.yandex.md' "$host/proxy-yandex";

🧩 Конфиг nginx

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

💬 Если есть вопросы или идеи по улучшению - пишите в комментарии.
👍17🔥9👏2
🙈 Я продолжаю каждый день сталкиваться с сайтами, где стандартный функционал браузера реализуют на JavaScript. Наверное можно даже рубрику #nojs сделать. Сегодня рассмотрим возможность закрепления блоков при скролле на чистом css.

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

В CSS уже достаточно давно появилось свойство position: sticky. Указываете его для элемента и позиционируете при помощи inset (top right bottom left) для закрепления. Закреплять можно сверху, снизу, слева и справа. Можно даже по двум осям.

Если вы сомневаетесь, можно ли использовать это решение - смотрите поддержку. На момент написания 96,58%.

Пример на Codepen

💬 Знали вы о таком свойстве? Используете в работе? Пишите в комментарии.
👍27🔥5👏1
Ворчанье деда

Нас больше 1000. Спасибо вам!

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

Почему все острее стоит проблема быстродействия сайтов и веб-приложений? Потому что все меньше внимания уделяется этому вопросу. Быстрый интернет и быстрые процессоры позволяют совсем расслабиться. Но проблема ещё и в самих разработчиках: уже изначально, при входе в профессию, учат не языки, а фреймворки: react, vue, angular. Это крутые инструменты, против них ничего не имею, но если человек не знает как работает JavaScript, то и использовать фреймворки он будет так же.

Я много общаюсь и знаю, что многие разработчики понимают важность быстродействия, но часто проблема системная, и в одиночку с ней не справиться. Например, маркетологи ставят задачу ускорить сайт и одновременно подключить 4 сторонних сервиса для "увеличения конверсии", которые наглухо блокируют основной поток на 4-6 секунд. 🤦‍♂️

Непонимание языка или лень?

Библиотека для вычисления разницы между двумя датами. Серьезно? Это одна функция с совсем простой математикой. Зачем подключать библиотеку на 200 кб? Просто потому что торопился. Да, эта библиотека решает необходимую задачу, и еще 400 других, которые не нужны. Отсюда мы и получаем предупреждение Lighthouse о неиспользуемом коде. Хорошо еще, если используется система сборки и импорт происходит не всей библиотеки, а только необходимой части. Но это скорее исключение из правил. Ведь в Examples этой библиотеки был пример только с полным импортом, так ведь?

Непонимание проблемы производительности.

"8 мегабайт картинка? Ну, у меня за секунду загрузилась на моем гигабитном интернете по проводу, если у вас медленно, значит проблема на вашей стороне." Нет. Картинку можно и нужно сжимать, готовить к публикации. Если с сайтом работают неподготовленные люди, то это должно происходить без их вмешательства. Тоже касается и 8 мб js на странице. Четыре разных слайдера на разных библиотеках, только потому что в примерах один свайпится тачем, а второй по таймеру. Так и хочется процитировать классика "Астанавитесь!". Не у всех такой компьютер как у разработчика. У большинства пользователей будут устройства медленнее чем у разработчика. Это нормально. И даже рост вычислительной мощности процессоров не должен позволять забывать об оптимизации. Даже если это временное решение, то техдолг растёт и со временем становится неуправляемым.

Сложность алгоритмов.

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

‼️ Важно: Я НЕ призываю отказываться от готовых библиотек - это нерационально писать велосипеды. Я призываю вдумчиво анализировать что подключается и используется на сайте.

💬 У меня все. Пишите, что думаете по этому поводу в комменты.
👍28👏8🔥4🎉3😁1
❗️ Сегодня рассмотрим еще одно интересное #nojs решение.

Все видели в интернет-магазинах переключение превью изображений при движении курсором мыши по фотографии товара влево и вправо? Интересный и уже достаточно привычный функционал. Но как его реализуют? На JS вычисляют положение мыши и выполняют переключение активного изображения в зависимости от ее координат. В результате на странице списка товаров стоит несколько десятков таких прослушивателей. Далее математика для вычисления того, какую картинку показать и в конце-концов действие с добавлением класса, которое вызывает перерисовку.

Сейчас мы сделаем на чистом CSS без полной перерисовки DOM. Думаю смысла нет рассказывать как стилизуем карточку, расскажу лишь про механизм работы. Все изображения в нашем случае это div с классом thumb спозиционированы относительно родителя и находятся друг под другом. Перед ними находятся пустые элементы с классом place, при наведении на которые мы меняем opacity следющего за ним элемента.

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

Пример на Codepen

💬 Если есть идеи по улучшению - пишите в комментарии.
👍21🔥8👏2
❗️ Сегодня речь пойдет о так называемом Critical CSS - небольшой хитрости для ускорения первой отрисовки (#fcp, #lcp) страницы и устранению её блокировки файлами стилей. Если у вас FCP больше 1.5 сек, то определенно стоит озадачиться.

Как обычно выглядит проект в конечном виде - HTML, в котором подключаются файлы стилей. Так вот, отрисовка страницы не начнется, пока все файлы стилей не будут загружены и прочитаны. Находятся умельцы, которые файлы стилей переносят из head куда-нибудь перед </body> и первая отрисовка становится почти мгновенной, но сначала мы видим страницу без стилей, а затем перерисовка и огромный CLS.

Чтобы этого избежать, стили, необходимые для отрисовки первого экрана нужно поместить в код страницы в тег <style>. Тогда прыгать контент не будет, и эти стили применятся к странице сразу же. Остальные стили при таком формате нужно подключать в <head> сайта, но чтобы они загрузились как можно быстрее и не блокировали отрисовку. Для этого отлично подходит небольшой лайфхак:

<link rel="preload" as="style" href="style.css" onload="this.onload=null;this.rel='stylesheet'">

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

Чтобы выделить Critical-CSS, лучше выполнять верстку покомпонентно, как в современных фреймворках, и управлять вручную теми стилями, которые попадут inline, или использовать инструменты для выделения критических стилей для текущей страницы, например плагин для вебпака, и отдельные приложения для экстракции стилей с готовой верстки critical.

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

💬 А вы используете Critical-CSS?
👍24🔥4👏2😱2
❗️ При загрузке контента одна из важных метрик - это #fcp - первая отрисовка контента. Это чаще всего элементы интерфейса, или текст. Для пользователя комфортнее, если отрисовка начнется раньше.

Как оценивается показатель FCP:

🟢 Зеленая зона: до 1.8 секунды
🟡 Желтая зона: от 1.8 секунд до 3 секунд
🔴 Красная зона: более 3 секунд

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

1. В <head> загружается слишком много стилей или js файлов. Помните, что стили и скрипты без async и defer блокируют первую отрисовку до момент пока не будут загружены и выполнены подключаемые файлы. Оставляйте там только то, что необходимо для первой отрисовки

2. Нет критических стилей, о которых мы писали вчера. Используйте их, это хорошо для первой отрисовки.

3. Шрифты используются без font-display:swap|optional или того хуже с Google Fonts. Не используйте Google Fonts. Такую ошибку можно часто встретить там, где первый экран на белом фоне, и нет основных элементов интерфейса. Пока шрифты не загрузятся у пользователя будет просто белый экран, хотя началась отрисовка уже второго и третьего блоков.

4. В <head> подключаются стили или скрипты со сторонних доменов, что может съедать 500-600 миллисекунд на установку соединения. Если подключений больше, то задержка может стать еще больше. Если нельзя перенести стили или скрипты на свой домен, проксируйте тем же способом, как мы предлагали проксировать яндекс-метрику.

⚠️ В Lighthouse есть аудит "Старайтесь не допускать создания цепочек критических запросов". Как раз тут нужно следить, чтобы цепочка была как можно короче, и там ни в коем случае не было внешних сервисов и поддоменов. Отличный аудит - один из самых полезных при отладке FCP.

💬 А как у вас дела с первой отрисовкой?
👍15🔥6👏2
❗️ Сегодня расскажу об интересной технологии, которую можно использовать вместо безвременно почивших HTTP/2 Server Push. Напомню, раньше была возможность при помощи веб-сервера вместе со страницей отправить сразу нужные ресурсы, которые подгружаются на этой странице, но Google удалил поддержку из Google Chrome. А как же хорошо они работали вместе HTTP 103 Early Hints!

HTTP 103 Early Hints - это другая и тоже интересная на мой взгляд технология. Вместо проталкивания указанных ресурсов, как это делал Push, сервер отдает два ответа. Первый моментально 103 Early Hints с HTTP заголовками, например preconnect или preload, и затем второй как обычно 200. Это позволяет начать загрузку ресурсов еще до момента, когда поступит настоящий полный ответ сервера с содержимым. В отличии от Server Push здесь не будет передачи лишних байт, если стили были закэшированы, браузер возьмет их из кэша. Во-вторых, пока происходит генерация даже какой-то тяжелой страницы, браузер может уже начать загрузку критичной статики.

🧩 Как использовать: Поддержки в ядре nginx пока нет, поэтому только собирать сторонние модули к нему. Поддержка apache2 есть, но при проксировании через nginx может не работать. Опробовать как это работает можно через CloudFlare, включив нужную галочку. Попробовать точно стоит, если ttfb больше 200 мс, ускорение может быть очень заметным. Для того, чтобы заработало, передавайте заголовки серверу из своего приложения. Браузерная поддержка есть пока только в свежем Google Chrome, но думаю, другие браузеры быстро подтянуться.

Например в php <?php header('Link: </style.css>; rel=preload; as=style');?>

💬 А вы слышали про 103 Early Hints?
👍9🔥5👏2👌21
❗️ Необычный #lifehack позволит ускорить постраничную навигацию, например в большом интернет магазине. На странице 20 товаров. Показ следующей страницы происходит после нажатия на кнопку "показать еще". Ответ от сервера приходит за 300 миллисекунд, значит до времени показа следующей страницы будет задержка не меньше этой цифры. Показатель INP на этой странице вырастет, и сайт станет менее отзывчивым.

Давайте для начала поймем, что мы хотим получить? Ускорить ответ сервера, используя кэш? А зачем? Нам нужно только показать следующую страницу быстрее. Давайте разбираться, какие еще есть варианты.

Можно загрузить следующую страницу в фоне, когда пользователь проскроллит например 50% от всех вариантов, и скрыть их до момента нажатия кнопки "показать еще". После нажатия кнопки показываем скрытые элементы и выполняем следующий запрос. После нажатия мгновенно отображается следующая страница, пока изучаем варианты грузится следующая. Быстрее приложение по факту не стало, но мы отдаем результат с точки зрения пользователей мгновенно. Задача решена.

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

💬 Что вы думаете о таком подходе? Использовали когда-то подобные фишки? Пишите свои варианты подобных механик.
👍33🔥6❤‍🔥2👏2🕊2
❗️ Мало кто знает, что существует интересное свойство content-visibility. Появилось оно в 85-ом хроме и создано для ускорения первой отрисовки контента. На момент написания поста, поддержка не очень большая. Суть свойства в том, что он не отрисовывает и не применяет стили для блоков которые находятся вне viewport. В некоторых случаях позволяет улучшить отрисовку в разы, а как следствие и #fcp.

Как этим пользоваться: указываете для типовых блоков content-visibility: auto, в листинге и блоков которых много за пределами первого экрана, и браузер сам решает когда его отрисовать, чтобы отрисовка стала быстрее и нагрузка на процессор не выросла.

Пользоваться свойством нужно осторожно, так как его использование может вызывать CLS. Чтобы этого не происходило, указываете contain-intrinsic-size в размер элемента. Это как отложенная загрузка изображений, только стилизация целых блоков.

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

⚠️ Помните, однако, что content-visibility может странно повлиять на position: fixed внутри элементов. Как-то раз очень долго не мог отловить ошибку, когда внутри content-visibility в попапе ехала верстка. Решилось вынесением из элемента попапа выше по DOM.

💬 А вы используете content-visibility?
👍21🔥4👏21
❗️ Совсем недавно я писал #lifehack про пагинацию, сегодня расскажу про другой функционал который можно оптимизировать таким же образом. Кнопка "добавить в корзину", или "добавить в избранное" - любые интерактивные элементы, которые не зависят от ответа сервера.

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

Мы уже знаем что выведено на frontend, просто суммируем к содержимому корзины стоимость добавленного товара и увеличиваем количество. Сам запрос может выполняться в фоне, а все данные для пользователя можно показать мгновенно. После обновления всех переменных в интерфейсе мы отправляем запрос в корзину и когда приходит ответ, если возвращаемые значения отличаются от текущих, меняем их в интерфейсе. Если используются современные фреймворки, типа vue, react, angular, svelte, то все еще проще, все запросы станут фоновыми, и добавится динамический компонент ошибки, который отображается только в случае этой ошибки.

Но как быть, если у пользователя пропал интернет, и на самом деле товары не добавляются? Да просто же! В случае ошибки XHR-запроса выводим об этом информацию для пользователя (проблемы с интернетом, товар закончился) и отнимаем последние измененные значения от того, что у нас получилось, или просто отменяем последние действия, предварительно сохраняя в памяти старые значения.

⚠️ Кажется, что это много действий, которые не нужны, однако отзывчивость станет просто мгновенной. Показ загрузки пользователю даже на пару секунд - это время для сомнения. Давайте уберем это время.

💬 А какие хитрости используете вы, чтобы пользователь меньше ждал?
👍13🔥7👏2
❗️ Часто встречается ситуация, когда в JS нужно выполнить много тяжелых операций, и показатель #TBT от этого будет расти. Современный JS позволяет начать выполнение следующей операции только когда предыдущая завершена и основной поток свободен для новых задач.

Знакомьтесь - requestIdleCallback метод, который позволяет выполнять операции во время простоя браузера, только когда основной поток свободен и новая задача минимально повлияет на быстродействие. Метод достаточно старый, но поддержка браузерами, не очень большая, на момент написания поста 78.33%. Но не переживайте полифилл очень простой и его можно просто включать в ваш код.

if (!window.requestIdleCallback) {
window.requestIdleCallback = (func, options) => {

options = options || {};
setTimeout(func,
options.timeout || 1);
}
}


Если браузер не поддерживает requestIdleCallback, то функция просто выполнится по таймауту.

Как пользоваться этим методом.

requestIdleCallback(() => {
// Ваш код
}, {timeout: 1000});


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

⚠️ Помните, это не волшебная кнопка и если просто обернуть в этот метод весь ваш js код, то разницы в быстродействии не будет, нужно логически разбивать код на блоки, выполнение которых не зависит друг от друга, тогда будет видна разница в быстродействии. И интерфейсные вещи первого экрана (события на кнопки и тд) лучше не откладывать, чтобы не понижать отзывчивость вашего сайта.

💬 А вы используете этот метод в своей работе?
👍14👏21🔥1🤯1
⁉️ В чем отличия preload, prefetch, preconnect, dns-prefetch, prerender и как они работают? Если мы говорим про скорость сайтов, то нельзя не упомянуть об этих техниках. Бывают случаи, когда просто удаление нескольких прелоадов или преконнектов из кода страницы уже дает прирост скорости. Давайте разбираться, почему. Для начала коротко о каждом.

<link rel="preload" as="style" href="style.css">

Этим тегом мы говорим браузеру, что уже прямо сейчас нам понадобится стиль style.css, и нужно немедленно их загрузить, не дожидаясь события load всей страницы с наивысшим приоритетом. Часто это снимает блокировку отрисовки, так как стили оказываются уже загружены, когда парсинг html-документа завершен.

⛔️ Частая ошибка: загружать огромное число ресурсов, что в итоге замедляет загрузку всей страницы. Не рекомендуется использовать со сторонними доменами, так как придется устанавливать соединение, а как вы уже знаете, это самая ресурсоемкая операция и можно потерять до 500мс на каждый коннект. Еще одна ошибка - выполняется загрузка ресурсов, которых нет на странице. Тут очевидно, лишний трафик с повышенным приоритетом замедлит отображение.

<link rel="preconnect" href="https://perfscan.ru">

Благодаря ему браузер как и в случае с preload может установить соединение еще до окончания парсинга документа, что ускоряет первое обращение к ресурсу с этого домена. Для чего использовать: У вас есть отдельный домен с api, или статикой, которые невозможно перенести на основной домен даже проксированием, например из-за сложной архитектуры проекта. В этом случае использовать preconnect можно и нужно.

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

<link rel="prefetch" as="image" href="image.jpg">

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

⛔️ Частая ошибка: использовать этот тег вместо preload. Загрузка не ускорится и приоритет не повысится, а значит текущая страница не ускорится.

⬇️⬇️⬇️ продолжение
👍16🔥2👏2
⬆️⬆️⬆️ начало поста

<link rel="dns-prefetch" href="https://perfscan.ru">

Как и preconnect, только как такового соединения не происходит, исключительно резолвинг dns. Если не используете preconnect, то dns-prefetch может ускорить установку этого соединения. Используется если неизвестно, понадобится ли соединение, но если понадобится, то мы точно знаем что dns-запрос уже выполнен.

⛔️ Частая ошибка: как и в preconnect - большое число запросов к днс снизит общую производительность вашего сайта.

<link rel="prerender" href="https://perfscan.ru/static/gallery/">

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

⛔️ Частая ошибка: Делать prerender нескольких старниц, так как в фоне будет запущена вся страница. Еще одна ошибка - думать что ты лучше пользователя знаешь куда он перейдет. Может и никуда, но мы ему уже выполнили что-то там в фоне без его ведома.

💬 Напишите, не повторяете ли вы ошибки, которые описаны выше?

update: Почему-то нет комментариев у последнего поста. Можете писать и задавать вопросы в предыдущем.
👍14🔥5👏2
🔆 Помните, когда-то давно были WAP-сайты, которые мы открывали с мобилок с черно-белым экраном и качали картинки с рингтонами? Интересно, довелось ли кому-то из моих подписчиков их разрабатывать? У меня был такой опыт. Почему вспомнил - недавно работал над скоростью AMP-сайта, и это что-то среднее между современным html и WAP-версткой. Чуть больше свободы, но скрипты свои уже не напишешь, теги которых нет в стандарте также не используешь, и все что мы можем сделать - это оптимизировать изображение и уменьшить влияние стороннего кода.

💬 Сегодня пятница, а значит давайте подискутируем, почему получается так, что технология, созданная для ускорения загрузки сайтов по факту грузится дольше, чем оригинальный оптимизированный сайт? Что вы думаете вообще про технологии AMP/Турбо/Instant Article? Это будущее, или очередной тупик, как и WAP?
👍7🔥3👏2
❗️ Сегодня расскажу про CDN: нужно ли подключать, как выбрать, и как подключать правильно. CDN - Content Delivery Network (сеть доставки контента), это когда контент доставляется пользователю с ближайшего к нему сервера, что снижает пинг и RTT, и как следствие ускоряет загрузку.

А нужен ли сайту CDN? Чтобы понять это, достаточно ответить на три вопроса:

1. Мои клиенты из разных городов/стран?
2. Есть ли посещаемость за пределами одного города?
3. Много ли приносят денег посетители из других регионов.


⚠️ Если на 1 вопрос ответ "нет", то достаточно разместить сайт на хостинге в пределах вашего региона, чтобы посетители получили ускорение загрузки. Если же ответ "да" на все три вопроса, то можно попробовать подключить CDN в режиме тестирования и проверить, как изменится конверсия и скорость загрузки сайта из других регионов.

⬇️⬇️⬇️ продолжение
👍8🔥4👏2