Плохая производительность цикла видео - PullRequest
0 голосов
/ 19 сентября 2018

Я работаю над видео слайдером, в котором следующее видео начинается незадолго до предыдущего - в цикле.В то же время мне нужно обновить индикатор выполнения каждого из них.Код ниже работает, но Chrome горит мой MacBook.Я делаю что-то не так?Как я могу улучшить производительность?Есть бесплатные слайды, и у видео нет атрибута loop = "true".Я просто запускаю слайдер, проигрывая первое видео.

videos.on('timeupdate', function () {
    var progress = this.currentTime / this.duration * 100 + '%';
    $(this).closest('.slide').find('.js-video-progress').width(progress);
    if ((this.currentTime * 1000 + 1000) > this.duration * 1000) {
        if ($(this).closest('.slide').next('.slide').length) {
            $(this).closest('.slide').next('.slide').addClass('is-swiped').find('video')[0].play();
        } else {
            $('.slide').eq(0).addClass('is-swiped').find('video')[0].play();
        }
    }
});

1 Ответ

0 голосов
/ 19 сентября 2018

timeupdate может срабатывать с высокой скоростью (возможно, даже быстрее, чем частота обновления экрана), поэтому все, что вы там делаете, должно быть максимально легким.

Методы jQuery делают много вещей каждыйвремя, когда вы вызываете их, и всегда возвращаете новые объекты, которые скоро загрязнят всю вашу память, заставляя GarbageCollector появляться каждый раз.Так что не вызывайте дважды одну и ту же функцию и вместо этого сохраняйте результат в переменной.

Вот несколько лучший подход для хранения каждого повторно используемого объекта в самом обработчике:

videos.on('timeupdate', function () {
    var time = this.currentTime, // it's a getter function, store
    var dur = this.duration;
    var progress = time / duration * 100 + '%';
    var $this = $(this); // store
    var $slide = $this.closest('.slide');
    var $progress = $slide.find('.js-video-progress');
    var $slide_next;
    $progress.width(progress);
    if ((time * 1000 + 1000) > dur * 1000) {
        $slide_next = $slide.next('.slide');
        if ($slide_next.length) {
           $slide_next
              .addClass('is-swiped')
              .find('video')[0]
              .play();
        } else { 
            $slide.eq(0)
              .addClass('is-swiped')
              .find('video')[0]
              .play();
        }
    }
});

Но личноЯ думаю, что даже пошел бы глубже, рискуя быть многословным, и сохранить все необходимые объекты в статическом объекте, который я бы просто нашел в обработчиках:

videos.each(function attach_data() {
  var $this = $(this);
  var $slide = $this.closest('.slide');
  var $progress = $slide.find('.js-video-progress');
  var $video = $slide.eq(0).find('video');
  var $slide_next = $slide.next('.slide');
  var $next_video = $slide_next.find('video');
  $this.data('$tree', {
    slide: $slide.eq(0),
    progress: $progress,
    video: $video,
    slide_next: $slide_next,
    video_next: $video_next
  })
})
.on('timeupdate', function () {
    var time = this.currentTime;
    var dur = this.duration;
    var progress = time / duration * 100 + '%';
    // retrieve our stored object
    var $tree = $(this).data('$tree');
    $tree.progress.width(progress);
    if ((time * 1000 + 1000) > dur * 1000) {
        if ($tree.slide_next.length) {
           $tree.slide_next.addClass('is-swiped');
           $tree.next_video[0].play(); // you may want to add a check the <video> really exists
        } else { 
           $tree.slide.addClass('is-swiped');
           $tree.video[0].play();
        }
    }
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...