Size: a a a

Иван Акулов про разработку

2018 December 27
Иван Акулов про разработку
Мини-конспект доклада «Make JavaScript Faster»

Законспектировал доклад «Make JavaScript Faster» с конфы performance​.now() (куда я поехал в этом ноябре, но счастливо проспал все утренние доклады): https://twitter.com/iamakulov/status/1077970286635614214

В конспекте:
— Как загружал скрипты IE 7 и как возникло правило «put scripts to the bottom»
— Как вырос объём third-party-скриптов за 7 лет (очень сильно)
— На что ещё обратить внимание при оптимизации JS, кроме привычных атрибутов <script async>/<script defer>
источник
2019 January 04
Иван Акулов про разработку
Наткнулся на классный пакет patch-package. patch-package помогает патчить пакеты из node_modules и сохранять эти изменения в гите: https://github.com/ds300/patch-package
источник
Иван Акулов про разработку
​​И ещё потвитил немного, как я нахожу, для каких ресурсов стоит добавить <link rel="preload">: https://twitter.com/iamakulov/status/1080467599392206848

(<link rel="preload" href="какой-то ресурс"> просит браузер предзагрузить какой-то ресурс, нужный для текущей страницы — например, CSS или JS — заранее. Это может помочь отрисовать страницу быстрее, но это надо использовать аккуратно. Если предзагружать слишком много, страница может даже замедлиться)
источник
2019 January 16
Иван Акулов про разработку
На ближайшей встрече #TC39 будет рассмотрена альтернатива текущим предложениям о приватных полях классов — приватные символы. Это предложение является компромиссом между приватными полями и старой версией пропозала о приватных символах, которая была ранее представлена комитету Кевином Смитом из Майкрософт.

https://github.com/jridgewell/proposal-private-symbols
источник
Иван Акулов про разработку
А тем временем продолжают кипеть страсти вокруг приватных свойств. Помимо альтернативного предложения о приватных символах (о котором я уже рассказывал), появилось дополнение к основным предложениям о приватных полях и приватных методах — new.initialize (на самом деле решает также и проблемы модификации цепочки прототипов). Но и это еще не всё. Появилось также предложение приватные декларации (честно говоря, по имеющейся информации я пока слабо понимаю мотивацию этого предложения).

Все эти три новых пропозала будут представлены уже менее чем через 2 недели на январской встрече #TC39.
Слайды к будущим презентациям:
- Private fields and methods refresher: Why they are based on WeakMaps
- Private Symbols for stage 1
- new.initialize for stage 1
- Private Declarations
источник
Иван Акулов про разработку
(@juliarderity вообще классный, читайте его)
источник
2019 February 15
Иван Акулов про разработку
​​Ускоритель Google Fonts → googlefonts.3perf.com

Сделал микроскрипт, который ускоряет рендеринг текста с гугл-шрифтами:
🔥 Рендерит текст на секунду или на две раньше в медленной сети
✂️ Занимает всего 550 байт с gzip
💼 Аккуратно фолбечится в старых браузерах
источник
Иван Акулов про разработку
​​В чём фишка
Если вы используете кастомные шрифты (в том числе Google Fonts), Chrome и Firefox не рендерят текст на странице сразу же. Вместо этого они держат текст невидимым несколько секунд, пока этот шрифт не загрузится. Это не очень заметно с быстрой сетью, но довольно неприятно на мобильных. А ещё это, скорее всего, влияет на конверсию и выручку.

Как это решают обычно

Обычно, чтобы решить это, используют CSS-рул font-display. Проблема в том, что в Google Fonts font-display не поддерживается, и единственная альтернатива — хостить шрифты на своих серверах, а это неудобно. (Есть ещё всякие JS-библиотеки вроде Webfont Loader, но с ними шрифт при первом посещении загружается медленнее.)

Как работает это решение

Чтобы решить это, я сделал скрипт, который фетчит CSS-файл гугл-шрифтов асинхронно, добавляет туда правила font-display и вставляет его в документ. А чтобы перформанс не падал, скрипт ещё генерирует несколько вспомогательных тегов вроде <link rel="preload">.

Какие результаты
Например, я поэкспериментировал локально на wordpress.org. Если загружать его на быстром 3G с этим скриптом, то текст рендерится на две секунды раньше, чем без скрипта.

👉 Устанавливайте: googlefonts.3perf.com
источник
Иван Акулов про разработку
источник
2019 February 20
Иван Акулов про разработку
Почти всегда, при разговоре о производительности веб-сайта, мы говорим о времени ожидания пользователем какого-то события ("First Meaningful Paint" и тд). Мы часто обсуждаем оптимизации фронтенда и бэкенда. И это круто, но остается корень всех бед - скорость света. Часто JavaScript разработчики упускают это проблему из виду 😀

Может ли случится такое, что через 30 лет Интернет будет настолько быстрым, что сайт с сервера в Сан-Франциско будет моментально открываться в Киеве? Физики говорит, что нет.

Допустим:
1. Твой бекенд рендерит страницу (или формирует JSON) за 20мс.
2. Не существует никакого WiFi, провайдеров, маршрутизации и тд. Есть просто оптоволоконный кабель, который одним концом вставлен в твой ноутбук, а вторым напрямую в сервер в Сан-Франциско. Растояние по прямой от Киева до Сан-Франциско - 9,848км (возьмем 10 тыс км для простоты счета).
3. Скорость света в вакуме 300 тыс км в секунду, скорость света в оптоволокне будет ниже - 200 тыс км в секунду.

Если мы посчитаем время, которое проведет наш запрос в пути, то мы получим 100 мс (10 тыс / 200 тыс * 2). Быстрее получить ответ не позволит скорость света.  Добавляем время оработки запроса и мы получим 120мс - в 6 раз дольше, чем наш запрос обрабатывает наш бэкенд.

========= Запрос к бэкенду ======
50ms: Kyiv -------запрос-----> SF
20ms: работа бэкенда        
50ms: Kyiv <------ответ------- SF

Хорошо, мы уже выяснили, что никогда не поиграем в CS:GO с ребятами с Сан-Франциско с пингом ниже 100м. Давайте дальше :)

Перед тем как запросить данные с сервера мы должны установить сетевое соединение. Протокол HTTP работает поверх TCP, следовательно нам нужно TCP соединение с сервером.

Для установки TCP соедения используется так называемое "тройное рукопожатие" ("TCP 3-way handshake") и теперь наш запрос выглядит:

========= TCP соединение ========
50ms: Kyiv -------syn--------> SF
50ms: Kyiv <------syn/ack----- SF
50ms: Kyiv -------ack--------> SF
========= Запрос к бэкенду ======
     Kyiv -------запрос-----> SF
20ms: работа бэкенда        
50ms: Kyiv <------ответ------- SF

Мы не тратим дополнительные 50ms после TCP хендшейка, поскольку мы можем сразу начать отправлять запрос после отправки ack, нам не нужно ждать ответ от сервера. Сервер, как примет ack, посчитает соединение открытым и сразу начнет обрабатывать наш запрос.

То есть ответ пользователь получит через 220ms, в 11 раз дольше, чем отрабатывал наш бэкенд.

Но мы используем HTTPS и нам нужно SSL/TLS соединение и оно устанавливается поверх TCP, и у него есть свой механизм рукопожатия для обменя ключами шифрования, и это нужно сделать до момента, как мы отправим наш запрос на сервер.

Наша схема превращается в:
 
========= TCP соединение ========
50ms: Kyiv -------syn--------> SF
50ms: Kyiv <------syn/ack----- SF
50ms: Kyiv -------ack--------> SF
========= TLS соединение ========
     Kyiv ---представление--> SF
50ms: Kyiv <--сертификаты----- SF
50ms: Kyiv ---обмен ключами--> SF
50ms: Kyiv <--обмен ключами--- SF
========= Запрос к бэкенду ======
50ms: Kyiv -------запрос-----> SF
20ms: работа бэкенда        
50ms: Kyiv <------ответ------- SF

То есть в условиях, которые не могут даже существовать, когда пользователь имеет оптоволоконный кабель длинной в 10тыс км от своего ноутбука к серверу, он получит ответ через 420мс, в 21 раз дольше чем отрабатывает наш бэкенд. Это без учета того, что нам нужно еще вначале сбегать к DNS, чтобы получить ip-адрес сервера.

Если мы разрабатываем веб-приложения (не важно фронтенд или бекэнд), то обязаны понимать азы работы веба.

Продолжение следует...
источник
2019 February 25
Иван Акулов про разработку
📐 for-of, reduce и перформанс

Рандомная напоминалка: разница в скорости между for-of и reduce (или любыми другими низкоуровневыми JS-штуками) не важна почти никогда.

for-of может быть быстрее reduce-а на 5 мс, если запустить его миллион раз — но это не играет никакой роли, если бандл с приложением загружается в тысячу раз дольше
источник
2019 March 01
Иван Акулов про разработку
На днях потратил несколько часов, чтобы закопаться в HTTP Archive — поэтому вот вам тоже пачка данных:

1️⃣ В дампе архива от первого февраля 134 млн сохранённых http-ответов

2️⃣ 63 млн из этих ответов — это JavaScript

3️⃣ 3 млн из этих JS-файлов ссылаются на соурс-мап (через sourceMappingURL)

4️⃣ Из первых 10000 ссылок на реальные соурс-мапы резолвятся 7387

5️⃣ 3407 из зарезолвенных соурс-мапов (46%) сделаны вебпаком

Не благодарите
источник
Иван Акулов про разработку
Выбирай сердцем
anonymous poll

Пахлава вебпаку – 256
👍👍👍👍👍👍👍 71%

Ура вебпаку – 55
👍👍 15%

Хвала вебпаку – 27
👍 7%

Похвала вебпаку – 25
👍 7%

👥 363 people voted so far.
источник
2019 March 19
Иван Акулов про разработку
​​Preload, prefetch и другие link-теги

В HTML есть аж пять link-тегов для того, чтобы что-нибудь предзагружать:
— Например, можно загрузить и закешировать какой-то файл заранее, чтобы, когда он понадобится, он достался мгновенно
— Можно установить соединение с каким-то сервером, но больше ничего не делать
— Можно даже отрендерить целую страницу в невидимой вкладке, чтобы потом переход на неё сработал мгновенно

Это всё помогает с перформансом.

Написал подробный гайд по всем этим link-тегам. Что они делают и когда использовать каждый из них: https://3perf.com/blog/link-rels/
источник
Иван Акулов про разработку
​​А также сделал красивую страничку со всем публичным, что мы в PerfPerfPerf сделали в рамках перформанса (надо больше!): https://3perf.com/content/
источник
2019 March 26
Иван Акулов про разработку
Ого, меня перевели! Если не прочитали прошлый пост на английском, читайте на русском:
источник
Иван Акулов про разработку
Preload, prefetch и другие теги <link>, которые префетчат ресурсы, резолвят домены и даже предварительно рендерят страницы для максимального ускорения. Иван Акулов в переводе на Хабре — https://habr.com/p/445264/
источник
2019 April 09
Иван Акулов про разработку
​​Google Fonts accelerator, v2

Выпустил вторую версию ускорителя гугл-шрифтов! Более приятный дизайн, поддержка нескольких CSS-файлов и фиксы разных эджкейсов. Подключайте, если ещё не

→ https://googlefonts.3perf.com
источник
Иван Акулов про разработку
И ещё мы запустились на продукт-ханте! Если используете скрипт и он вам нравится, поддержите нас :) А если нет, расскажите, что улучшить: https://www.producthunt.com/posts/google-fonts-accelerator
источник
2019 April 24
Иван Акулов про разработку
Как работает JavaScript-кеш в V8

V8 — это JS-движок, который используется в Chrome и Node.js. Команда V8 рассказала, как они кешируют скомпилированный JavaScript-код и как оптимизировать приложения, чтобы они кешировались лучше: https://v8.dev/blog/code-caching-for-devs

Второе не очень полезно (если у вас тормозит приложение, то вряд ли из-за плохого кеша), а вот первое интересно:

1️⃣ Когда V8 нужно выполнить какой-то JavaScript, V8 компилирует этот JavaScript из текста в байткод. Это выглядит вот так:
источник