Работа движка браузера
Ссылки
WebAssembly
WebAssembly (WASM) — бинарный формат, позволяющий запускать код в браузере
Точнее: бинарный формат инструкций для стековой виртуальной машины. WebAssembly спроектирован как портативная цель компиляции для высокоуровневых языков, таких как C/C++/Rust, которую можно развертывать в web для клиентских и серверных приложений.
Представляет собой переносимое абстрактное синтаксическое дерево, обеспечивающее как более быстрый анализ, так и более быстрое выполнение кода, чем JavaScript.
Это эффективный низкоуровневый байт-код для веб-приложений. Wasm даёт возможность разработки функционала веб-страниц на языках, отличных от JavaScript (например, это C, C++, Rust и другие). Код на этих языках компилируется (статически) в WebAssembly. В результате получается веб-приложение, которое быстро загружается и отличается очень высокой производительностью.
Зачем?
- быстро исполнять код в браузере. Быстрее чем JavaScript — в идеале, со скоростью света родного кода нашего процессора.
- Zero configuration — решение «из коробки», без установки, нужен только браузер.
- Безопасно — новая технология не должна создавать новых угроз.
- Кросс-платформенно — у нас есть несколько платформ, включая мобильные, несколько операционных систем.
- Удобно для разработчиков — нужны удобные средства разработки и отладки.
В принципе,эту задачу решает JS. Что плохо: нужен плагин и/или runtime ⇒ нет zero configuration. У JS есть внутренние ограничения, которые уже не позволят сделать его радикально быстрее.
Потенциальные альтернативы (не прижились):
- NaCl (Native Client) - Google
- PNaCl (Portable Native Client) - LLVM IR subset.
- asm.js - Mozilla
Преимущества WebAssembly
- Скорость — почти как родной код.
- Эффективность — бинарный формат, быстрый парсинг и компиляция.
- Портируемость — все браузеры и операционные системы.
- Безопасность — запуск в sandbox.
- Удобство отладки — поддержка отладки в браузерах, отладчик есть уже сейчас.
- Открытый стандарт — то есть это уже не инициатива отдельной компании, пытающейся «перетянуть одеяло на себя». Стандарт уже принят, в 2017 году.
Так что же такое WebAssembly?
- Бинарный формат
- НЕ язык программирования, а байт-код. Мы же не называем Java-байткод языком программирования.
- Загружается в браузер и исполняется в браузере. Формально, WebAssembly исполняется JavaScript-движком, а не самим браузером, поэтому есть и другие варианты исполнения, например, под NodeJS.
- Исполняется виртуальной машиной. Это простая стековая машина с памятью, простота позволяет легко реализовать её для любого современного процессора.
- НЕ имеет ничего общего с Web, кроме того что общается с внешним миром через JavaScript. Действительно, WebAssembly это просто виртуальная машина, имеющая память и исполняющая инструкции.
Unsorted WebAssembly - это просто куски кода внутри js-программы которые работают максимально быстро. Также и WebCL(использование параллельных вычеслений на видеокарте)
Просто js работает в 2-5 раз медленнее чем аналогичная программа на Си (производительность отжирает интерпретатор). Для преодоления этой проблемы в js внедряют WebAssembly и WebCL чтобы добиться максимально возможной производительности
Улучшение JavaScript: Реализуйте все критичные вещи на wasm и импортируйте его как стандартный JavaScript модуль.
WebAssembly определяет абстрактное синтаксическое дерево (как и JavaScript) в бинарном формате. Вы можете писать код и чистить его от ошибок в текстовом формате. WebAssembly легко читаем.
Улучшение для браузеров: Браузеры будут понимать бинарный формат, а это значит, что разработчики смогут компилировать бинарники, которые можно сжать гораздо больше, чем используемые сегодня текстовые файлы с JavaScript. Чем меньше файл, тем быстрее загрузка. В зависимости от возможностей оптимизации времени компиляции, код на WebAssembly может передаваться и запускаться быстрее, чем на JavaScript!
Цель для компиляции: Возможность другим языкам, получить первоклассную двоичную поддержку через весь стек веб-платформы.
WebAssembly может увеличить скорость JavaScript в разы!
WebAssembly позволяет использовать больше языков в веб-разработке
WebAssembly добавляет вещи, которые большинство JS разработчиков не хотят видеть в JavaScript. Сама функциональность нужна, но вот в JavaScript ей места точно нет. Тем более, что мы можем получить все эти функции с помощью компиляции с других языков программирования.
Фактически, WebAssembly предоставляет нам альтернативный компилятор — созданный специально для этих целей.
Теперь, нам будет гораздо легче портировать код, который сильно зависит от, например, совместно используемых цепочек памяти. Я уверен, что написать компилятор для WebAssembly будет легче, чем написать компилятор для JavaScript, а все потому, что первый гарантирует лучший перенос функций языка в заданное абстрактное синтаксическое дерево.
То, что все старые языки программирования теперь без проблем могут быть использованы в Сети — это хорошо, однако главное не в этом.
WebAssembly является отличным основанием для разработчиков начать работу над новыми языками программирования.
WebAssembly или wasm – это низкоуровневый формат байт-кода для клиентских скриптов на стороне браузера.
При компиляции в WebAssembly вы делаете свою программу доступной для всех платформ, на которых поддерживается wasm, другими словами, для всех браузеров (и не только)
На практике WebAssembly реализуется разработчиками браузеров на основе существующего JavaScript-движка. По сути, он предназначен для замены JavaScript как целевого языка. Например, вместо компиляции TypeScript в JavaScript его разработчики теперь могут компилировать свой код в WebAssembly. Иными словами, это не новая виртуальная машина, это новый формат для той же самой виртуальной машины JavaScript, которая включена в каждый браузер. Это позволит использовать существующую инфраструктуру JavaScript без использования самого JavaScript.
Во-первых, новый формат WebAssembly обещает значительное увеличение производительности парсинга - тип бинарного формата, используемый в WebAssembly, может быть декодирован гораздо быстрее, чем JavaScript может быть пропарсен (эксперименты показывают более чем 20-кратную разницу). Это позволит использовать в вебе ПО, которое раньше было бы нецелесообразно разрабатывать, например: виртуальные машины, виртуальную реальность, распознавание изображений и многое другое.
Больше не придётся использовать JavaScript для веба, только потому что это единственное, что выполняется в браузере. JavaScript имеет плохую репутацию, хотя на самом деле это хороший язык в том, для чего он предназначен: позволяет быстро писать небольшие скрипты. Однако в настоящее время вы вынуждены использовать его для всего, что запускается в вебе, и это проблема для многих крупных проектов.
WebAssembly можно будет переносить на другие платформы. Это означает, что, если вы пишете программное обеспечение на языке, который компилируется в WebAssembly, вы сможете запустить его на .NET.
В отличие от других подходов для достижения нативного опыта, WebAssembly не требует встроенных плагинов, а запускается внутри веб-платформы. Это значит, что разработчики могут интегрировать библиотеки WebAssembly для сложных вычислительных процессов (сжатие данных, распознавание лиц) в существующие JavaScript-приложения для снижения нагрузки.
WebAssembly – это инициатива, направленная на создание безопасного, переносимого и быстрого для загрузки и исполнения формата кода, подходящего для Web. WebAssembly – это не язык программирования. Это – цель компиляции, у которой имеются спецификации текстового и бинарного форматов. Это означает, что другие низкоуровневые языки, такие, как C/C++, Rust, Swift, и так далее, можно скомпилировать в WebAssembly. WebAssembly даёт доступ к тем же API, что и браузерный JavaScript, органично встраивается в существующий стек технологий. Для компиляции кода в формат WebAssembly используется Emscripten.
Emscripten – это компилятор из байт-кода LLVM в JavaScript. То есть, с его помощью можно скомпилировать в JavaScript программы, написанные на C/C++ или на любых других языках, код на которых можно преобразовать в формат LLVM.
Веб-приложения, написанные на WebAssembly, могут запускаться на скорости, близкой к нативной, потому что весь код анализируется и компилируется преждевременно. Браузер сразу видит инструкции на машинном языке, которые он может сразу проверить, оптимизировать и запустить.
В каком-то смысле WebAssembly меняет работу веб-разработчика и фундаментальные свойства веба. С помощью WebAssembly и сопутствующего набора инструментов программы, написанные на C и C++, могут быть перемещены в веб для запуска с близкой к нативным приложениям производительностью. Мы ожидаем, что, с развитием WebAssembly, вы сможете поступать так же с языками создания мобильных приложений – то есть, Java, Swift и C#.
Время загрузки
Для того, чтобы запустить JavaScript-программу, браузеру сначала нужно загрузить все .js-файлы, которые хранятся и передаются по сети в виде обычного текста.
Wasm — это низкоуровневый язык, похожий на ассемблер. WebAssembly-программы загружаются браузером быстрее, так как через интернет нужно передать уже скомпилированные файлы в весьма компактном бинарном формате.
Выполнение
Сегодня wasm-программы выполняются лишь на 20% медленнее чем машинный код. Это, без сомнения, достойный результат. Ведь речь идёт о формате, который компилируется в особом окружении и запускается с применением множества ограничений, которые обеспечивают высокий уровень безопасности. Подобное замедление в сравнении с машинным кодом в этом свете выглядит не таким уж и большим. Кроме того, в будущем ожидается повышение производительности wasm-кода.
Ещё интереснее то, что wasm платформенно-независим. Его поддержка имеется во всех ведущих браузерных движках, которые демонстрируют примерно одинаковую производительность при выполнении wasm-кода.
Оптимизация кода
Если рассматривать wasm в конвейере JS-движка, то окажется, что wasm-код не нуждается в анализе и в нескольких проходах компиляции. Он уже оптимизирован и готов к использованию. Т.е. мы проскакиваем несколько трудозатратных стадий.
Wasm-код оптимизируется в ходе статической компиляции. При работе с ним не нужно разбирать текстовые файлы. Благодаря wasm в нашем распоряжении оказываются бинарные файлы, которые достаточно лишь преобразовать в машинный код. Все улучшения в этот код были внесены при компиляции, которая производится до того, как он попадает в браузер. Всё это делает выполнение wasm гораздо более эффективным, так как немало шагов по превращению текста программы в оптимизированный машинный код можно пропустить.
Ссылки:
- habr - Знакомство с WebAssembly
- habr - Как работает JS: особенности и сфера применения WebAssembly
- habr - WebAssembly: начало новой эры
- Почему WebAssembly значительно изменит веб
- Введение в WebAssembly: как устроена технология и почему она важна
- Википедия - WebAssembly
Web Worker API
Веб-воркеры — это потоки, принадлежащие браузеру, которые можно использовать для выполнения JS-кода без блокировки цикла событий. Введены в HTML 5.
Ещё раз: это часть браузерного API! Не является частью JS. Просто из JS можно взаимодействовать с этими возможностями браузера. Веб-воркеры не реализованы в Node.js — там есть концепция «кластеров» или «дочерних процессов», а это уже немного другое.
Позволяет частично снять ограничения, которые накладывает на JS концепция однопоточности.
Веб-воркеры позволяют разработчику размещать задачи, для выполнения которых требуются длительные и сложные вычисления, интенсивно задействующие процессор, в фоновых потоках, без блокировки пользовательского интерфейса, что позволяет приложениям оперативно реагировать на воздействия пользователя.
Веб-воркеры позволяют выполнять тяжёлые в вычислительном плане и длительные задачи без блокировки потока пользовательского интерфейса. На самом деле, при их использовании вычисления выполняются параллельно. Перед нами настоящая многопоточность. Они отлично подходят для того, чтобы выполнять тяжёлые вычислительные операции, не замедляя работу пользовательского интерфейса.
Web workers создаются в отдельных js-файлах. Выполняются в изолированных потоках в браузере.
Страница создаёт web-worker (используя специальный файл), браузер создаст новый поток, который асинхронно загрузит этот файл. Страница, создавшая веб-воркер, может взаимодействовать с ним. Например - обмениваться с ним данными, используя JSON-объект.
Когда воркер получает сообщение и понимает, чего от него хотят, он будет выполнять вычисления самостоятельно, не блокируя цикл событий. То, чем занимается воркер, выглядит как стандартная JS-функция. Когда вычисления завершены, их результаты передаются главной странице.
Ограничения Веб-воркерам, из-за их многопоточной сущности, доступен лишь ограниченный набор возможностей JavaScript - из них нельзя менять DOM, вызывать методы объектов window, document, parent и ещё много чего. Всё это значит, что веб-воркеры не могут манипулировать DOM (и, таким образом, не могут прямо влиять на пользовательский интерфейс). Поначалу может показаться, что это значительно усложняет использование веб-воркеров, однако со временем, узнав о том, как правильно использовать веб-воркеры, вы начнёте воспринимать их как отдельные «вычислительные машины», в то время как то, что относится к работе с пользовательским интерфейсом, будет выполняться в коде страницы. Воркеры будут выполнять тяжёлые вычисления, и после того, как работа будет завершена, отправлять результаты на страницу, вызывающую их, код которой уже внесёт необходимые изменения в пользовательский интерфейс.
Сценарии использования веб-воркеров
- Рендеринг трёхмерных сцен
- Шифрование
- Предварительная загрузка данных.
- Прогрессивные веб-приложения. Прежде всего - работа с хранилищем данных на стороне клиента (IndexedDB или похожее API).
- Проверка правописания.
Ссылки
Service Worker API
Сервис-воркеры — это разновидность веб-воркеров.
Это API позволяет приложениям поддерживать оффлайновые сценарии работы, даёт программисту контроль над тем, как приложение взаимодействует с внешними ресурсами. Включает механизмы перехвата запросов, возврата кэшированных данных и кэширования новых материалов.
Service worker это скрипт, который выполняется браузером в фоне, отдельно от веб-страницы и способен выполнять функции для которых не требуется взаимодействие со страницей или пользователем. На практике Service Worker API позволяет делать такую магическую вещь, как кеширование файлов онлайн веб-приложения на локальное устройство пользователя и затем работать полностью в оффлайне, если нужно. В будущем планируется добавить такие классные вещи как синхронизация кеша в фоне, то есть даже если пользователь не находится сейчас на вашем сайте, сервис-воркер все равно сможет запуститься и скачать обновления например. А также доступ к PushApi из фона опять же (то есть при получении обновления отправить вам пуш-уведомление).
Важные характеристики:
- Они выполняются в собственном глобальном контексте, ServiceWorkerGlobalScope.
- Они не привязаны к конкретной странице.
- Они не имеют доступа к DOM.
- Работают только по https
Жизненный цикл сервис-воркера не имеет ничего общего с жизненным циклом веб-страницы. Воркер регистрируется в API браузера и продолжает работать, даже когда вкалдака с сайтом закрыта.
Некоторые сценарии использования
- Push-уведомления. Они позволяют пользователям настраивать периодические уведомления, поступающие из веб-приложений.
- Фоновая синхронизация. Этот механизм даёт возможность откладывать выполнение неких действий до тех пор, пока у пользователя не будет стабильного соединения с интернетом. При использовании системы фоновой синхронизации разработчик может быть уверен в том, что если пользователь, скажем, хочет сохранить изменения документа, отредактированного в веб-приложении без доступа к сети, эти изменения не пропадут.
- Периодическая синхронизация (ожидаемая возможность). Это API, которое предоставляет функционал для управления периодической фоновой синхронизацией.
- Работа с геозонами (ожидаемая возможность). Данная возможность позволяет приложению предоставлять пользователю полезный функционал на базе его географического положения, и, в частности, основываясь на событиях попадания пользователя в заранее заданную область.
Ссылки
- habr - Как работает JS: сервис-воркеры
- MDN ru
- MDN en
- Service Workers: an Introduction (en)
- habr - Service Workers. Инструкция по применению
- habr -
- habr - Подводные камни Service Workers
- Введение в Service Worker'ы
Веб push-уведомления (Push API и Notifications API)
Технология позволяет пользователям подписываться на периодические уведомления веб-приложений, которые направлены на то, чтобы сообщать подписчикам о появлении новых материалов, или возникновении событий, которые могут представлять для них интерес.
Одним из механизмом, обеспечивающих работу push-уведомлений, являются сервис-воркеры.
Пользователь получит сообщение, даже есул у него не открыта вклдака с данным сайтом, достаточно просто запустить браузер.
Более того, пользователь получит сообщение, даже если оно произошло некоторое время назад, например вчера. Т.е. ты два дня не включал компьютер, запускаешь браузер - а тебе приходит сообщение "На любимом сайте вышла новая статья про котиков". Это достигается благодаря тому, что:
- используются промежуточные push-сервисы, например Google FСM. Т.е. новостной сайт отправляет сообщение не напрямую в мой браузер, а специальному сервису в Интернете. Сервис ставит сообщение в очередь и отправляет его нужному браузеру
- у каждого push-сообщения есть "время жизни" (специальный параметр, задаётся прис оздании сообщения). Пока это время не истекло - push-сервис будет пытаться отправить сообщение браузеру.
Ещё там есть ключи (открытые и закрытые) - чтоб сервис push-уведомлений знал, какой сервер приложения подписал пользователя, и был уверен что это — тот же самый сервер, который отправляет уведомления конкретному пользователю. Браузер передаёт applicationServerKey (открытый ключ) push-сервису в ходе оформления подписки. Это означает, что push-сервис сможет связать открытый ключ приложения с подпиской.
Разумеется, работает это всё только в сравнительно новых браузерах, которые поддерживают Push API и Notifications API. Ну, и сервер тоже надо настроить, чтоб он мог отсылать эти самые push-сообщения
HTTP/2 вводит технологию Server Push, которая позволяет серверу отправлять данные в клиентский кэш по собственной инициативе. Однако, при использовании этой технологии данные нельзя отправлять прямо в приложение. Данные, отправленные сервером по своей инициативе, обрабатывает браузер, при этом нет API, которые позволяют, например, уведомить приложение о поступлении данных с сервера и отреагировать на это событие.
Именно в подобной ситуации весьма полезной оказывается технология Server-Sent Events (SSE). SSE — это механизм, который позволяет серверу асинхронно отправлять данные клиенту после установления клиент-серверного соединения.
Ссылки
- Как работает JS: веб-воркеры и пять сценариев их использования
- habr - HTTP/2 Server Push не так прост, как я думал
MutationObserver API - отслеживание изменений в DOM
Web API, предоставляемое современными браузерами и предназначенное для обнаружения изменений в DOM. С помощью этого API можно наблюдать за добавлением или удалением узлов DOM, за изменением атрибутов элементов, или, например, за изменением текстов текстовых узлов.
Общая логика такая:
- в js коде объявляю, что хочу наблюдать за мутациями на этой странице. Объявляю о своём намерении я при помощи создания нового экземпляра объекта MutationObserver.
- там же указываю, что делать при появлении мутации. Например выводить сообщение в консоль, или запускать какую-то функцию
- после этого запускаю наблюдение, вывзывая у объекта MutationObserver метод observe. Здесь я указываю, за каким DOM-элементом я буду наблюдать. Все его потомки будут отслеживаться автоматически
- Метод disconnect останавливает наблюдение за изменениями.
- Метод takeRecords возвращает текущую очередь экземпляра MutationObserver, после чего очищает её. (пока не понял, что это значит)
Альтернативы MutationObserver
- Опрос (polling).
- Механизм MutationEvents.
- CSS-анимация.
Опрос
Самый простой и незамысловатый способ отслеживания изменений DOM — опрос. Используя метод setInterval можно запланировать периодическое выполнение функции, которая проверяет DOM на предмет изменений. Естественно, использование этого метода значительно снижает производительность веб-приложений.
MutationEvents API MutationEvents было представлено в 2000 году. Несмотря на то, что это API позволяет решать возлагаемые на него задачи, события мутации вызываются после каждого изменения DOM, что, опять же, приводит к проблемам с производительностью. Теперь API MutationEvents признано устаревшим и вскоре современные браузеры перестанут его поддерживать.
CSS-анимация Идея заключается в создании анимации, которая будет вызвана после того, как элемент будет добавлен в DOM. В момент запуска анимации будет вызвано событие animationstart. Если назначить обработчик для этого события, можно узнать точное время добавления нового элемента в DOM. Время выполнения анимации при этом должно быть настолько маленьким, чтобы она была практически незаметна для пользователя.
Делаем очень короткую анимацию и навешиваем её ко всем узлам-потомкам нужного DOM-элемента . Когда анимация заканчивается, вызывается соответствующее событие.
Разумеется, нужна JS-функция, которая будет играть роль обработчика событий.
По сути, навешиваем обработчик события на на родительский элемент, при его изменении вызывается сверх-быстрая (невидимая) анимация, а когда она закончилась - вызывается нужная нам js-функция... Костыль, короче.
Ссылки
WebSocket
Протокол для пересылки любых данных, на любой домен, безопасно и почти без лишнего сетевого трафика. Замена AJAX.
SSE API (Server-Sent events) - ещё более продвинутая технология для тех же целей.
Ссылки
SSE API (Server-Sent events)
Ещё один вариант API, который предоставляет браузер для COMET-взаимодействия. Позволяет серверу асинхронно отправлять данные клиенту после установления клиент-серверного соединения
Альтернатива WebSocket. Технология SSE основана на HTTP, т.е. нет необходимости вводить новый протокол (WebSocket) - а это важное преимущество (безопасность, простоат, настройка сервера)
Ссылки
WebRTC и механизмы P2P-коммуникаций
Real Time Communication - связь в режиме реального времени.
WebRTC, позволяет веб-приложениям создавать P2P-соединения (peer-to-peer, соединения типа «точка-точка», одноранговые, пиринговые сети).
Например - создание чата.
Ссылки
Shadow DOM
Технология для создания приложений, основанных на компонентах.
Ссылки
Web-компоненты, пользовательские элементы (Custom Elements)
Позволяет создавать свои собственные элементы HTML, наподобии «вшитых» в браузер HTML-тэгов типа <slelct>
или <>
. Компактные, модульные и подходящие для повторного использования. Объединяют вёрстку, оформление и некоторую логику.
Некоторые фреймворки (такие, как Angular или React) пытаются решить ту же проблему, которую решают пользовательские элементы, вводя собственные концепции. Пользовательские элементы можно сравнить с директивами Angular или с компонентами React. Однако пользовательские элементы — это стандартная возможность браузера, для работы с ними не нужно ничего, кроме обычных JavaScript, HTML и CSS. Конечно, это не позволяет говорить о том, что они являются заменой для обычных JS-фреймворков. Современные фреймворки дают нам гораздо большее, нежели лишь возможность имитировать поведение пользовательских элементов. В результате можно говорить о том, что и фреймворки, и пользовательские элементы — это технологии, которые можно использовать совместно для решения задач веб-разработки.
Ссылки
- Как работает JS: технология Shadow DOM и веб-компоненты
- Как работает JS: пользовательские элементы
- Learnjs - Веб-компоненты
- Learnjs - Пользовательские элементы (Custom Elements)
Системы хранения данных
Некоторые популярные системы хранения данных, доступные веб-разработчикам:
- API FileSystem
- API LocalStorage
- API SessionStorage
- API Cookie
- API Cache
- API IndexedDB
Ссылки