Главная » Хабрахабр » Оптимизируем веб с Виталием Фридманом: скорость загрузки, память, CPU

Оптимизируем веб с Виталием Фридманом: скорость загрузки, память, CPU

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

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

В основе материала — расшифровка доклада Виталия с конференции HolyJS 2018 Piter.
Первая часть тут: Оптимизируем веб с Виталием Фридманом, — компрессия, картинки, шрифты, фичи HTTP/2 и Resource Hints.
Вторая часть:

Горчица и медленные устройства

В этой части речь пойдет о производительности. Как ее повысить? Какое-то время мы использовали технику «Сutting the mustard». Суть ее в том, чтобы с помощью сниппета узнать, со старым или с новым браузером мы имеем мы дело. В зависимости от этого определялось, какой скрипт и стили загружать, чтобы не грузить их ненужным функционалом.

Пример сниппета для определения браузера

Потом появилась возможность заменить последовательность из querySelector, localStorage и addEventListener  на visibility state API — и именно так в основном поступали в маленьких проектах. Но с этой техникой была проблема —  та же, что бывает со всеми остальными техниками, в том числе и теми, которые используете вы.

Дело в том, что есть устройства из low-end сегмента (например,  Motorola Moto G4), которые имеют мало оперативной памяти и слабый процессор. Проблема заключается в том, что когда мы хотим дать красивые стили новому браузеру, мы не знаем, насколько хорошо он их отрисует, потому что это зависит от устройства, на котором он запущен. Тем не менее, на них установлен новый браузер, который поддерживает все (ну или почти все) технологии, которые у нас есть.

Поэтому использовать эту технику сегодня уже нельзя.

По следам Google с Moto G4  в кармане

Почему бы не сделать так, чтобы responsive-верстка отображалась только на тех устройствах, который «потянут» ее в части аппаратных ресурсов? Для этого мы можем использовать Device Memory API. Если же данный API недоступен, можно откатиться до «cutting the mustard».

А вот и сам Moto G4:

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

Если посмотреть на данные по сайтам на мобильных телефонах, видно, что больше всего времени тратится именно на парсинг JS.


Желтым отмечено время парсинга страницы

Для того, чтобы запарсить 1 мегабайт скриптов, Moto G4 требуется 35 секунд. На самом деле, это очень большая проблема. В Gmail, например, комментировали весь код и отправляли в качестве текстовой переменной, а затем, когда этот код требовался, делался eval этой переменной. Учитывая то, что большинство сайтов использует лишь 40% из всего скрипта на сайте, можно попытаться найти выход из этого положения, дабы снизить время на парсинг.

Учитывая, что 1,6 секунды уходят на сетевые взаимодействия, у нас остаются лишь 3,4 секунды — то есть, если взять среднюю скорость соединения 400kbps, за это время мы можем отправить максимум 170KB данных. Рекомендации Google гласят, что есть так называемый Time to Interactive Budget, промежуток времени, в течение которого большинство пользователей ждет возможности взаимодействовать с сайтом — и это всего 5 секунд. Учитывая, что сюда входят фреймворки, утилиты, critical path, js, css, html, такой объем данных — это очень и очень мало. Это немного для того, чтобы отправить что-либо, пригодное для немедленного использования.

Google рекомендует много разных метрик, которые можно использовать, они делят загрузку на этапы по времени: time-to first byte (navigation begins) — до передачи первого байта, first paint — до загрузки первой картинки, first contentful paint — до появления навигации на сайте, first meaningful paint — когда почти все готово по контенту, visualy ready — до загрузки всей страницы, time to interactive — до возможности взаимодействовать со страницей, fully loaded — когда страница полностью готова. Как уместить ядро приложения в 170 Кбайт?

Итак, как же выглядит оптимальная метрика (performance baseline) на сегодняшний день? В целом для каждого сайта такая метрика будет особой, поэтому нам для нашего проекта тоже нужно составить свою.

На изображении указано, какие аспекты и цели нужно принимать во внимание при разработке своей метрики.

Как повысить скорость загрузки?

Что полезно использовать в борьбе за время загрузки? Например, code-coverage tool — чтобы смотреть покрытие кодом страницы. А еще он показывает, какой процент кода не используется.  

Если вы используете какие-то третьи библиотеки — можно убрать их из runtime, воспользовавшись, например, webpack-libs-optimizations. Еще можно применить JavaScript Bundle Auditing. По-возможности отказаться от видео, так как парсинг самого контейнера для видео тоже занимает длительное время. И, конечно, нужно отказаться от gif. Если отказаться от видео не получается — использовать для его размещения <img src> контейнер.

Он поможет сгенерировать из загруженной вами картинки или группы картинок изображения для responsive верстки. Еще если у вас отзывчивые картинки на странице, можно использовать Responsive Image Breakpoints Generator. Кроме того, инструмент генерирует саму разметку на сайт. Вы можете указать, на сколько килобайт вам нужна картинка, с помощью движков генератора.

Если в вашей картинке есть какая-то важная часть, например, лицо или какой-то объект, он сделает сropping так, как вам нужно, что очень удобно.

Тогда можно прибегнуть к помощи LazySizes. Допустим, у вас очень много картинок. Это библиотека, которая делает все то же, что предыдущий инструмент, но только при помощи JavaScript.

Можно посмотреть, куда уходит время, когда происходит парсинг.
Интересный инструмент — Priority hints — в нем вы можете задать браузеру, что важно загрузить раньше, а что позже.

Он не обязательно нужен, если у вас хороший сервер и CDN, браузеры пытаются открыть еще одно соединение, если это HTTP/1. Но что же делать с critical CSS? Поэтому стоит протестировать, как работает версия с critical CSS и как — если critical CSS сохранен как отдельный файл в root. А если это HTTP/2, они пытаются «догадаться», какой CSS нужен, а какой нет.  

Guess.js

Да, у нас есть webpack, bundling, chunks. Но что, если есть инструмент, который с помощью алгоритмов предугадывания и машинного обучения помогает предугадать, какие chunks будут нужны на следующей итерации пользовательского взаимодействия? Guess.js с помощью predictive анализа, на основе данных google-аналитики, может понять, какое следующее действие совершит пользователь, и загрузить именно тот кусок кода, который необходим для этого взаимодействия.

Для webpack есть Guess плагин, который можно попробовать.

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

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

Допустим, нам нужно учесть следующие вещи: network transfer, parse/compile, runtime cost. Еще один совет: внимательно выбирайте фреймворк для разработки. Конечно, для этого есть инструменты, например, можно протестировать, как ваше приложение будет работать в разных сетях передачи данных: 2G, 3G, Wi-Fi.

Еще одна проблема, которая в нем есть, это server push: если есть server push — это было бы идеальной заменой для critical CSS. Проблема заключается в том, что HTTP/2, конечно, хороший новый стандарт, но всегда он быстрее, чем HTTP/1, во-вторых, он значительно медленнее на медленных соединениях, особенно если это мобильное устройство. Но как только мы запрашиваем страницу с сервера, последний не всегда знает, есть ли она уже в кэше. В таком случае пользователь, запрашивая index.html, получал бы его и в довесок critical.css.

Если это не первый заход на страницу, сервер все равно производит push. Поэтому сейчас разрабатывается механизм под названием cache-digest: если мы первый раз заходим на страницу, происходит server push, если no push — no repeat. Это надстройка над HTTP, которая сделаем механизм более продуманным, она работает вместо TCP на UDP протоколе. Это проблема, которую в Google решили исправить с помощью QUIC.

В то же время он медленнее на медленных соединениях. В QUIC много интересных вещей: он быстрее на быстрых соединениях, на 4G. Это отражает следующее изображение: Более того, так как он использует UDP, то требует больших ресурсов CPU в случае с JavaScript.

Service workers

Может быть, они смогут нам помочь? Судя по статистике, они дают ощутимый прирост производительности, если использовать их для кэширования. Первое — оптимизируем шрифты, второе — настраиваем service workers.

Можно использовать PWA Builder, он даже сгенерирует для вас иконку и манифест, чтобы ваше приложение было более прогрессивным. Как создать service worker?

Есть замечательный сайт PWA Stats, который собирает различные истории и кейсы по работе с PWA.

Сторонние скрипты — шаг в сторону зла?

Будет ли толк от улучшения производительности, если вы установили на сайт сторонние скрипты, они подгрузили еще скрипты со стороны и в итоге перегрузили и устройство пользователя?

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

Для того, чтобы узнать эту информацию, есть инструмент request map.

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

На основе положений коалиции о лучшей рекламе. Chrome пытается блокировать недобросовестную рекламу своим собственным блокировщиком.

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

Пользоваться инструментами для их контроля, например, с помощью requestmap.webperf.tools мы можем провести аудит сайта и сторонних скриптов. Так как понять, чем занимаются сторонние скрипты, пока вы на них не смотрите? Посмотреть статистику позже можно будет по ID: requestmap.webperf.tools/render/[ID]

На странице внизу есть ссылка по загрузке CSV файла с отчетом:

Потом можно пропарсить данные через терминал:

Разница будет очевидна. И получить код, который нужно вставить в блок web page test, после чего замерить, какая разница в производительности между приложением со сторонними скриптами и без них. Просто нам надо понять, как их оптимизировать. Это не значит, что их нужно удалять.

Можно вставить этот CSV в Excel и получить довольно подробный обзор того, какие у вас есть сторонние приложения, сколько они «весят», сколько грузятся. Как водится, для этого тоже есть инструменты. А еще интереснее будет попробовать blackhole сервер, его IP:

Чтобы узнать, как будет вести себя ваше приложение в случае, если все сторонние приложения уйдут в тайм-аут, добавьте в файл hosts этот ip и посмотрите, что произойдет с вашим приложением.

Лучше делать это через iframe, потому что тогда у них не будет доступа в DOM на вашей странице. Еще один совет: никогда не добавляйте third-party скрипты через тег script. Была даже создана спецификация Safe Frame, которая говорит об изоляции внешнего скрипта от данных приложения и контроле его деятельности. Кстати, в iframe есть свойство sandbox, в котором можно указать, что именно скрипт на странице делать может, а что нет. Если вас интересует эта тема, информацию по ней можно найти на github, проект safeframe.

Используйте service worker для того, чтобы заблокировать или удалить сторонний скрипт, если он завис.

Это позволяет загружать рекламные блоки, когда пользователь при просмотре страницы находится неподалеку от рекламного блока. При помощи Intersection Observer можно посмотреть, отобразилась ли реклама, когда находилась рядом с Viewport. Расстояние до рекламного блока можно указывать даже в пикселах.

Об этом вы можете прочитать в статьях Дениса Мишунова «Now You See Mee: How To Defer, Lazy-Load And Act With Intersection Observer», Harry Roberts «It’s My (Third) Party, and I’ll Cry if I Want To», Yoav Weiss «Taking back control over third-party content».

Отзывчивые email

У верстки email-рассылки свои особенности и правила. Теги img у клиентов без отображения картинок в письмах надо на что-то менять, поэтому используются атрибуты alt и другая черная магия.

Но что, если хочется чего-то новенького, например media queries: в каких-то браузерах они-таки поддерживаются, но с мобильными версиями email-клиентов дела обстоят хуже. Для нормальной верстки писем используются table-header-group, table-footer-group и другие атрибуты таблиц. Что, если использовать:

Вот пример такой магии:

Какое итоговое значение будет у класса box? Зависит от ситуации, по спецификации читаем так: если width-значение больше, чем max-width, max-width в приоритете.

Но если min-width, больше чем width или max-width, то применяется min-width.

Вот пример: как сделать из четырех колонок две на мобильном? Это можно использовать, когда медиа-запросы не поддерживаются. Ответ:

Это же шикарный хак! Грубо говоря, значение width определяет, max или min-width победит.

Например, добавить туда live twitter feed. А как сделать интерактивное письмо? Есть картинка со всеми твитами, которые есть, генерируется на сервере каждые 2 секунды, мы просто анимируем ее и все. Да, это возможно! Вот вам и решение.

Посмотрите на изображение и вы все поймете: Как сделать интерактивный email, в котором вы можете провести весь заказ и выбор товара?

Получится довольно длинная цепочка получится, но, тем не менее, это возможно сделать. Логика, завязанная на label, checked и input’ах. Обратите внимание, цена тоже считается, через counter и инкременты: Вот пример со статистикой использованных элементов.

Но не все так просто, у email есть ограничения по количеству символов (12000), поддержке :checked и размер письма ограничен 102kb. Казалось бы, фантастика, оказывается, через email можно привести человека к покупке.

Тем не менее, это главные тренды в маркетинге на сегодняшний день, и это видно на графиках:

Он нужен, чтобы автоматически генерировать нужную разметку в письме под ваши желания. Вот почему в Google создали AMP.

Вариабельные шрифты

Laurence Penney делал полезный доклад на эту тему, обязательно посмотрите.

Вот комментарий Hakon Wium Lie, одного из тех, кто писал спецификацию к шрифтам:

Звучит так: «Одна из причин, почему мы выбрали использовать трехзначные номера (в спецификации для значение font-weight) в поддержке промежуточных значений в будущем. И будущее уже наступило».

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

Все остальные начертания создаются автоматически, когда нужно. Дизайнеру достаточно создать два начертания символа — очень толстое, для значения 1000, и очень тонкое, для значения 1. Но это справедливо не только для оси width, также это работает и с height.

Использовать для этого в CSS надо font-variation-settings свойство. Еще сюрприз: оси мы можем создавать сами без особого труда. Оно задает значения для высокоуровневых свойств, таких как font-weight, font-stretch и других.

Вот пример настройки дизайнером шрифтов нужного шрифта:

Нужно использовать какой-то формат шрифта, позаботиться об откате, для старых версий браузеров, и подумать об отзывчивом поведении — правильно выставить значения для разных экранов. А что, если это где-то не поддерживается? Для старых версий браузер подберет сам нужный шрифт, правда, это означает некоторое отсутствие контроля за начертанием. Таким образом, используем формат WOFF2 для шрифтов, он более прогрессивный.

Резюмируем

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

Уже известная информация о программе — на сайте, и билеты можно приобрести там же. Если доклад понравился, обратите внимание: 24-25 ноября в Москве состоится новая HolyJS, и там тоже будет много интересного.


Оставить комментарий

Ваш email нигде не будет показан
Обязательные для заполнения поля помечены *

*

x

Ещё Hi-Tech Интересное!

5-нм на подходе — когда ждать новый техпроцесс

В начале октября тайваньский производитель чипов TSMC, который работает с такими компаниями, как AMD и Apple, сделал два заявления. Первое — компании удалось улучшить свой 7-нм техпроцесс и изготовить чип по новой технологии. Второе — 5-нанометровый чип выйдет в 2019 ...

Почему он нам не перезвонил-5, или Как я убежал с интервью в фирму, работать в которой — большая честь

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