2014-09-12 3 views
2

У меня есть проблема с jquery javascript, особенно связанная с Firefox.Производительность Firefox, javascript и iFrame с JQuery

У нас есть набор вложений vimeo, и идентификаторы втягиваются через json-файл. На каждом клике отображается новое видео. После воспроизведения видео контейнер удаляется, а облако заголовка возвращается. После определенного количества раундов производительность Firefox серьезно ухудшается, и вы получаете ошибку «невосприимчивого скрипта». Этого не происходит в других браузерах. Более того, профилировщик FF, похоже, не указывает на первопричину замедления.

Я считаю, что это вызвано плохим качеством iframe и тем, как FF обрабатывает iframe, но я не совсем уверен в этом. Ничто другое, что я делаю, не является чем-то большим, в основном, просто функциями jquery, такими как empty(), remove(), prepend() и т. Д.

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

Вот ссылка на сайт и конкретная часть упоминается: http://www.wongdoody.com/mangles

Это не весь код, но это та часть, которая вызывается каждый клик.

Кроме того, я попытался просто заменить src = "" в iframe, но производительность все еще ухудшается.

EDIT: Я могу подтвердить, что это не утечка памяти, я о: память и с аддонами отключены в безопасном режиме я получаю приличное использование памяти:

359.11 MB ── частные 361,25 MB ── резидент 725.54 МБ ── vsize

Что-то в vimeo embed замедляет механизм javascript, но это не утечка памяти. Кроме того, это подтверждается тем фактом, что я могу решить проблему, просто обновив страницу. Если бы это была утечка памяти, мне пришлось бы полностью закрыть FF.

function getIframeContent(vid) { 
    mangle_vid_id = vid; 
    return '<div class="vimeoContainerflex"><div class="vimeoContainer"><iframe class="vimeo" style="z-index:1;" width="100%" height="100%" frameborder="0" allowfullscreen="" mozallowfullscreen=""     webkitallowfullscreen="" src="//player.vimeo.com/video/' + mangle_vid_id + '?api=1&title=0&color=89ff18&amp;byline=0&amp;portrait=0&amp;autoplay=1"></iframe></div></div>'; 
} 

function show_titles() { 
    $('.mangle-btn').hide(); 
    $('.vimeoContainerflex').remove(); 
    $('span.mangle').hide(); 
    if ($('#mangle-titles').length < 1) { 
     $('#wongdoody').prepend(wd_titles_content); 
    } 

    $('#arrow').show(); 

    if (clicks > 12) { 
     location.reload(); 
    } 

    $('#mangle-titles span').click(function() { 
     clicks = clicks + 1; 
     $('#mangle-wrapper').remove(); 
     var vidID = $(this).attr('data-id'); 
     if ($('.vimeoContainer').length < 1) { 
      if (vidID == "home") { 
       $('#wongdoody').prepend(getIframeContent(getRandom())); 
      } else { 
       $('#wongdoody').prepend(getIframeContent(vidID)); 
      } 
     } 
     $('#arrow').hide(); 
     vimeoAPI(); 
    }); 

    $('#mangle-titles span').not('noscale').each(function() { 
     var _this = $(this); 
     var classname = _this.attr('class'); 
     var scaleNum = classname.substr(classname.length - 2); 
     var upscale = parseInt(scaleNum); 
     var addition = upscale + 5; 
     var string = addition.toString(); 

     _this.hover(
      function() { 
       _this.addClass('scale' + string); 
      }, 
      function() { 
       _this.removeClass('scale' + string); 
      } 
     ); 
    }); 
} 

function vimeoAPI() { 
    var player = $('iframe'); 
    var url = window.location.protocol + player.attr('src').split('?')[0]; 
    var status = $('.status'); 

    // Listen for messages from the player 
    if (window.addEventListener) { 
     window.addEventListener('message', onMessageReceived, false); 
    } else { 
     window.attachEvent('onmessage', onMessageReceived, false); 
    } 

    // Handle messages received from the player 
    function onMessageReceived(e) { 
     var data = JSON.parse(e.data); 

     switch (data.event) { 
      case 'ready': 
       onReady(); 
       break; 
      case 'finish': 
       onFinish(); 
       break; 
     } 
    } 

    // Helper function for sending a message to the player 
    function post(action, value) { 
     var data = { 
      method: action 
     }; 

     if (value) { 
      data.value = value; 
     } 

     var message = JSON.stringify(data); 
     if (player[0].contentWindow != null) player[0].contentWindow.postMessage(data, url); 
    } 

    function onReady() { 
     post('addEventListener', 'finish'); 
    } 

    function onFinish() { 
     setTimeout(show_titles, 500); 
    } 
} 
+0

Это происходит, когда вы отключите firebug тоже – charlietfl

+1

Да, это происходит в большинстве версий firefox, как на ОС, так и на окнах. Я думаю, что это связано с механизмом javascript FF и сборкой мусора. – jorblume

+1

Я думаю, что ваше предположение действительно также. Вероятно, FF вызывает утечку памяти. Именно по этой причине я перешел на Chrome много лун назад - это не так плохо: p – below9k

ответ

2

Отчасти проблема заключается в том, что вы продолжаете добавлять все больше обработчиков кликов к промежуткам. После завершения каждого фильма функция onFinish снова вызывает show_titles, которая прикрепляет новый (= дополнительный) обработчик кликов к прогонам $('#mangle-titles span'). jQuery делает не удалить ранее прикрепленные обработчики.

Попробуйте разделить функцию show_titles на две части. init_titles должен вызываться только один раз:

function init_titles() { 
    if ($('#mangle-titles').length < 1) { 
     $('#wongdoody').prepend(wd_titles_content); 
    } 

    $('#mangle-titles span').click(function() { 
     $('#mangle-wrapper').remove(); 
     var vidID = $(this).attr('data-id'); 
     if ($('.vimeoContainer').length < 1) { 
      if (vidID == "home") { 
       $('#wongdoody').prepend(getIframeContent(getRandom())); 
      } else { 
       $('#wongdoody').prepend(getIframeContent(vidID)); 
      } 
     } 
     $('#arrow').hide(); 
     vimeoAPI(); 
    }); 

    $('#mangle-titles span').not('noscale').each(function() { 
     var _this = $(this); 
     var classname = _this.attr('class'); 
     var scaleNum = classname.substr(classname.length - 2); 
     var upscale = parseInt(scaleNum); 
     var addition = upscale + 5; 
     var string = addition.toString(); 

     _this.hover(
      function() { 
       _this.addClass('scale' + string); 
      }, 
      function() { 
       _this.removeClass('scale' + string); 
      } 
     ); 
    }); 
} 

function show_titles() { 
    $('.mangle-btn').hide(); 
    $('.vimeoContainerflex').remove(); 
    $('span.mangle').hide(); 
    $('#arrow').show(); 
} 
+0

Это ответ, когда я изменил все на bind() и поместил его в функцию init, проблемы с производительностью исчезли. Спасибо за вашу помощь, очень глупая ошибка. – jorblume

+0

Рад, что я могу помочь – mhu

1

Я бы рекомендовал использовать повторное использование iframe вместо очистки и повторного добавления. В противном случае, я думаю, вам может быть не повезло. Ваш метод закрытия iFrame в порядке; ваш браузер, в котором он работает, - нет.

+0

К сожалению, я уже пробовал это решение, и оно не решило проблему. На данный момент, после определенного количества кликов, он просто обновляет страницу, которая, кажется, решает проблему. Но все же, очень неудачно ... – jorblume

1

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

Вы можете легко проверить это, добавив console.log («Огонь!»), Например, в начале onMessageReceived.Вы увидите, что эта функция запускается с ужасным количеством раз после того, как пользователь выполнил несколько кликов по видео.

Это, безусловно, влияет на производительность.

Надеюсь, это поможет.

Смежные вопросы