SPA на Vue.js, сборка Webpack.
- для бесплатных пользователей подключена рекламная сеть ВК: преролл, баннеры.
- для статистики прикручена Яндекс.Метрика
- для работы с ВК загружается их скрипт
xd_connection.js
Раньше грузил скрипты для работы перечисленного прямо с их сайтов просто через теги
<script>
. Всякие
ad.mail.ru/static/admanhtml/rbadman-html5.min.js
,
vk.com/js/api/adman_init.js
, сниппет Метрики,
xd_connection.js
Потом через RequireJS грузил их же, с fallback'ом на локальные пустышки-затычки.
Некоторые баннерорезки не пропускают то один, то другой, то все разом, включая необходимый для работы xd_connection.
Рассматриваю варианты:
- при сборке копировать скрипты себе на сервер и включать в общий бандл
- сначала объявлять объекты-методы-пустышки с используемыми названиями, чтобы не возникало вызовов несуществующих методов; затем пытаться загрузить настоящие скрипты с CDN. Необходимейший xd_connection сначала грузить локальную копию (возможно, устаревающую), потом пытаться загрузить оригинал.
- все вызовы к «ненадёжным» скриптам обернуть в
try-catch
– но их много, особенно к Метрике
❓ Какова best practice для внешних JS скриптов третьих сторон, которые могут и не загрузиться?
Приоритеты:
- загрузить оригинал с их CDN и выполнить;
- если нет, то подсунуть локальную копию;
- если никак, то понять и простить (а не вылетать с ошибками) – а обращений к той же Метрике довольно много по всему приложению.
Написал такую загрузку с Promise:
addScriptPromise(url) {
return new Promise((res, rej) => {
const newScript = document.createElement("script");
newScript.onerror = loadError => rej(loadError);
newScript.onload = res;
document.currentScript.parentNode.insertBefore(newScript, document.currentScript);
newScript.src = url;
});
}
// использую:
addScriptPromise('//yandex-cdn/metrika.js')
.then(undefined, err => addScriptPromise('/local-copies/metrika.chunk.js'))
.then(undefined, err => {
App.Metrika = { // к App.Metrika потом идут обращения для трекинга
addFileExtension : function(){},
clickmap : function(){},
enableAll : function(){},
extLink : function(){},
file : function(){},
hit : function(){},
replacePhones : function(){},
notBounce : function(){},
reachGoal : function(){},
trackLinks : function(){},
params : function(){},
})