MFD平板JS动画触摸屏幕卡顿性能问题优化方案咨询
我目前正在为MFD平板开发JS动画,遇到了性能问题:我编写的小型动画脚本原本运行正常,但只要触摸屏幕就会开始卡顿,请问有什么可行方案可以优化该动画的性能?
性能优化方案
- 启用GPU硬件加速:给动画元素添加
will-change: transform属性,提示浏览器提前对该属性的变更做优化,也可添加transform: translateZ(0)强制开启合成层,让动画运行在独立的GPU线程,不受主线程触摸事件处理的阻塞。 - 替换
setInterval为requestAnimationFrame:setInterval的回调执行时机不与屏幕刷新同步,在主线程负载高(比如处理触摸事件)时容易出现丢帧卡顿,requestAnimationFrame会在每次屏幕刷新前执行回调,动画流畅度更高。 - 提前缓存DOM节点:原代码每帧都会重复执行
getElementsByClassName查询DOM,这类操作开销很大,提前把需要操作的元素列表缓存下来,避免重复DOM查询。 - 减少帧回调内的计算量:把可以复用的动画参数提前计算完成后再统一设置元素样式,降低每帧的执行耗时。
- 优先使用CSS原生动画:如果动画逻辑固定,可以替换为CSS
@keyframes实现,浏览器对CSS动画的优化程度远高于JS驱动的动画,在低性能嵌入式设备上性能优势更明显。
优化后完整代码
<html> <head> <title>JS SpeedTest</title> </head> <style> .row, .row1 { display: flex; } .row1 { margin-top: 20px; } .block { background: black; width: 30%; height: 50px; margin: 5px; /* 开启GPU加速优化 */ will-change: transform; transform: translateZ(0); } </style> <body> <div class="row"> <div class="block" style="background: red;"></div> <div class="block"></div> <div class="block"></div> <div class="block"></div> </div> <div class="row1"> <div class="block" style="background: red;"></div> <div class="block"></div> <div class="block"></div> <div class="block"></div> </div> </body> <script> (() => { function* step() { let back = false; let n = 0; while (true) { if (n >= 200) { back = true; } if (n <= -200) { back = false; } yield back ? n-- : n++ } } // 提前缓存所有DOM元素,避免每帧重复查询 const rows = Array.from(document.getElementsByClassName('row')); const row1List = Array.from(document.getElementsByClassName('row1')); rows.forEach(el => { const nextStep = step(); const blocks = Array.from(el.getElementsByClassName('block')); // 用requestAnimationFrame替代setInterval function animate() { blocks.forEach((b) => { b.style.transform = `translate(${nextStep.next().value}px, 0px)`; }); requestAnimationFrame(animate); } requestAnimationFrame(animate); }); row1List.forEach(el => { const nextStep = step(); const blocks = Array.from(el.getElementsByClassName('block')); function animate() { blocks.forEach((b) => { const val = nextStep.next().value; b.style.transform = `translate(${val}px, 0px) scale(${val / 100})`; }); requestAnimationFrame(animate); } requestAnimationFrame(animate); }); })(); </script> </html>
内容的提问来源于stack exchange,提问作者Alexander Onishchuk
相关产品推荐
相关产品推荐

