Как найти причину постоянного обновления страницы в сафари?

Я пытаюсь выяснить проблему на клиентском веб-сайте, которая возникла в прошлом месяце или около того после последних обновлений как для iOS, так и для OSX. Когда пользователи Mac или iOS Safari направляются на любую страницу сайта по ссылке в EDM, они попадают в постоянный цикл обновления страницы. Также кажется, что происходит утечка памяти между обновлениями, поскольку Activity Monitor показывает, что процесс веб-контента Safari для сайта быстро увеличивает использование памяти (до 4 ГБ за две минуты или около того, прежде чем я его убил).

Проблема может быть воспроизведена только в браузере Safari. Chrome на Mac кажется нетронутым. Safari для Windows отображает проблему обновления, но, похоже, не начинает накапливать память, хотя использование ЦП процессом WebKit2WebProcess.ee постоянно находится на довольно высоком уровне, пока окно не будет закрыто. Я попытался удалить параметры utm_*, добавленные к ссылкам EDM, один за другим, пока не смог подтвердить, что проблема была вызвана только utm_source сам по себе, а затем обнаружил, что должен был ожидать этого, поскольку, по-видимому, это основной тег, который ищет GA. Более интересным является тот факт, что удаление GA не решило проблему — я закомментировал код, создающий тег script (что бы это ни стоило, используемый скрипт был не обычным www.google-analytics.com/ga.js, а скорее DFP с сайта stats.g.doubleclick.net/dc.js).

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

var googletag = googletag || {};
    googletag.cmd = googletag.cmd || [];
    (function() {
        var gads = document.createElement("script");
        gads.async = true;
        gads.type = "text/javascript";
        var useSSL = "https:" == document.location.protocol;
        gads.src = (useSSL ? "https:" : "http:") + "//www.googletagservices.com/tag/js/gpt.js";
        var node =document.getElementsByTagName("script")[0];
        node.parentNode.insertBefore(gads, node);
    })();

Поэтому я совершенно уверен, что GPT обнаруживает параметр utm_source и пытается сделать... что-то... что в Safari не удается... по какой-то причине... К сожалению, код GPT запутан, и я вряд ли найду свой проблема, просто читая это, поэтому я надеялся, что, возможно, есть какой-то способ получить стек вызовов в тот момент, когда страница обновляется в консоли разработчика Safari, о которой я не знаю, или какой-то другой метод отладки, о котором я не думал. Может быть, кто-то еще сталкивался с этой проблемой?

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

РЕДАКТИРОВАТЬ: я попытался раскомментировать тег скрипта GPT, а затем прокомментировать одно место на странице, в котором мы отправляем ему команду (с googletag.cmd.push()), на случай, если наше его использование вызывает проблемы (по сути, мы просто определяем, а затем публикуем 8 слотов в нажал cmd, затем включил рекламные службы). Комментирование этой команды не решило проблему, похоже, она вообще связана с загрузкой GPT.


person Chris O'Kelly    schedule 07.01.2015    source источник


Ответы (1)


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

Мы смогли исправить проблему, обновив библиотеку History.js, используемую на сайте, что само по себе я могу полностью принять как допустимый шаг устранения неполадок (таким образом, я попробовал его). Однако я совершенно не понимаю, как History.js и gpt.js будут когда-либо взаимодействовать друг с другом. в результате чего проблема возникает только в ситуации:

Использование Safari Использование более старой версии History.js с использованием GPT (что не должно влиять на History.js) Использование тега utm_source (который не должен влиять на History.js ИЛИ GPT)

но я счастлив быть сбитым с толку фиксированной проблемой, а не распространенной, поэтому я собираюсь оставить это в корзине «слишком сложно».

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

  • Я добавил тег скрипта вверху <head>, который зарегистрировал обработчик событий для предварительной загрузки, вызывающий оператор отладчика. Это дало бы мне время проверить временную шкалу и профайлер перед обновлением страницы.
  • Это показало мне, что непосредственно перед событием beforeunload было вызвано событие popstate (оглядываясь назад, я ругаю себя за то, что не перешел сразу к History.js, когда увидел popstate). Это событие установило таймер, который, как я заметил, срабатывал сразу, а затем каждые 1000 мс. Это было последнее, что срабатывало в событии popstate перед событием beforeunload, поэтому я решил, что это, скорее всего, вызывает обновление.
  • #P6# <блочная цитата>
    var origST = window.setTimeout;
    window.timers = [];
    window.setTimeout = function(f,t) {
      window.timers[origST(f,t)] = window.setTimeout.caller ? window.setTimeout.caller : 'Global Scope';
    }
    
  • И сделал то же самое для setInterval. Затем я мог перезагрузить страницу, получить идентификатор таймера, а затем в консоли проверить timers[the id] текст функции, которая установила таймер.

  • Затем мне нужно было найти во всех загруженных файлах сценариев определение рассматриваемой функции (это был запутанный и искаженный сценарий, а не то, что я мог легко догадаться). Я не уверен, что это действительно возможно в Safari, если это так, я мог не пойму как. К счастью, это не зависит от воспроизведения проблемы, поэтому я загрузил Chrome и использовал его инструменты разработчика для поиска файлов сценариев.
  • Найдя функцию в History.js, мы обновили ее и обнаружили, что проблема решена.
person Chris O'Kelly    schedule 07.01.2015