Ленивая загрузка форм Marketo в Wordpress (собственный Javascript)

Последний квартал в MyOutDesk был жестоким циклом изучения всех тонкостей Wordpress, Javascript и влияния маркетинговых инструментов на Google PageSpeed ​​Insights. Одной из конкретных проблем был тот факт, что загрузка Marketo была дорогой и блокировала выполнение скрипта. Чтобы бороться с этим, я разработал простой способ обработки ленивой загрузки Marketo Forms (Forms2) без необходимости добавлять слишком много накладных расходов. Это действительно полезно для скорости страницы, когда форма находится ниже сгиба.

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

Соображения

Было несколько ограничений, при которых мне пришлось сделать этот скрипт:

  • Используйте нативный JS
  • Легко вставляется в Wordpress
  • Форма может располагаться в любом месте страницы

Предварительное условие: динамическая вставка скриптов

Нам нужно добавить динамический вставщик скриптов, который может использовать источник и добавлять его в заголовок тела, чтобы мы могли использовать внешний JS. Код довольно прост в использовании

function dynamicScriptInserter(scriptSource, args) 
{
    let script = document.createElement('script');
    script.src = scriptSource
    Object.keys(args).forEach(key => {
        script.setAttribute(key, args[key]);
    })
    document.getElementsByTagName('head')[0].appendChild(script)
}

Этот код будет использоваться так:

dynamicScriptInserter('https://your_marketo_url.com/js/forms2/js/forms2.min.js', {});

Это также можно использовать для самых разных сценариев, а не только для Marketo.

Ленивый загрузчик Marketo

Перейдите к нижней части, чтобы получить основную ссылку. Я расскажу, как это работает здесь.

Начальная фаза

Первым шагом, который мне нужно было сделать, было найти сами формы при загрузке, что было довольно легко благодаря тому, что Marketo предоставил вам встроенный код из коробки. Чтобы этот код работал, единственное, что вам нужно скопировать и вставить в строку, это этот фрагмент.

<form id=”mktoForm_[ID HERE]”/>

Все формы будут загружены, и мы отправим запрос на поиск идентификатора, содержащего mktoForm_. Для каждой формы мы будем вызывать функцию getBoundingClientRect(), чтобы проверить, находится ли форма в окне просмотра клиента, а также извлечь идентификатор формы.

let coords = forms[i].getBoundingClientRect();                    let formId = forms[i].getAttribute('id').replace('mktoForm_', '');                     if (this.isInView(coords)) {
    // Load forms2 and marketo form
}

Тогда произойдет следующее

  • Если форма находится в поле зрения, немедленно введите Forms2, а затем загрузите форму.
  • В противном случае поставьте Forms2 в очередь для внедрения и загрузите форму, когда произойдет первое событие прокрутки пользователя.

Загрузка форм2

Forms2 немного шатается, когда дело доходит до загрузки, потому что это не код, который мы контролируем. Если форма находится выше сгиба, я немедленно ввожу Forms2 и вызываю loadForm() с идентификатором. В противном случае мы просто ждали, пока событие прокрутки вызовет loadMarketoOnScroll. Поскольку функция инициализации уже нашла все формы и поставила их в очередь, нам просто нужно перебрать формы и вызвать функцию загрузки с нашим извлеченным идентификатором формы.

примечание: если form2 уже присутствует, мы предполагаем, что на странице есть устаревший код marketo, и ничего не делаем.

Во-первых, объект отслеживает, загрузили ли мы Forms2 или нет, через его логическое значение marketoInjected:

if (this.marketoInjected === false) {
    this.injectForms2();
}
// other code here
injectForms2: function() {
    dynamicScriptInserter('your forms2.min.js goes here', {});
    this.marketoInjected = true;
},

Тогда эта глупая функция является секретным соусом, скрепляющим все это вместе:

waitForForms2: function() {
    return new Promise((resolve, reject) => {
        this.waitInterval = setInterval(() => {
            if (MktoForms2 !== undefined) {
                clearInterval(this.waitInterval);
                resolve();
            }
        }, 500);
    })
}

Вы можете либо ждать здесь, либо использовать .then(), на ваше усмотрение. Все, что он делает, это ждет, пока Forms2 будет готов на странице, чтобы мы могли вызвать его для загрузки нашей формы. Я просто решил дождаться этого обещания, а затем выполнить вызов MktoForms2.loadForm:

loadForm: async function(id) {
    await this.waitForForms2();
    MktoForms2.loadForm("MARKETO_URL_HERE", "COMPANY_ID_HERE", id);
},

Исходный код и использование

Источник здесь!

Вставьте свою форму, не включая Forms2 или JS, только часть HTML:

<form id=”mktoForm_[ID HERE]”/>

Инициализируйте загрузчик, проверьте, можно ли продолжить, вызовите init(), а затем прикрепите обработчик прокрутки:

var marketoFormLazyLoader = new MarketoLazyLoader();
if(marketoFormLazyLoader.readyToHook) {
    marketoFormLazyLoader.init();
    var marketoLazyScrollHandler = function() {
        marketoFormLazyLoader.loadMarketoOnScroll();
        // don't forget to remove the scroll handler
        window.removeEventListener('scroll', marketoLazyScrollHandler);
    }
    window.addEventListener('scroll', marketoLazyScrollHandler);
}

Настройте его и добавьте в свои дочерние темы js, поставьте в очередь, и все будет готово.

add_action('wp_enqueue_scripts', 'register_marketo');
function register_marketo() {
    wp_enqueue_script('marketo-lazy-loader', get_stylesheet_directory_uri() .'/js/marketo-lazy-loader.min.js', [], 2, true);
}

Или просто бросьте его внизу с помощью вставки сценариев верхнего и нижнего колонтитула. Вам решать!