# Понедельник 13 твитов
Привет!
Я — Артём @belov, инженер-программист.
Последние пару лет исследую «Web Perf», и с недавних пор — это моя д… twitter.com/i/web/status/1…
Будет круто, если позволите мне провести эту неделю на уровне «Advanced».
Попробую рассказать о чём-то продвинутом,… twitter.com/i/web/status/1…
Ну и чтобы хоть как-то поднять доверие к своим последующим тредам — представлюсь...
11:24Мне посчастливилось найти своё дело ещё в юности. В школе шёл на медаль и боялся после 9 класса поступать в ссуз (х… twitter.com/i/web/status/1…
11:24Взял красный диплом ССУЗа, и, как итог, на 18-летие я получил в трудовой книжке запись «программист». С тех пор стаж не прерывался.
11:24Я работал фронтендером и параллельно фулл-тайм учился в лучшем ВУЗе города.
Это был как раз тот период, когда «кажд… twitter.com/i/web/status/1…
Через несколько лет получил ещё один красный диплом (уже бакалавра) и начал выступать на профессиональных конференц… twitter.com/i/web/status/1…
11:24Двух лет выступлений хватило, чтобы на «YouTube» и «Хабре» искаться по запросу «Белов Артём фронтенд».
11:24Со временем стал тимлидом.
11:24Поступил в магистратуру, чтобы с профессором исследовать предиктивную загрузку веб-приложений. Уже три семестра экс… twitter.com/i/web/status/1…
11:24На момент первого курса магистратуры, стал руководителем разработки React-направления в одной из самарских компаний.
11:24Сейчас работаю над «Web Performance» в компании, которая отвечает за цвет купола в доме «Зингера».
11:24По сей день не боюсь быть студентом (в широком смысле слова) — учусь, пробую себя в контестах по программированию и… twitter.com/i/web/status/1…
11:24# Вторник 37 твитов
🧑🔬 Ревёрс-инжиниринг медленного Твиттера
Так получилось, что Твиттер в этой стране работает не шустро.
Давайте пр… twitter.com/i/web/status/1…
Это логично, ведь проблема по другую сторону их штаб-квартиры. Где-то на магистрали до Франкфуртского CDN, который и отдаёт нам статику.
6:43Возможно, команда Твиттера вообще ничего не делала. Но я в это не особо верю, так как отдел мониторинга привык виде… twitter.com/i/web/status/1…
6:43На всём пути инвестигации нам потребуется только вкладка «Network» в «DevTools», терминал и понимание работы сети.
6:43Кстати, проверить фундаментальные знания оппонента о работе сети можно прямо на этом инфоповоде.
Если собеседник сч… twitter.com/i/web/status/1…
В случае споров — напомните историю с LinkedIn.
Если же услышите «ты не понимаешь, это другое!», то просто извинитесь.
Начнём с того, что конкретно я не могу гарантировать технику, которая инкапсулирована в осуществление троттлинга за… twitter.com/i/web/status/1…
6:43Собственно, если полазить по Твиттеру, то всё кроме картинок и первых экранов выглядит шустрым, если не заострять в… twitter.com/i/web/status/1…
6:43Это отголосок грамотного агрессивного кэширования. 🙂 pic.twitter.com/9vee7CdfwB
Вам пишу «F12», сам нажимаю «Cmd+Option+I», а думаю вообще про «DevTools»...
6:43То есть, пара принципов агрессивного кэширования:
6:43Для потенциально изменчивых ассетов это даёт непрятный эффект. Пример с аватаром...
Вы: загрузили аватар и обновил… twitter.com/i/web/status/1…
6:43Это поведение можно переложить и на CSS.
Так что, keep in mind.
А про ETag сегодня кто-нибудь помнит ещё? 🧐
6:43В погоне за неизменчивыми хэшами в файлах можно взять и сделать из 100 модулей, например, 1000.
Тогда эта «оптимиз… twitter.com/i/web/status/1…
6:43Переводя зарубежный мем, получим формулу: «Чем больше вы модуляризируете приложение, тем больше оно становится».
6:43В довесок, может быть, и выкатывают релизы теперь пореже. Эдакая параллель с LTSB-веткой Windows – черри-пикают тол… twitter.com/i/web/status/1…
6:43А теперь, оставаясь в «DevTools» > «Network» сбросим кэш и жёстко перезагрузим страницу. Для этого — зажмите кнопку… twitter.com/i/web/status/1…
6:43Собственно, после перезагрузки страницы тормозят все запросы: от Initial (где мы получаем HTML) до API вообще на др… twitter.com/i/web/status/1…
6:43Характер тормозов один и тот же — очень долгий TTFB и Content Download.
Похоже, что хотя бы потери пакетов нет. pic.twitter.com/AwyAWZJ42D
Иначе, будь там PLR, тайминги загрузки для одного и того же ассета были бы разрозненные.
В стиле, что каждый 3-ий… twitter.com/i/web/status/1…
6:43Чтож. Перепроверим мои «теории» инструментами. Выполнив сотни тестов и попыток хоть как-то определить, что теряются… twitter.com/i/web/status/1…
6:43Да и вряд ли я теоретик... ибо не пишу на Coq.
6:43Так почему потеря пакетов — это важно?
Потому что есть вариант переключить протокол CDN на HTTP/1.1 + доменное шар… twitter.com/i/web/status/1…
6:49Дело в том, что H1 куда более устойчив к PLR (Packet Loss Rate), в отличии от H2.
TL;DR - Всё дело во внутреннем… twitter.com/i/web/status/1…
6:49Доменное шардирование в 2k21…
6:49Кстати, вспоминается та шутка про UDP, которая обычно не д
6:49Разумеется, подобного рода «спорные» решения не должны приниматься чисто на авторитете.
Это как в Data Science пол… twitter.com/i/web/status/1…
6:49Есть гипотеза по переходу с H2 на H1 для RU-региона?
Значит, её стоит подвергнуть АБ-тесту, где А-группа на H1, а… twitter.com/i/web/status/1…
6:49Разумеется, Твиттер использует HTTP/2 для статики. Ведь этот протокол был заточен и под медиа-контент. Но есть проб… twitter.com/i/web/status/1…
6:49Будь Твиттер на HTTP/1.1, то в четверг сюда можно было бы тупо не заходить.
6:49Послесловие:
Острых проблем с «Percieved Performance» в Твиттере не наблюдается, поэтому я их и не упоминаю. Они ни… twitter.com/i/web/status/1…
Виден инженерный подход 🥲
6:49И это всё?
Да. Ибо продолжать генерировать нерентабельные варианты — странная затея, чтобы набрать классы.
Напри… twitter.com/i/web/status/1…
6:49Неважно. Это нерентабельно. Инженер должен смотреть на проблему шире и оценивать не только пользу, но и затраты.
6:49# Среда 27 твитов
⚛️ Is React Suspense Ready Yet?
Тред о том, чему можно поучиться у инженеров «FB», что закладывали Suspense-логику… twitter.com/i/web/status/1…
8:49Disclaimer:
Подчеркну, что тред — исследование внутреннего устройства и попытки понять решения инженеров.
Призыва к использованию здесь нет.
Вообще, первое впечатление о Suspense, достаточно обескураживающее.
8:49Но если всё же начать разбираться и понять, что «Suspense» — термин, а затем разложить его на составляющие, то их б… twitter.com/i/web/status/1…
8:49C Reat.lazy() все знакомы — компонент для код-сплиттинга. pic.twitter.com/6IhZXrsDeX
И для того, чтобы заменять fallback-компонент, на тот, что загружается, тут используется «алгебраический эффект».… twitter.com/i/web/status/1…
8:49Со вторым компонентом Suspens'а (кэшем) всё неопределённо.
С ним непонятно что делать. Уже второй год.
В документ… twitter.com/i/web/status/1…
8:49Принцип работы React-компонента с кэшем аналогичен — бросить из компонента асинхронную функцию к API, так как для н… twitter.com/i/web/status/1…
8:49В этот момент происходит первая фаза понимания паттерна — отрицание.
— «Всмысле, кидать промис из компонента?» pic.twitter.com/dNGs1pGIvH
Затем, «гнев».
— «Так мне ещё и кэш самому надо инвалидировать? А давно это надо делать на фронте?» pic.twitter.com/mkE6d2JvSg
Потом, торгуешься, но всё же делаешь первую реализацию своего нерабочего кэша (на картинке).
— А что, пускай отдых… twitter.com/i/web/status/1…
8:49В конце приходит и понимание того, что в Suspense, так-то, содержится конструкция `catch`, которая ожидает выбрасыв… twitter.com/i/web/status/1…
8:49О да, и вот, без лишних предисловий, 20 твитов спустя, мы у чего-то интересного. 👏
8:58Понятие Suspense не ограничивается только отложенной загрузкой компонентов и данных.
Рассмотрим нестабильный компо… twitter.com/i/web/status/1…
8:58Про параметр `revealOrder` можно узнать самостоятельно. Из одноабзацевой документации.
Сейчас же, мы приглядимся ч… twitter.com/i/web/status/1…
8:58Опция `tail` имеет 2 состояния.
Нам интересен `tail="collapsed"`, что использует алгоритм отображения компонентов… twitter.com/i/web/status/1…
8:58Продублирую работу алгоритма...
Дано: 4 компонента, обёрнутые в SuspenseList c `tail="collapsed"`.
Hint: Начните… twitter.com/i/web/status/1…
9:141 коммит: 3 фоллбэк-компонента из 4. Где <D />? 😒 pic.twitter.com/G4HsM8aIX5
2 и 3 коммит — поочерёдная вставка загрузившихся компонентов <A /> и <B />.
4 коммит — одновременная вставка загру… twitter.com/i/web/status/1…
9:14Реконсилер в реакте штука сложная и она знает цену коммита в (Virtual)DOM. Это дорого.
А конкретно в данном случа… twitter.com/i/web/status/1…
9:14Фактически — реконсилер сэкономил на рендере фоллбэк-компонента, а к следующей транзакции уже был готов и сам загружаемый компонент.
9:14Итого, Suspense своей реализацией показывает:
9:14Десонмтрация работы алгоритма: suspensive-react.artbelov.now.sh/74* листайте вправо.
![]()
Десонмтрация работы алгоритма: suspensive-react.artbelov.now.sh/74
* листайте вправо.
11:15![]()
Автор недели: «Буду говорить академично»
Тоже автор недели: «Кэш — отвечает за кэш»11:16Но если всё же начать разбираться и понять, что «Suspense» — термин, а затем разложить его на составляющие, то их б… twitter.com/i/web/status/1…
⚛️ Is React Suspense Ready Yet?Тред о том, чему можно поучиться у инженеров «FB», что закладывали Suspense-логику… twitter.com/i/web/status/1…
Этот тред — выжимки из моих исследований 2019 года. Feel old yet?
Есть презентация suspensive-react.artbelov.now.sh
⚛️ Is React Suspense Ready Yet?
Тред о том, чему можно поучиться у инженеров «FB», что закладывали Suspense-логику… twitter.com/i/web/status/1…
11:19
Если «React Suspense» сам себя остановил на стадии эксперимента, то это можно считать успешным релизом? 🤔
18:51# Четверг 22 твита
🧑🔬 ML & JS: Предиктивная загрузка модулей веб-приложений
В этом треде я постараюсь популярно описать положение де… twitter.com/i/web/status/1…
8:44Disclaimer:
Автор треда постарался не жестить и особо не оперировать терминами из «Machine Learning».
Но тут всё равно очень душно. 🥵
Что мы знаем и слышали о предиктивной загрузке?
Очевидно — Guess.js
Проект был анонсирован на Google I/O 2018, за… twitter.com/i/web/status/1…
8:44По README в Guess.js видно принадлежность автора – человек из науки, Минко Гечев.
Структура документа, будто бы не… twitter.com/i/web/status/1…
8:44И после этого шквала событий… всё.
Проект по сей день в альфа-версии, а топ-контрибьютор — “renovate-bot”.
И може… twitter.com/i/web/status/1…
8:44В сторону предиктивной загрузки ислледуют множество компаний. У каждой свои цели.
Вот, например, патент* MS для вт… twitter.com/i/web/status/1…
8:44В научном же мире (пока в техническом тишина) солидные авторы, в авторитетных журналах, публикуют достойные научны… twitter.com/i/web/status/1…
8:44Короче говоря, у меня сложилось впечатление, что предиктивный фетчинг — это не совсем про «Open Source», а больше п… twitter.com/i/web/status/1…
8:44💡 Идея предиктивной загрузки модулей заключается в следующем:
На этапе сборки приложения, для каждого роута опреде… twitter.com/i/web/status/1…
8:44Итог — переход на роут практически мгновенный, так как все его ассеты (или большинство) уже предзагружены и остаётс… twitter.com/i/web/status/1…
8:44👍 Плюсы идеи:
1) меньше нагрузка на сеть.
2) меньше нагрузка на CPU, так как загрузка и парсинг выполняются с низ… twitter.com/i/web/status/1…
😓 Минусы:
1) внедрить в сборку (затратно)
2) настроить сборку (ещё сложнее)
3) отладить сборку (совсем фатально)
🧐 Что нужно понимать для интеграции предиктивной загрузки?
По сути, для реализации этой задачи хватает базового зн… twitter.com/i/web/status/1…
8:55🦸♂️ На данный момент, главный «компонент» предиктивной аналитики — цепи Маркова.
en.wikipedia.org/wiki/Markov_mo…
Эта мод… twitter.com/i/web/status/1…
8:55Модель имеет ряд разновидностей, которые тоже используются для «тренировки» на данных.
Например, скрытая Марковска… twitter.com/i/web/status/1…
8:55Для того, чтобы в ориентированном графе приложения искать роуты с сильной связностью, используется алгоритм Тарьяна… twitter.com/i/web/status/1…
8:55Опционально, для группировки роутов в группы, используется кластеризация методом k-средних.
В основном же, этим ме… twitter.com/i/web/status/1…
8:55👀 То есть, предиктивная загрузка - это сборка, цепи Маркова (или скрытая Марковская модель), метод Монте-Карло, алг… twitter.com/i/web/status/1…
8:55🧐 Итого, что мы имеем:
Предиктивная загрузка распространяется не таким уж стремительным темпом, как маркетинг «ML»… twitter.com/i/web/status/1…
9:01@jsunderhood а в чем профит если посчитать в деньгах (business value)?
«Amazon» ещё в 2017 запатентовали предиктивный поиск с предзагрузкой информации о результатах:… twitter.com/i/web/status/1…
@jsunderhood а в чем профит если посчитать в деньгах (business value)?
11:26
🧐 Что нужно понимать для интеграции предиктивной загрузки?По сути, для реализации этой задачи хватает базового зн… twitter.com/i/web/status/1…
Там не «Рокет саенс», можно и с батутом справиться.
🧐 Что нужно понимать для интеграции предиктивной загрузки?
По сути, для реализации этой задачи хватает базового зн… twitter.com/i/web/status/1…
14:17
💡 Идея предиктивной загрузки модулей заключается в следующем:На этапе сборки приложения, для каждого роута опреде… twitter.com/i/web/status/1…
О! У меня есть версия для тех, кто искал оптимальный путь... 🧐
Предиктивная загрузка — взвешенный граф. ⚛️
💡 Идея предиктивной загрузки модулей заключается в следующем:
На этапе сборки приложения, для каждого роута опреде… twitter.com/i/web/status/1…
14:18
# Пятница 20 твитов
🧑🏫 Почему «BigO» так важен в «Web Performance»?
В этом треде автор постарается объяснить, почему в «Web Perf» нет… twitter.com/i/web/status/1…
8:46📝 Disclaimer
Автор треда — адепт старой школы и в 2k21 зачем-то учится в универе, хотя это уже не модно. Убеждён,… twitter.com/i/web/status/1…
8:46Я не уверен, знают ли ребята без фундаментального образования, как обозначается блок модификации на блок-схеме, да… twitter.com/i/web/status/1…
8:46Если ты начертился на бумаге алгоритмов, то ставь класс. pic.twitter.com/R0OuuGeECJ
Придётся рассказать про опыт «старой школы» — мой.
Конкретно у меня было 2 преподавателя по алгоритмизации с абсолютно разными подходами.
8:46Алгоритмизация (опыт в техникуме)
Преподаватель давал разные задачи и принимал решения любой ценой.
Это олимпиадн… twitter.com/i/web/status/1…
8:46Алгоритмизация (опыт в универе)
Преподаватель давал не ёмкие задачи и принимал только максимально оптимизированные… twitter.com/i/web/status/1…
8:46Было забавно наблюдать за проверкой алгоритмов. Студент с алгоритмом на 10 блоков мог отлететь, а вот блок-схема на… twitter.com/i/web/status/1…
8:46НО!
Я не могу понять почему не использовал даже простые оптимизации первые 2 года в своём коде, вообще.
Наверное… twitter.com/i/web/status/1…
8:46Когда алгоритмическая база освоена, самое время расширить свои знания о структурах данных. Ещё.
Ибо если загуглить… twitter.com/i/web/status/1…
8:46– «Плохие программисты беспокоятся о коде. Хорошие программисты беспокоятся о структурах данных и их отношениях» ©… twitter.com/i/web/status/1…
8:46«BigO» и понимание структур данных — неотъемлемы.
Поэтому, затраты на: чтение, поиск, вставку и удаление сначала (… twitter.com/i/web/status/1…
8:46Там еще есть такой прикольный момент, когда ты сам понимаешь цену вставки:
8:46И вот когда у тебя в голове есть понимание структур данных, а твои руки могу зачертить блок-схему, чтобы это понял… twitter.com/i/web/status/1…
8:46Со временем, у тебя появляются следующие повадки:
8:46И восприятие эвристики оптимизации программы, меняются.
Нпример, помню свои мысли, когда увидел `optimize-js`: «Ог… twitter.com/i/web/status/1…
8:46В трюк с обёртыванием объектов в `JSON.parse` уже хочется вникнуть, а не просто использовать.
Что ж, идешь и смотр… twitter.com/i/web/status/1…
8:46А затем у тебя начинают вызывать вопрос: `React.memo`, `shouldComponentUpdate` и кастомные компараторы.
– «А зачем… twitter.com/i/web/status/1…
8:47Итого, что нам даёт понимание «BigO» и структуры данных?
Они дают надежду, что «Web Performance» не скатится в чек… twitter.com/i/web/status/1…
8:47И тогда, придёт и понимание того, что «UX» не заканчивается при остановке профайлера в "Idle", путь пользователя зд… twitter.com/i/web/status/1…
8:47# Суббота 1 твит
Если у вас есть желание поговорить о «Web Performance» (и вышке), то завтра в 19:00 МСК залетайте в «ClubHouse»!
joinclubhouse.com/event/xqYw7A8D
20:02# Воскресенье 22 твита
🚀 Web Performance Profiling: 101
В этом треде найдём все неоптимизированные строки кода в рамках одного файла и по… twitter.com/i/web/status/1…
13:13⚠️ Disclaimer:
От этого треда не стоит ждать решения всех Performance-проблем. Ибо «DevTools» – не тот инструмент,… twitter.com/i/web/status/1…
📝 Предварительные требования:
1) Понимать что такое стек вызовов (LIFO)
2) Примерно понимать как интерпретатор JS «… twitter.com/i/web/status/1…
Крайне желательно, чтобы были подключены «SourceMap».
Сердитый вариант — `cheap-module-source-map`.
И помните, что… twitter.com/i/web/status/1…
13:13🧑🏫 Дано:
Написан код, который вызывает подозрения.
Мы понимаем, что он тормозит, но не совсем понимаем, где и в ка… twitter.com/i/web/status/1…
Действия:
1) Открываем приложение и жмём «F12» > «Performance»
2) Для контраста замеров, выставляем троттлинг: ⚙️>… twitter.com/i/web/status/1…
Теперь нам необходимо записать профайлером работу замеряемого кода. Здесь может быть два алгоритма:
1) Код вызывает… twitter.com/i/web/status/1…
Когда Profile-таймлайн отобразился, то можно сразу перейти в нижнюю часть панели, и нажать «Bottom-up».
Нам будут… twitter.com/i/web/status/1…
13:13Если исследуемая функция в ТОПе по времени, то ОК — дебажим дальше.
Если нет, можно отфильтровать функцию по имен… twitter.com/i/web/status/1…
13:13Теперь, посмотрим на тайминги каждой строки в панели «Sources».
Тут 2 варианта перехода:
1) Нажимаем правой кнопко… twitter.com/i/web/status/1…
И тут есть пара не самых очевидных моментов при работе с этими таймингами.
Покажу на примерах...
13:13Тайминги возле строк — суммарные.
Всегда будьте внимательны при отслеживании цепочки вызовов. «Тормозящими» могут к… twitter.com/i/web/status/1…
Для наших целей хватит `console.time`, который по-старинке а̶л̶ё̶р̶т̶а̶м̶и̶ в консоль выведет промежуточные замеры… twitter.com/i/web/status/1…
13:13🧐 Pro Tip
Если вы дебажите цикл\генератор\подписку и устали фильтровать результаты из общей массы, то рискну напом… twitter.com/i/web/status/1…
13:13И для адептов FP – про тайминги у чейнингов.
Они, (на данный момент?), профайлятся не всегда стабильно.
Поэтому,… twitter.com/i/web/status/1…
13:13Q: Хотелось бы больше... а через какие курсы сейчас вкатываются в «DevTools»?
A: Сейчас? Не знаю, сам же был Early… twitter.com/i/web/status/1…
🧑🔬 Ревёрс-инжиниринг медленного ТвиттераТак получилось, что Твиттер в этой стране работает не шустро.
Давайте пр… twitter.com/i/web/status/1…
🧑🔬 Ревёрс-инжиниринг медленного Твиттера
Так получилось, что Твиттер в этой стране работает не шустро.
Давайте пр… twitter.com/i/web/status/1…
⚛️ Is React Suspense Ready Yet?Тред о том, чему можно поучиться у инженеров «FB», что закладывали Suspense-логику… twitter.com/i/web/status/1…
⚛️ Is React Suspense Ready Yet?
Тред о том, чему можно поучиться у инженеров «FB», что закладывали Suspense-логику… twitter.com/i/web/status/1…
15:22🧑🏫 Почему «BigO» так важен в «Web Performance»?В этом треде автор постарается объяснить, почему в «Web Perf» нет… twitter.com/i/web/status/1…
🧑🏫 Почему «BigO» так важен в «Web Performance»?
В этом треде автор постарается объяснить, почему в «Web Perf» нет… twitter.com/i/web/status/1…
15:22🧑🔬 ML & JS: Предиктивная загрузка модулей веб-приложенийВ этом треде я постараюсь популярно описать положение де… twitter.com/i/web/status/1…
🧑🔬 ML & JS: Предиктивная загрузка модулей веб-приложений
В этом треде я постараюсь популярно описать положение де… twitter.com/i/web/status/1…
15:22🚀 Web Performance Profiling: 101В этом треде найдём все неоптимизированные строки кода в рамках одного файла и по… twitter.com/i/web/status/1…
🚀 Web Performance Profiling: 101
В этом треде найдём все неоптимизированные строки кода в рамках одного файла и по… twitter.com/i/web/status/1…
15:22