Андрей Прокопюк

Андрей Прокопюк

Темы
Неделя
Mar 23, 2020 → Mar 29, 2020

Архив недели @Andre_487

Понедельник


Всем привет! Я @Andre_487 (Андрей по-простому) – разработчик, аналитик, менеджер. Занимаюсь тем, что делаю веб-сервисы быстрыми. @DmitryMakhnev предоставил мне честь веселить народ в jsunderhood на этой неделе. Ну, приступим…

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

Раз будем говорить о скорости, пожалуй, следует начать с методик измерения. Так уж у нас заведено – не измерил, значит, не было. Некогда мы со @st00nsa рассказывали об этом на HolyJS: youtu.be/Whm2FMBIgA0, youtu.be/TzCMDlYMydA Подробнее – в треде

В классической модели скорости мы смотрели вот на что: FCP – время первой отрисовки контента FMP – время отрисовки полезного контента JS inited – время, когда заработали все JS-элементы Пока так и продолжаем, но появляются новые вызовы, ответ на которые мы готовим

FCP – время первой отрисовки. Оно должно быть минимальным. Но для всех ли проектов и для любых ли переходов? Пользователям не очень нравится мигание блоков страницы, а оно будет при большой дельте между FCP и FMP. Возможно, пора смотреть и на эту дельту.

FMP – время отрисовки значимого контента. Очень показательная метрика, для которой нет стандартного способа измерения. Нужно комбинировать разные API, чтобы получить эти данные: requestAnimationFrame, IntersectionObserver, Element Timing, Resource Timing. Самая сложная метрика

JS inited в первой своей версии был прост – время, когда фреймворк закончил развешивать обработчики после DOMContentLoaded. Но что если фреймворк не ждёт DCL, а инициализируется по мере появления элементов во вьюпорте? Какое время считать? Об этом задумались при переходе на React

🔥Тред (Андрей Прокопюк)
Как выбрать значимый контент для измерения FMP? Очень индивидуально для проекта. Google пробовали разработать универсальную метрику, но отчаялись. Теперь вместо неё LCP: web.dev/lcp/ Но если нет универсальной – не значит, что не нужно делать свою под проект

Для ЯндексПоиска FMP – это отрисовка выдачи. И это можно вычислить приблизительно. Отрисовку контента можно оценить интервально так, как я рассказывал на HolyJS: gist.github.com/andre487/25410… Так мы и делали долго. Но как же картинки? Их не учитывали, а зря

Однажды мы научились исследовать UX в разрезе скорости с помощью краудсорсинговой платформе Толока. И вот оказалось, что пользователи считают страницу, где картинки загрузились сильно позже отрисовки текста, более медленной, даже если уже могли читать текст

В данный момент работаем над метрикой FMPv2, которая будет учитывать также и время отрисовки (или загрузки) видимых картинок. Смотрим в сторону Element Timing или Resource Timing github.com/WICG/element-t… developer.mozilla.org/en-US/docs/Web…

🔥Тред (Андрей Прокопюк)
Кто любит, когда в процессе загрузки блоки на странице прыгают, появляются и исчезают? Я знал только одного такого человека. Ему ещё вручили судебный запрет на работу над клиентскими приложениями. Численно эту проблему оценивает Cumulative Layout Shift: web.dev/cls/

Largest Contentful Paint (LCP, web.dev/lcp/) – интересная метрика, но есть проблема – на неё влияют не только изменения в интерфейсе, но и изменение сценариев пользователя. Мы разработали Largest Loading Element Pain – как LCP, только финалом считается window.onload

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

Последняя метрика перед сном – Time To Interactive (TTI): web.dev/tti/ Время от старта запроса до момента, когда всё перестало тормозить. Мы используем её с изменениями: TTI у нас наступает, когда 3 секунды не было лонг-тасков. Сеть не учитываем

«Фиалки в саду. Одуванчики вдоль дороги. Неизбежное время сна. Жидкость стекает из порезанного запястья» Это значит, что я люблю ранние части Silent Hill, а также понимаю неизбежность отхода ко сну. Выгорание, о котором позже, любит отсутствие режима сна, а я не люблю выгорание

Вторник


В одном из тредов был спор, что TTI должен быть единственной метрикой. Это не так, но единую метрику построить можно. Компонентами должны быть FCP, FMP, JS inited, а также можно добавить любые другие, включая TTI. Сегодня поговорим о составных метриках.

Один из возможных пререквизитов к комбинированию метрик – переход от классических агрегаций (средняя, процентили), которые комбинировать не очень честно, к метрикам восприятия, основанным на восприятии пользователем задержек: smashingmagazine.com/2015/09/why-pe…

Мы выбрали такие пороги: FCP, FMP: - мгновенно: <= 200 мс - хорошо: <= 1 с - терпимо: <= 2 с - медленно: >= 3.5 с - ужасно: >= 5 с JS inited, TTI: - мгновенно: <= 200 мс - хорошо: <= 2 с - терпимо: <= 3.5 с - медленно: >= 5 c - ужасно: >= 10 c Отрисовка – 1 волна, JS – 2

Когда мы имеем оценку, насколько пользователю было хорошо по всем параметрам (FCP, FMP, JS inited, TTI), мы можем создать комбинированную метрику. Самое простое – взять по минимуму. Допустим, если на запросе оценки "хорошо, терпимо, медленно, ужасно" – ставим "ужасно" запросу.

Ещё способ комбинировать метрики – голосование. Можно реализовать алгоритм голосования вроде такого: gist.github.com/andre487/27dc9… Он отвечает на вопрос, можно ли считать запрос хорошим с точки зрения скорости. Коэффициенты нужно подбирать экспериментально

И ещё способ – Apdex: en.wikipedia.org/wiki/Apdex Но в нём нет штрафа за "плохие" показатели.

У замедлений есть опасное отличие от поведенческих метрик. Пример: мы вырастили клики на 10%, а замедлились всего на 5%, пользователь и не заметит. И правда, он заметил то, что растит клики, в тот же момент, а замедление на 5% – нет. Но 4 эксперимента, и будут очень заметные 20%

А сегодня перед сном будет не метрика, а утверждение. Фуллстек существует! Всем спокойной ночи.

Среда


Начнём день с обмена опытом. В тред призывается @jin_nin для рассказа про свою оригинальную методику оценки скорости веба

Ожидание в предыдущем твите затягивается, поэтому завершим про метрики. Их нельзя рассматривать как истину и по одной. Нужно смотреть вместе, желательно в А/Б и вместе с поведенческими. Метрики – как полиграф. Не говорят, кто врёт, но дают полиграфологу информацию для анализа.

Как мы вчера выяснили, фуллстек существует. Разработчик решает задачи бизнеса, и есть такие задачи, где нужен один человек, который настроит сервер, развернёт Bitrix/Wordpress/etc, напишет немного PHP/CSS/HTML и задача будет решена. Не понимаю, почему тема холиварная.

Теперь давайте серьёзно обмениваться опытом. Скорость в том числе предоставляется как консалтинговый сервис. Вот @vigodnee знает про это кое-что. Хотелось бы узнать подробностей.

Официальное заявление по итогам тредов: если у вас проблемы со скоростью сервисов Яндекса – пишите на andre487@yandex-team.ru с деталями для дебага. Всё будет рассмотрено, и либо исправлено нашей командой, либо передано куда надо.

Четверг


Среда – это маленькая пятница, поэтому финальный твит в 1:27. Чтобы не выгорать (о чём позже), нужно иногда добавлять рандома в график. Всем спокойной ночи.

Метрики – безусловно очень интересная штука, но не в них цель скорости. Цель скорости – в скорости, как бы странно это ни звучало. А метрики – инструмент контроля и приоритизации задач. Поговорим сегодня о том, что используется в Поиске для ускорения

Первая крутая оптимизация – отдача страницы чанками. Поиск занимает несколько сотен миллисекунд, но у страницы есть части, которые не зависят от данных из базы. Почему бы не отдать их как можно раньше? Как минимум, можно отдать head, куда положить link[rel=preload]

Пример отдачи страницы чанками: gist.github.com/andre487/cb299… Можно даже показать какую-то часть страницы пользователю, пока идёт запрос за данными. Это не всегда хорошо, поэтому можно не отправлять body, чтобы не было белой вспышки, но начать префетчить ресурсы

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

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

Пятница


Reduce bundle size via one-letter css classname hash strategy dev.to/denisx/reduce-… #dev #frontend #css #webpack #perfomance
Мы пробовали и этот метод. Размер страницы до gzip действительно драматически уменьшается, но выигрыша по FCP, FMP, JS inited мы не увидели. Да и размер после gzip/brotli/SDCH уменьшается уже не так драматически. Взвесили и отказались в связи с усложнением связи DOM и JS-логики twitter.com/denisx/status/…

Ну и твит на позднюю ночь. SDCH – крутой, но сложный способ сжатия: en.wikipedia.org/wiki/SDCH Его выпилили из Chrome в 17 году. Но мы (Яндекс.Браузер, приложение Яндекс) его поддержали и используем вместе с brotli.

Интересный способ оптимизации – унести все сервисы на единый домен. Вместо images.yandex.ru делаем yandex.ru/images, получаем прогретое Keep-Alive или HTTP/2 соединение, быстрый переход и драматическое ускорение.

Мы показываем лёгкую версию выдачи на медленных соединениях. Это совсем другая вёрстка и урезанные фичи. Медленное соединение понимаем по первым syn/ack на этапе установки соединения. Дальше работает алгоритм анализа и принимается решение, медленно или ок.

А теперь шок. Перезагрузить целую (ну или большой кусок) страницу через AJAX – медленнее с точки зрения FCP и FMP, чем новая навигация. Всё потому, что при навигации браузер умеет рендерить прогрессивно, а при манипуляциях с DOM через JS – нет. Теперь в шапке Поиска нет AJAX

На своём поле (Яндекс.Браузер, приложение Яндекс) мы используем ML для предсказания финального запроса пользователя и пререндерим выдачу для него. Можно почитать вот тут: habr.com/ru/company/yan…

Ну что, снова про фуллстек? Я вижу ошибку в наличии "стек". Очень редок специалист, знающий все уровни, на которых работает приложение. Мне нравится "дивергент", узнал об этом из обзора BadComedian на фильм "Дивергент": youtube.com/watch?v=KCTRET…

Быть узким специалистом – хороший выбор для work-life balance в сторону life. Но если хочется расти как крутой решатель задач с карьерой, нужны знания из разных смежных областей, нужных бизнесу. И это может быть не стек, а точки на плоскости с неравномерной плотностью

Суббота


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

Pull Request Измерение скорости SSR и размера ответа как часть CI. Если мы видим деградацию – pr нельзя влить. По возможности можно измерить на реальном девайсе из облака клиентские метрики. Это долго и пока на совести разработчика

Релиз – все те же проверки, что и в pr, только базой для сравнения является не текущий master, а предыдущий релиз. В релизе также можно измерить клиентские метрики, так как это не будет лежать на критическом пути, не смотря что долго.

Эксперимент Все нужные скоростные метрики реализованы в А/Б, есть механизмы предупреждения экспериментатора о проблемах со скоростью. Также за этим следят эксперты по экспериментам, без подтверждения которого раскатывать нельзя.

🔥Тред (Андрей Прокопюк)
Разработчики команды скорости сами разрабатывают метрики, пишут инструменты, оптимизируют код. Это разные области знания Если бы этим занимались несколько команд узких специалистов, эффективность была бы сильно ниже и потребовались бы большие менеджерские усилия

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

Воскресенье


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

Опрос на ночь. Из серии тем про выгорание, life-work balance и прочее такое. Как вы оцениваете свой запас сил во время рабочих дней на момент окончания работы? Попробовал задать уровни, исходя из своего опыта.
🤔 8.9% Хорошо: активный отдых
🤔 12.9% Норм: чтение умных книг
🤔 63.5% Так себе: сериалы/игры
🤔 14.7% Нет сил: сразу спать

Синдром хронической усталости, выгорание, депрессия – всё это я испытывал, но больше не хочу. Порой нахожусь где-то недалеко, но уже года 4 не приближаюсь больше чем на 12 метров, не смотря на рост нагрузки. Поделюсь своими методиками, а вы поделитесь тут своими.

Сон. Мне всегда дико не хочется идти спать, ведь сон – это маленькая смерть и время безделия. Но сон возьмёт своё с процентами, если с ним бороться. Сон всегда победит в одну калитку. Нужно стараться спать 8 часов, ложиться до полуночи.

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

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

Вредные привычки. Я пока с ними – пью, курю и ругаюсь матом Они вредят здоровью, в том числе так: никотин – стимулятор, провоцирует работу на износ. Алкоголь – волшебный эликсир, может развеселить, но несколько дней будешь расплачиваться Встречи с этим нужно минимизировать

Дозирование нагрузки и цикличность При гибком графике нужно сделать себе негибкий. Главное – фиксировать время ухода из офиса Ухожу в 19:00, меняю обстановку. Могу иногда ещё поработать, но уже только из дома. А лучше спланировать на завтра

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

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

Отпуск К концу года должны быть потрачены все отведённые дни отпуска Очень желательно в отпуск куда-то уехать, чтобы отключиться от бытовых проблем

Альтернативная профессиональной умственная нагрузка У меня лайтовая – смотрю АНТРОПОЗЕНЕЗ.РУ, UtopiaShow, TrashSmash, Разведопрос и всякие популярные лекции Особенно интересно про биологию, астрономию, археологию, историю. Переключает мозг

Физическая нагрузка В отличие от других правил, тут у меня очень переменный успех, но когда он наступает – становится сильно лучше Спортзал, длительные прогулки, велосипед и всё такое

Обращение к психологу Сильно ускорит разрешение каких-то внутренних противоречий и повысит продуктивность на длительной дистанции Бояться и стесняться этого не нужно

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

🔥Тред (Андрей Прокопюк)
Что ж, вот и закончилась наша неделя. Я не заходил в Твиттер с 2018 года, а тут зашёл и прямо понравилось. Продолжу у себя у в @Andre_487 Спасибо всем! Было круто. До вступления в должность следующего ведущего ещё поотвечаю на комменты, но всем предварительное пока!

Ссылки