Chrome浏览器在滚动时,HTML画布会卡顿
这里的代码基本上展示自上一次绘制帧以来经过了多久,当dt > 20ms时就会变成红色。
通常我的电脑可以让requestAnimationFrame以 60fps(约16ms)运行,但当我滚动时,它会闪出红色并且卡顿很严重。
<!DOCTYPE html>
<html>
<style>
body, html {
overflow: hidden;
overscroll-behavior: none;
}
</style>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no, maximum-scale=1, minimum-scale=1, viewport-fit=cover">
</head>
<body style="padding:0;margin:0;background-color: #151515;pointer-events: none">
<script>
class LCanvas{
constructor(){
this.canvas = document.createElement("canvas")
this.ctx = this.canvas.getContext("2d")
this.canvas.style.position = "fixed"
this.canvas.style.top = "0px"
this.canvas.style.left = "0px"
this.canvas.style.pointerEvents = "none"
document.body.appendChild(this.canvas)
return(this)
}
fitScreenSize(){
this.canvas.width = window.innerWidth
this.canvas.height = window.innerHeight
}
clear(){
this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height)
}
}
var can = new LCanvas()
can.clear()
can.fitScreenSize()
var lastTime = 0
function mainLoop(){
requestAnimationFrame(mainLoop)
let now = performance.now()
let dt = now-lastTime
lastTime = now
can.clear()
can.ctx.font = "40px arial"
can.ctx.fillStyle = dt>20?"red":"pink"
can.ctx.fillText(dt,100,100)
can.ctx.fillRect(400,100,dt*50,100)
}
requestAnimationFrame(mainLoop,true)
</script>
</body>
</html>
在这段极短的视频中,当我的光标放在页面底部附近时向下滚动
https://www.youtube.com/watch?v=da2YuPcyNvc
滚动时,它清楚地会闪出红色,并把帧率从60fps变到90fps。其实并不需要滚得这么快,滚轮一个小小的刻度就足以出现红色条。
这里每一帧的绘制性能其实并不是瓶颈。我可以绘制成千上万的东西,它本应一直流畅,直到我触碰滚轮,才会卡顿几帧。
如果改用setInterval而不是requestAnimationFrame,问题就不会再出现。
我在Firefox上也试过,也没有这个问题。Chrome有没有解决办法?
解决方案
添加这一行就能修复滚动时的卡顿
document.addEventListener("wheel",(e)=>{e.preventDefault()},{passive: false})
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。