Уменьшите влияние стороннего кода (zendesk)

введите здесь описание изображения

<script
  id="ze-snippet"
  src="https://static.zdassets.com/ekr/snippet.js?key=some_zendesk_key"
/>

Я пытаюсь оптимизировать производительность своего веб-сайта. Я столкнулся с большим влиянием стороннего кода на мою производительность, я думаю, что весь мой пакет имеет меньший размер, чем код Zendesk. Как я могу загрузить его, не влияя на основной поток? Должен ли я использовать теги async или defer? Или какой подход лучше для этого случая?


person Andrey Radkevich    schedule 20.10.2019    source источник
comment
IIRC, я пытался использовать асинхронные теги в своей разработке с чатом Zendesk, и это вызывает так много проблем. В основном я пришел к выводу, что этот скрипт никак не может не повлиять на вашу производительность, потому что он просто загружает так много других скриптов.   -  person Bergis    schedule 29.10.2019
comment
То же самое. Я загружаю этот скрипт в приложение для реагирования на Гэтсби. Забавно, что если запускать аудиты на zendesk.com, то размер 354 КБ и время блокировки 638 мс. Я чувствую, что аудиты слишком деликатны, поскольку реальное ощущение времени загрузки на самом деле хорошее.   -  person itdoesntwork    schedule 11.05.2020


Ответы (3)


Кажется, это проблема, которая мучает так много людей без четкого решения.

Что мне удалось сделать, так это уменьшить время блокировки, добавив эту конфигурацию.

window.zESettings = {
    webWidget: {
      chat: {
        connectOnPageLoad: false
      }
    }
  };

ссылка https://developer.zendesk.com/embeddables/docs/widget/settings#connectonpageload

ps Я провел тест производительности для своей службы поддержки zendesk «domain.zendesk.com», и результаты там были еще хуже.

введите здесь описание изображения

person itdoesntwork    schedule 11.05.2020

Недавно я столкнулся с этой проблемой и сделал этот хак, используя функцию загрузки скрипта zendesk только тогда, когда вы достигли определенной точки документа. Я знаю, что это немного грязно, но это работает:

<script defer type="text/javascript">
    (function($, win) {
        $.fn.inViewport = function(cb) {
            return this.each(function(i,el){
                function visPx(){
                    var H = $(this).height(),
                    r = el.getBoundingClientRect(), t=r.top, b=r.bottom;
                    return cb.call(el, Math.max(0, t>0? H-t : (b<H?b:H)));  
                }  visPx();
                $(win).on("resize scroll", visPx);
            });
        };
    }(jQuery, window));


$('#trigger_div').inViewport(function(px){
    if(px) {

    //zopim code

    }
});

person Mauricio Castillo    schedule 02.06.2020

Начиная с этой статьи https://www.newmediacampaigns.com/blog/maintaining-great-site-performanc-using-zendesk-web-widget Я реализовал решение, которое значительно сокращает время загрузки как минимум на 3 секунды (в Google Lighthouse).

Я создал фальшивую кнопку в HTML, которая будет загружать скрипт Zendesk и открывать виджет при нажатии. Он также загрузит элемент localStorage, который предотвратит это при последующих загрузках страницы.

⚠️ Внимание:

Код в значительной степени зависит от того, как в настоящее время реализован виджет (например, он ожидает, что на странице появятся элементы #launcher и #webWidget), поэтому он может сломаться, как только исходный код изменится, но, по крайней мере, мы получим улучшение в время загрузки, пока они не исправят это.

Вот самая важная часть кода:

HTML-кнопка

<button class="zendesk-button">
  <span class="left-icon">
    <!-- here you insert the icon -->
  </span>
  <span class="text">Chat</span>
</button>

JavaScript-код

// select the button
const zendeskButton = document.querySelector('.zendesk-button');

// add the script to the page
const loadZendeskScript = () => {
  const zenDeskScript = document.createElement("script");
  zenDeskScript.id = "ze-snippet";
  zenDeskScript.src = "https://static.zdassets.com/ekr/snippet.js?key=HERE_YOU_INSERT_YOUR_KEY";
  (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0] || document.getElementsByTagName('script')[0].parentNode).insertBefore(zenDeskScript, null);
};

// a poller that waits for a condition and executes a callback
const poller = (comparison, callback, timerStep = 250, maxTime = 5000) => {
  // why setTimeout instead of setInterval
  // https://stackoverflow.com/questions/8682622/using-setinterval-to-do-simplistic-continuous-polling
  let currTime = 0;
  const checkCondition = () => {
    // `comparison` is a function so the condition is always up-to-date
    if (comparison() === true) {
      callback();
    } else if (currTime <= maxTime) {
      currTime += timerStep;
      setTimeout(checkCondition, timerStep);
    }
  };
  checkCondition(); // calling the function
};

// load the script and execute a callback if provided
const loadZendeskChat = callback => {
  loadZendeskScript();
  if (callback) {
    callback();
  }
};

// this function opens the chat
const openZendeskChat = () => {
  poller(
    () => {
      // check that zendesk-related functions are available
      return typeof zE !== 'undefined';
    },
    () => {
      // open the widget
      zE('webWidget', 'open');
      poller(
        () => {
          // check that the elements exist and that the opacity is already set to "1"
          const launcher = document.querySelector('#launcher');
          const webWidget = document.querySelector('#webWidget');
          return launcher !== null && webWidget !== null && webWidget.style.opacity === '1';
        },
        () => {
          // hide the fake button
          zendeskButton.style.opacity = '0';
          // save in localStorage
          localStorage.setItem('zd_hasOpened', 'true');
        }
      );
    }
  );
};

// zendesk management
if (localStorage.getItem('zd_hasOpened')) {
  // load the zendesk widget if we find that it was opened
  loadZendeskChat();
} else {
  // show the fake button if it's the first time it shows
  zendeskButton.style.opacity = '1';
}
// This will run when the .zendesk-button element is clicked
zendeskButton.addEventListener('click', () => {
  // add a 'Loading' text to the button, as the widget will take some time to load (between 1 and 2 seconds on my laptop)
  zendeskButton.querySelector('.text').innerHTML = 'Loading';
  // load the zendesk widget
  // open the widget and hide the fake button
  loadZendeskChat(openZendeskChat);
});

Что касается стилей, я в значительной степени скопировал стиль исходного виджета, преобразовав ems в пиксели, но одну часть, которую я хотел бы выделить, — это стиль фокуса, потому что, по моему мнению, он помогает сообщить пользователю, что что-то происходит.

.zendesk-button:focus {
  outline: none;
  box-shadow: inset 0 0 0 0.21429rem rgb(255 255 255 / 40%) !important;
}
person Giorgio Tempesta    schedule 19.04.2021