виджет
Опыт travelpayouts
Виджеты
Виджеты
• Проблемы виджетов;
• Тонкости разработки;
• Пуленепробиваемый код.
Travelpayouts
• 5 лет на рынке (до этого были в составе Aviasales);
• Более 100 000 аффилиатов;
• Более 600 млн ₽ выплат;
• 18 634 работающие конфигурации виджета
поисковой формы;
• Ещё 8 виджетов и вайтлейблы.
Виджеты
• Легковесные;
• Работающие.
Отличие от других проектов
• Размер;
• Агрессивная среда размещения;
• Локализации + кастомизируемость;
• Время на разработку (но это не точно).
Любой разработчик сможет
за пару дней
сделать виджет на Реакте.
Очень простой виджет
Какие были проблемы
• 200кб дистрибутив;
• Неизолированные стили;
• Непродуманный код для вставки.
Что такое 200кб
для виджета?
Средний размер по данным HTTPArchive http://bit.ly/2hmIF3r:
• 3300кб страница;
• 450кб JS gzipped (25 js-файлов);
• 10мбит средняя скорость интернета в России;
• 6250кб за 5 секунд.
Introducing Mewtwo
Чего мы смогли добиться
• 45кб js + 10кб CSS + 7кб Logo = 55кб + 7кб;
• Эффективность, вымученная а/б тестами;
• Почти не было жалоб от партнёров после деплоя
на 100%.
Как уместить виджет в 50kb
• NPM as a framework:
- Babel-plugin-lodash / submodules / lodash-es;
- date-fns / js-joda вместо moment.js ?.
• Monkberry.js for templates;
• Постоянный контроль итогового размера дистрибутива:
- Size Limit;
- Webpack bundle analyzer;
- jsize.
Попытка загрузить виджет
быстрее основного контента
• Не забывать про async;
• Разделение загрузчика и контента;
• Монолитный виджет с закешированным конфигом.
Конфликты CSS и JS
Проблемы с CSS
• Коллизия имён классов;
• Глобальное переопределение свойств;
• Более сильные селекторы.
Изолирование стилей
• All initial
01. #mydiv {
02. all: initial; /* blocking
03. inheritance for all properties */
04. }
05. #mydiv * {
06. all: unset; /* allowing inheritance
07. within #mydiv */
08. }
09. #mydiv::before,
10. #mydiv::after,
11. #mydiv *::before,
12. #mydiv *::after { Не работает в IE и Opera Mini
13. all: unset;
14. }
Изолирование стилей
• All initial (не работает в IE и Opera Mini);
• Iframe (влияет на скорость загрузки).
Изолирование стилей
• All initial (не работает в IE и Opera Mini);
• Iframe (влияет на скорость загрузки);
• Shadow DOM (работает в Chrome, Opera и Android).
Изолирование стилей
• All initial (не работает в IE и Opera Mini);
• Iframe (влияет на скорость загрузки);
• Shadow DOM (работает в Chrome, Opera и Android);
• CSS Modules.
Изолирование стилей
• All initial (не работает в IE и Opera Mini);
• Iframe (влияет на скорость загрузки);
• Shadow DOM (работает в Chrome, Opera и Android);
• CSS Modules;
• CSS-in-JS styled CSS.
Изолирование стилей
• All initial (не работает в IE и Opera Mini);
• Iframe (влияет на скорость загрузки);
• Shadow DOM (работает в Chrome, Opera и Android);
• CSS Modules;
• CSS-in-JS styled CSS;
• Наш собственный вариант.
Шаг 1
Закрываем стандартные свойства от внешнего мира.
Mewtwo
Chansey Weedle
Что мы сделали
• Wrapper CSS reset; 01.
02.
.mewtwo-widget .mewtwo-flights-origin {
position: relative!important;
09. }
SVG и логотипы
• Кастомизируемые цвета в SVG:
- Определять их в monk-шаблоне;
- CSSX в js.
• SVG с логотипами в отдельном файле 7kb.
Код для вставки
Любое усложнение кода приведёт к дополнительным
тикетам в поддержку.
Как можно вставить виджет
• script + div#id (div.class, div[role], etc).
01. <div id="widget"></div>
• script.
Как передать параметры
Data-attributes
01. <script src="//www.travelpayouts.com/widget" data-width="100%"
02. width=100%&border_radius=2&show_logo=true&show_hotels=true"
03. async></script>
Как передать параметры
Inline js params
01. <script>
04. border_radius: 2,
06. show_hotels:true
07. }
08. </script>
03. window.TP_FORM_SETTINGS["1d8b372abc912411e4f5d247d117990d"] = {
08. };
09. </script>