There is a canvas that draws a video . I want to change the source of the video and while doing this just by changing the src attribute. I don’t understand what happens with the canvas in this case, but every time the source changes (or load from the video), the performance drops and the CPU load increases. Obviously, doing something wrong.
Actually, the question is why this is happening and how to correctly change the source of the video in order to avoid possible performance problems?
PS In the snippet, the canvas is small, it starts to lag after 30+ replacements, in the draft, the full screen and two pieces of them, there it is noticeable after 6-8 replacements.
videos = new Array(); videos[0] = { source: "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerBlazes.mp4" }; videos[1] = { source: "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerEscapes.mp4" }; videos[2] = { source: "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerFun.mp4" }; var setSource = function(num) { $('video').attr('src', videos[num].source); } var loadVideo = function() { var i = 0; var loadTimer = setInterval(function() { i += 1; $('video').get(0).load(); if (i == 41) { clearInterval(loadTimer); }; }, 100); } const canvas = document.querySelector('canvas'); const ctx = canvas.getContext("2d"); const video = document.querySelector('video'); video.addEventListener('play', () => { function step() { ctx.drawImage(video, 0, 0, canvas.width, canvas.height); requestAnimationFrame(step); } requestAnimationFrame(step); }) let frameCount = function _fc(timeStart) { let now = performance.now(); let duration = now - timeStart; if (duration < 1000) { _fc.counter++; } else { _fc.fps = _fc.counter; _fc.counter = 0; timeStart = now; $("#fps-counter").html(_fc.fps); if (_fc.fps >= 55) { $("#fps-counter").css("color", "green"); } else if (_fc.fps >= 30) { $("#fps-counter").css("color", "orange"); } else if (_fc.fps < 30) { $("#fps-counter").css("color", "red"); } } requestAnimationFrame(() => frameCount(timeStart)); }; frameCount.counter = 0; frameCount.fps = 0; frameCount(performance.now()); canvas, video { position: absolute; right: 0; margin: auto; } canvas { top: 0; width: 300px; border: 1px solid red; } video { bottom: 0; width: 100px; border: 1px solid blue; } <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <p>Set video source</p> <button onclick="setSource(0)">1</button> <button onclick="setSource(1)">2</button> <button onclick="setSource(2)">3</button> <p>video.load() x40</p> <button onclick="loadVideo()">load()</button> <p> fps: <span id='fps-counter'>0</span></p> <video autoplay muted loop src='https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerBlazes.mp4'></video> <canvas></canvas>