Skip to content

Instantly share code, notes, and snippets.

@taxigy
Last active December 6, 2018 12:49
Show Gist options
  • Save taxigy/7888395a3c31b5acc352bdb2b0d4ab2a to your computer and use it in GitHub Desktop.
Save taxigy/7888395a3c31b5acc352bdb2b0d4ab2a to your computer and use it in GitHub Desktop.
Notes from FrontendConf 2018

Иван Тулуп: асинхронщина в JS под капотом / Михаил Башуров (Luxoft)

Фазы Event Loop в Node (19:40):

  • timers — исполняем коллбэки готовых таймеров.
  • pending callbacks — коллбэки от некоторых системных операций (например, TCP error).
  • idle, prepare.
  • poll — исполняет IO-коллбэки, круто делать setImmediate; если нет таймеров и setImmediate, то ждём событий от IO; есть лимит по количеству коллбэков, то есть защита от слишком долгого выполнения этой фазы.
  • check — исполняется setImmediate, который выполнится в poll-фазе раньше таймера.
  • close callbacks — коллбэки закрытия сокетов, но только если это событие произошло неожиданно.

libuv предоставляет event loop, Node использует фазы из libuv.

Микротаски (30:25):

  • Promise.then, но не сам Promise(•)
  • Mutation observer
  • Выполняются все микротаски в очереди до самого конца.
  • Если порождаются новые микротаски, они тоже будут выполнены.
  • Выполняются после макротаска или если опустел стек.

Как работает Headless Chrome / Виталий Слободин (Elonsoft LLC)

Компоненты системы браузера:

  • Platform layer
    • Ozone — взаимодействие с UI/IO
    • Scheduler
    • Net
  • Content layer — самый большой компонент
    • Blink — веб-движок, который умеет парсить и рисовать HTML и выполнять JS + DevTools Protocol + Extensions API.
    • Content API поверх Blink, чтобы использовать его.
  • Headless layer
    • Headless library: Embedder API & Content API
  • Application layer

Puppeteer (15:45):

  • Брать с NPM.
  • Рендеринг работает только на CPU.
  • Нет поддержки аудио и видео.
  • Может изолировать сессии: отдельные куки, LocalStorage, Cache для каждой «вкладки»; можно сериализовать сессии для последующего использования.
  • Виртуальные таймеры: прокрутить время вперёд, например, ускорить анимацию, или остановить время, пока выполняется сетевой запрос, или управлять работой отрисовщика.
  • Работа с сетевыми запросами: можно менять запрос налету.

Проблемы (28:10):

  • отличие в рендеринге страницы на разных платформах: не тестируйте скриншотами!
  • блокировки
  • некоторые функции реализовать невозможно. Например, Flash.
  • нет стандартного API.

Знай свой JIT: ближе к машине / Андрей Мелихов (Яндекс.Деньги)

Движки:

  • Chakra (JScript, not Javascript!) — in IE
  • ChakraCore (JavaScript)
  • SpiderMonkey — Firefox
  • JavaScriptCore — Webkit, RN
  • V8 — Node
  • Rhine, Nashorn — Java
  • JerryScript

JIT

  • спекулятивная оптимизация;
  • оптимистичная;
  • если догадка неверна, код будет деоптимизирован.

Интерпретатор и компилятор:

  • Ignition — interpreter
  • Turbofan — compiler

Задачи интерпретатора (9:02):

  • уменьшить накладные расходы на парсинг
  • уменьшить потребление памяти

Холодные и горячие функции (10:35):

  • интерпретатор собирает информацию о типах и горячих функциях
  • отдаёт оптимизатору
  • оптимизатор исполняет
  • если что-то пошло не так, деоптимизирует и сообщает об этом в интерпретатор

Мономорфность (11:40): если функция всегда оперирует одними и теми же типами; в этом случае оптимизируется.

Hidden classes (12:05)

  • все объекты имеют скрытые классы (в V8 они называются “Map”)
  • описывают структуру объектов
  • меняются при удалении или добавлении проперти объектов

Специальный синтаксис в Node (14:19):

$ node --allow-native-syntax

и

%HasSameMap({ a: 1 }, { b: 1 }); // -> false

Inline cache (14:30):

  • каждый аргумент функции имеет один и тот же тип при вызове в рантайме — мономорфное состояние,
  • тип аргументов поменялся — полиморфное состояние,
  • снова поменялся — мегаморфное состояние, неоптимально.  Разные типы массивов (16:30):
  • PACKED_SMI_ELEMENTS 〜 [smallint]
  • PACKED_DOUBLE_ELEMENTS 〜 [double]
  • PACKED_ELEMENTS 〜 [any]
  • HOLEY_SMI_ELEMENTS 〜 [int | undefined ]
  • HOLEY_DOUBLE_ELEMENTS
  • HOLEY_ELEMENTS

Массивы деградируют в типах и не улучшаются обратно, HOLEY_ELEMENTS не будет оптимизирован обратно в PACKED_• в рантайме!

Примеры массивоподобных типов (19:00): arguments и document.querySelectorAll(•). Возвращают типы, похожие на массивы, но не массивы. Оптимизированы не будут.

const map = f => x => Array.prototype.map.call(x, f); // <- не оптимизирован
const args = Array.prototype.slice.call(arguments); // <- оптимизирован
(…args) = arguments; // <- оптимизирован

Большие массивы (20:15):

  • new Array(1000) — сразу создаём массив с тысячей дырок HOLEY_ELEMENTS, он не будет оптимизирован: быстро пишем, медленно работаем
  • array = [] — создаём пустой массив: медленно пишем, быстро работаем.

Сборщик мусора (20:50):

  • пространство молодых объектов — Scavenge
  • пространство старых объектов — Mark-Sweep

WASM (23:00)

  • статически типизирован
  • оптимизирован на этапе компиляции — не нужно оптимизировать в рантайме — быстрее работает
  • ручное управление памятью — не нужен GC — быстрее работает
  • сам код более оптимален — исполнение быстрее работает

Три вида оптимизаций (25:10):

  • Алгоритмические — написать более эффективный алгоритм
  • Специфические для языка — правильно управлять типами в рантайме
  • Специфические для движка — самые опасные (интересная заметка: если сделаны оптимизации для движка, их нужно покрывать перфоманс-тестами, которые будут доказывать, что и в будущих версиях движка код работает быстрее, чем без оптимизаций)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment