面试题答案
一键面试性能优化方法
- 使用
requestAnimationFrame
:- 它会在浏览器下一次重绘之前调用指定的回调函数,与浏览器的刷新频率保持同步,避免不必要的计算和渲染。例如:
function animate() {
// 动画逻辑
requestAnimationFrame(animate);
}
animate();
- 硬件加速:
- 通过 CSS 的
transform
和opacity
属性触发硬件加速,因为这两个属性的改变不会引起重排和重绘。例如,将元素移动可以使用transform: translateX(50px);
而不是改变left
属性。
- 通过 CSS 的
- 减少重排和重绘:
- 批量修改样式,而不是一次修改一个样式。例如:
// 不好的做法
element.style.left = '10px';
element.style.top = '20px';
element.style.width = '30px';
// 好的做法
const newStyles = {
left: '10px',
top: '20px',
width: '30px'
};
const styleString = Object.entries(newStyles).map(([key, value]) => `${key}:${value}`).join(';');
element.style.cssText = styleString;
- 优化动画时间函数:
- 选择合适的
easing
函数(缓动函数),避免过于复杂的计算。例如使用cubic - bezier
曲线来创建平滑的动画效果,而不是自定义复杂的数学函数。像transition - timing - function: cubic - bezier(0.1, 0.7, 1.0, 0.1);
- 选择合适的
- 减少动画元素数量:
- 如果可能,合并一些动画元素,或者将动画效果应用到父元素上,而不是每个子元素都有独立动画。
通过改变 CSS 属性和 JavaScript 控制逻辑提升动画性能示例
假设要实现一个多元素联动的水平移动动画。
- CSS 属性改变:
- 原来使用
left
属性移动元素:
- 原来使用
.element {
position: relative;
left: 0px;
transition: left 1s ease - in - out;
}
- 改为使用
transform
属性:
.element {
position: relative;
transform: translateX(0px);
transition: transform 1s ease - in - out;
}
- JavaScript 控制逻辑改变:
- 原来直接在
setInterval
中改变left
属性:
- 原来直接在
let leftValue = 0;
const intervalId = setInterval(() => {
leftValue += 10;
document.querySelectorAll('.element').forEach((element) => {
element.style.left = leftValue + 'px';
});
}, 100);
- 改为使用
requestAnimationFrame
并改变transform
属性:
let translateXValue = 0;
function moveElements() {
translateXValue += 10;
document.querySelectorAll('.element').forEach((element) => {
element.style.transform = `translateX(${translateXValue}px)`;
});
requestAnimationFrame(moveElements);
}
moveElements();
这样通过改变 CSS 属性为 transform
触发硬件加速,以及使用 requestAnimationFrame
优化 JavaScript 控制逻辑,提升了动画性能。