直接修改 grid-template-columns 会强制同步重排,因浏览器需丢弃缓存、重测子项并重新分配轨道;应改用 CSS 自定义属性、媒体查询、minmax(像素值, 1fr)、显式 grid-auto-rows 及预设宽高来规避。

为什么直接改 grid-template-columns 会抖
浏览器每次解析新的 grid-template-columns 字符串(比如 el.style.gridTemplateColumns = '1fr 2fr'),都必须丢弃旧的网格缓存,从头测量所有子项的 min-content、扣除 gap、再重新分配轨道——这个过程无法异步,且必然触发整容器同步重排。滚动中频繁调用,DevTools Performance 面板里会密集出现 “Layout” 事件。
用 CSS 自定义属性替代 JS 字符串拼接
把列数或比例逻辑抽到 CSS 变量里,让浏览器内部完成计算,不暴露 layout 触发点:
.grid {
--cols: 3;
display: grid;
grid-template-columns: repeat(var(--cols), 1fr);
}
JS 只需更新变量值:
-
el.style.setProperty('--cols', '4')—— 安全,不触发重排 - 避免
el.style.gridTemplateColumns = '1fr 1fr 1fr 1fr'—— 每次都强制重算 - 若需响应式列数变化,优先用媒体查询整套切换,而非 JS 动态写入
慎用 minmax() 混合单位组合
minmax(30%, 1fr) 在 Safari ≤15.4 中极易抖动,因为滚动条出现/消失会导致容器宽度微变,30% 像素值跳变,连带 1fr 分配震荡。更稳的写法是:
- 用
minmax(280px, 1fr)替代百分比,固定下限像素值 - 完全避开
%和fr混用,尤其在grid-template-rows中 - 需要比例布局时,用
repeat(auto-fit, minmax(280px, 1fr))),由 CSS 引擎原生处理,不走 JS 路径
动态增删子项时,别依赖隐式轨道自动伸缩
没设 grid-auto-rows 的 Grid 容器,新增项会掉进 auto 高度的隐式行,内容加载或文字变化时高度突变,反向拉扯列宽计算,放大抖动。
- 显式声明
grid-auto-rows: minmax(48px, auto),给隐式行设最小高度底线 - 避免
grid-auto-rows: 1fr或minmax(0, 1fr),0 会让空项坍缩,破坏结构稳定性 - 图片等异步内容,必须在父容器上用
aspect-ratio或padding-top预留空间,否则加载瞬间触发整行重排
真正卡顿的从来不是 fr 本身,而是你把它放在了读写布局的敏感路径上。只要 JS 还在 scroll/resize 回调里拼字符串改 grid-template-columns,抖动就停不下来——这不是浏览器问题,是你把布局计算权交给了最不可控的时机。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











