Chrome中文本动画流畅,Safari及iOS设备中卡顿问题求助
文本动画在Safari/iOS设备卡顿的解决方案
问题背景
开发的网站中,h1元素的CSS关键帧动画在Chrome浏览器表现流畅,但在Safari和iOS设备上出现明显卡顿。动画基于CSS keyframes实现旋转效果,已添加-webkit前缀适配Safari,尝试过will-change属性,但问题仍未解决。相关代码如下:
CSS代码
.hero-scroll { position: absolute; top: 35%; left: 50%; transform: translate(-50%, -50%); font-size: 6rem; font-weight: bold; transition: transform 0.7s ease, font-size 0.7s ease, top 0.7s ease, color 0.7s ease; z-index: 2; color: rgba(255, 255, 255, 0.3); letter-spacing: 0.5px; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-rendering: optimizeLegibility; -webkit-text-stroke: 0.5px transparent; text-shadow: 0px 0px 1px rgba(0, 0, 0, 0.1); } @-webkit-keyframes keyarm { 0% { -webkit-transform: rotate(0deg); } 5% { -webkit-transform: rotate(-14deg); } 10% { -webkit-transform: rotate(0deg); } 100% { -webkit-transform: rotate(0deg); } } @keyframes keyarm { 0% { transform: rotate(0deg); } 5% { transform: rotate(-14deg); } 10% { transform: rotate(0deg); } 100% { transform: rotate(0deg); } } .sticky { position: fixed; top: 5%; left: 50%; transform: translate(-50%, -50%); font-size: 2rem; color: #000; z-index: 1001; transition: top 0.7s ease, font-size 0.7s ease, color 0.7s ease; user-select: none; -webkit-animation: keyarm 1.5s ease-in-out infinite; animation: keyarm 1.5s ease-in-out infinite; }
React组件代码
import React, { forwardRef } from 'react'; const HeroSection = forwardRef((props, ref) => { return ( <div className="hero-section"> <div className="hero-image-left"> <h1 className="hero-scroll" ref={ref}>ATNATIC</h1> <div className="video-container"> <video src="/Static/Models/Refercopy.mp4" autoPlay loop muted playsInline className="hero-video" /> </div> </div> </div> ); }); export default HeroSection;
App.js代码片段
const handleScroll = () => { const header = headerRef.current; const heroText = heroTextRef.current; const threshold = header ? header.offsetHeight : 0; if (header) { if (window.scrollY > threshold) { header.classList.add('visible'); header.classList.remove('pre-scroll'); } else { header.classList.remove('visible'); header.classList.add('pre-scroll'); } } if (heroText) { if (window.scrollY >= threshold) { heroText.classList.add('sticky'); } else { heroText.classList.remove('sticky'); } } };
优化方案
1. 分离transform属性冲突
当前.sticky类同时设置了transform: translate(-50%, -50%)和动画中的transform: rotate(),Safari对叠加的transform处理易引发卡顿。通过嵌套元素分离平移定位与旋转动画:
修改React组件结构:
const HeroSection = forwardRef((props, ref) => { return ( <div className="hero-section"> <div className="hero-image-left"> {/* 外层处理平移定位,内层承载文本与旋转动画 */} <div className="hero-scroll" ref={ref}> <h1>ATNATIC</h1> </div> <div className="video-container"> <video src="/Static/Models/Refercopy.mp4" autoPlay loop muted playsInline className="hero-video" /> </div> </div> </div> ); });
修改CSS样式:
.hero-scroll { position: absolute; top: 35%; left: 50%; transform: translate(-50%, -50%); z-index: 2; } .hero-scroll h1 { font-size: 6rem; font-weight: bold; transition: font-size 0.7s ease, color 0.7s ease; color: rgba(255, 255, 255, 0.3); letter-spacing: 0.5px; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-rendering: optimizeLegibility; -webkit-text-stroke: 0.5px transparent; text-shadow: 0px 0px 1px rgba(0, 0, 0, 0.1); } .sticky { position: fixed; top: 5%; left: 50%; transform: translate(-50%, -50%); z-index: 1001; transition: top 0.7s ease; } .sticky h1 { font-size: 2rem; color: #000; user-select: none; -webkit-animation: keyarm 1.5s ease-in-out infinite; animation: keyarm 1.5s ease-in-out infinite; } /* 动画仅作用于内层h1,避免与外层平移冲突 */ @-webkit-keyframes keyarm { 0% { -webkit-transform: rotate(0deg); } 5% { -webkit-transform: rotate(-14deg); } 10% { -webkit-transform: rotate(0deg); } 100% { -webkit-transform: rotate(0deg); } } @keyframes keyarm { 0% { transform: rotate(0deg); } 5% { transform: rotate(-14deg); } 10% { transform: rotate(0deg); } 100% { transform: rotate(0deg); } }
2. 强制启用硬件加速
给动画元素添加属性,强制Safari创建独立渲染层,降低重绘开销:
.sticky h1 { /* 保留原有样式 */ backface-visibility: hidden; -webkit-backface-visibility: hidden; transform: translateZ(0); -webkit-transform: translateZ(0); }
3. 简化动画与过渡的叠加
原代码中.sticky类同时触发字体大小过渡和旋转动画,Safari对字体变化的重绘成本较高。通过分离元素的方式已减少冲突,也可进一步调整动画时间曲线,将静止阶段的占比通过keyframes直接定义,避免无效的帧渲染。
验证建议
修改后在iOS Safari中测试滚动切换效果,使用Safari开发者工具的Timelines面板查看重绘/回流数据,确认优化后的性能提升。
内容的提问来源于stack exchange,提问作者Sudarshan R
相关产品推荐
相关产品推荐

