Браузерный SDK и встраиваемые виджеты - как это устроено

Партнёр ставит на свой сайт один скрипт - дальше всё делает браузерный SDK. В Gravity Sales я спроектировал и собрал его с нуля, и это оказался совсем не тот фронтенд, к которому привыкаешь в своём приложении.

Как устроено. SDK собирает поведение посетителя и отправляет на бэкенд, там ML-модель решает, какое персональное предложение показать. Решение возвращается по WebSocket, SDK ставит его в очередь показа и подгружает с CDN бандл нужного виджета. Виджеты - отдельная библиотека на Preact, каждый собран в самостоятельный бандл, так что на страницу партнёра приезжает только то, что реально нужно показать.

Что в этой задаче устроено иначе.

Вес. Скрипт грузится на чужом сайте, и за его размер ты отвечаешь перед чужим бизнесом. Отсюда Preact вместо React, ленивая подгрузка бандлов и свои компоненты вместо готового UI-кита - в бандл попадает только то, что используется.

Изоляция. Виджет живёт в чужом DOM и чужих стилях, поэтому рендерим в Shadow DOM. Стили сайта не текут внутрь, наши не текут наружу. Готовые UI-библиотеки с этим дружат плохо - оверлеи уходят в портал за пределы теневого дерева и остаются без стилей. Ещё один довод в пользу своих компонентов. Инлайн-блоки при этом встраиваются прямо в страницу партнёра, код самой страницы не трогаем.

Очередь. Предложений может прийти несколько, а посетитель один. Показ выстраивается в очередь, иначе виджеты налезают друг на друга.

Связь. Соединение может не подняться или отвалиться в любой момент, поэтому в транспорте реконнект с backoff и HTTP-фолбэк.

Самое непривычное - код выполняется в среде, которую ты не контролируешь и не можешь починить. Отладка идёт не в твоём приложении, а на сайте, где своя аналитика, свои стили и свой чужой JS.