如何消除页面渲染时因navHeight计算延迟导致的布局偏移?
解决布局偏移(Layout Shift)的几种方案
方案1:用CSS Flexbox 替代JS计算(推荐)
完全通过布局逻辑让main自动占据剩余视口高度,不需要依赖JS计算导航高度,从根源避免布局偏移。
// 给父容器设置flex垂直布局 <div style={{ display: 'flex', flexDirection: 'column', minHeight: '100vh' }}> <nav ref={navRef}>导航内容</nav> {/* flex:1 让main自动填充剩余空间 */} <main style={{ flex: 1 }}></main> </div>
导航高度由自身内容决定,main会自动适配剩余高度,全程无JS计算,不会出现布局跳动。
方案2:给navHeight设置合理初始值
如果导航高度是固定值(比如设计稿指定60px),直接把初始状态设为该值,后续JS计算的高度只会做微小修正,不会引发明显偏移:
const [navHeight, setNavHeight] = useState(60); // 预设导航默认高度 useLayoutEffect(() => { setNavHeight(navRef.current!.clientHeight); }, []); <main style={{ height: `calc(100vh - ${navHeight}px)` }}></main>
方案3:初始渲染时设置占位高度/骨架屏
如果导航高度完全不固定,且必须用JS计算,可以在高度未获取到前,给main设置临时占位高度,或者用骨架屏占位:
const [navHeight, setNavHeight] = useState(null); useLayoutEffect(() => { setNavHeight(navRef.current!.clientHeight); }, []); <main style={{ // 未获取高度时用临时值占位,获取后替换为真实高度 height: navHeight ? `calc(100vh - ${navHeight}px)` : 'calc(100vh - 60px)', minHeight: 'calc(100vh - 100px)' // 防止内容溢出 }}> {/* 高度未计算完成时显示骨架屏 */} {!navHeight && <div className="skeleton">加载中...</div>} {/* 实际页面内容 */} </main>
内容的提问来源于stack exchange,提问作者Waldemar Karasik
相关产品推荐
相关产品推荐

