javascript性能优化_如何减少重绘和回流
发布时间 - 2026-01-09 00:00:00 点击率:次回流是浏览器重新计算元素几何属性并构建渲染树的过程,重绘是仅重画外观变化的像素;回流必触发重绘,但重绘不一定触发回流;读取 offsetTop 等布局信息会强制同步回流,应批量读写分离,优先使用 transform/opacity,结合 DocumentFragment 和 display 隐藏优化。
什么是回流(reflow)和重绘(repaint)
回流是浏览器重新计算元素几何属性(位置、尺寸)并重新构建渲染树的过程;重绘是仅改变元素外观(如颜色、背景)但不触发几何变化时,重画像素的过程。回流必然触发重绘,但重绘不一定触发回流。offsetTop、clientWidth、getComputedStyle() 这类读取布局信息的 API 会强制同步触发回流——这是性能杀手的常见源头。
批量读写分离:避免强制同步回流
连续读写混用会导致多次回流。比如先读 offsetHeight,再改 style.width,再读 offsetLeft,浏览器会在每次读操作前“清空队列”,强制执行一次回流。
正确做法是把所有读操作集中到一起,所有写操作集中到一起:
const el = document.getElementById('box');
// ❌ 错误:读-写-读-写 → 触发 2 次回流
el.style.width = '200px';
console.log(el.offsetHeight);
el
.style.height = '100px';
console.log(el.offsetWidth);
// ✅ 正确:读批量在前,写批量在后 → 最多 1 次回流
console.log(el.offsetHeight);
console.log(el.offsetWidth);
el.style.width = '200px';
el.style.height = '100px';
用 transform 和 opacity 替代位置/尺寸变更
CSS 属性中,transform(如 translateX、scale)和 opacity 属于合成层(compositing layer),修改它们只触发重绘或直接由 GPU 合成,完全跳过回流和主渲染管线。
- 用
transform: translateX(10px)代替left: 10px - 用
transform: scale(1.2)代替width/height变更 - 动画优先用
@keyframes+transform,而非 JS 修改top/marginLeft
注意:will-change: transform 可提前提示浏览器创建独立图层,但滥用会导致内存占用上升,只对明确频繁动画的元素设置。
离线 DOM 操作与文档片段
向 document.body 频繁插入多个节点(如循环 appendChild)会逐次触发回流。应先构建完整结构,再一次性挂载。
推荐方式:
- 用
DocumentFragment缓存节点,最后append()一次 - 对已有元素,先
el.style.display = 'none',操作完再设回'block' - 使用
innerHTML批量写入 HTML 字符串(比逐个创建元素快,但需注意 XSS)
const fragment = document.createDocumentFragment();
for (let i = 0; i < 100; i++) {
const div = document.createElement('div');
div.textContent = `Item ${i}`;
fragment.appendChild(div);
}
document.getElementById('list').appendChild(fragment); // 仅 1 次回流
真正难的是识别隐式回流——比如某个第三方库内部调用了 getBoundingClientRect(),或者框架响应式更新中不经意读写了布局属性。上线前用 Chrome DevTools 的 Rendering > Paint flashing 和 Layers 面板验证,比凭经验更可靠。
# css
# javascript
# java
# html
# js
# 浏览器
# app
# ai
# 内存占用
# 回流
# 重绘
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
如何在自有机房高效搭建专业网站?
网站制作壁纸教程视频,电脑壁纸网站?
Laravel定时任务怎么设置_Laravel Crontab调度器配置
HTML 中动态设置元素 name 属性的正确语法详解
Python数据仓库与ETL构建实战_Airflow调度流程详解
如何在局域网内绑定自建网站域名?
Laravel怎么使用Blade模板引擎_Laravel模板继承与Component组件复用【手册】
如何在搬瓦工VPS快速搭建网站?
CSS3怎么给轮播图加过渡动画_transition加transform实现【技巧】
JS中使用new Date(str)创建时间对象不兼容firefox和ie的解决方法(两种)
百度浏览器如何管理插件 百度浏览器插件管理方法
企业在线网站设计制作流程,想建设一个属于自己的企业网站,该如何去做?
Android利用动画实现背景逐渐变暗
作用域操作符会触发自动加载吗_php类自动加载机制与::调用【教程】
如何在Windows环境下新建FTP站点并设置权限?
浅谈redis在项目中的应用
Laravel如何安装使用Debugbar工具栏_Laravel性能调试与SQL监控插件【步骤】
node.js报错:Cannot find module 'ejs'的解决办法
javascript中的数组方法有哪些_如何利用数组方法简化数据处理
Win11怎么关闭透明效果_Windows11辅助功能视觉效果设置
教你用AI润色文章,让你的文字表达更专业
Javascript中的事件循环是如何工作的_如何利用Javascript事件循环优化异步代码?
Laravel全局作用域是什么_Laravel Eloquent Global Scopes应用指南
Laravel怎么定时执行任务_Laravel任务调度器Schedule配置与Cron设置【教程】
Laravel Livewire是什么_使用Laravel Livewire构建动态前端界面
php后缀怎么变mp4格式错误_修改扩展名提示格式不对怎么办【技巧】
绝密ChatGPT指令:手把手教你生成HR无法拒绝的求职信
iOS正则表达式验证手机号、邮箱、身份证号等
在线制作视频网站免费,都有哪些好的动漫网站?
Python结构化数据采集_字段抽取解析【教程】
JavaScript如何操作视频_媒体API怎么控制播放
Laravel怎么解决跨域问题_Laravel配置CORS跨域访问
如何将凡科建站内容保存为本地文件?
谷歌浏览器如何更改浏览器主题 Google Chrome主题设置教程
南京网站制作费用,南京远驱官方网站?
Laravel如何使用软删除(Soft Deletes)功能_Eloquent软删除与数据恢复方法
Laravel如何集成Inertia.js与Vue/React?(安装配置)
手机网站制作与建设方案,手机网站如何建设?
如何在云服务器上快速搭建个人网站?
Laravel如何实现模型的全局作用域?(Global Scope示例)
香港服务器WordPress建站指南:SEO优化与高效部署策略
中山网站推广排名,中山信息港登录入口?
如何用狗爹虚拟主机快速搭建网站?
网站制作大概要多少钱一个,做一个平台网站大概多少钱?
Laravel如何发送邮件_Laravel Mailables构建与发送邮件的简明教程
Laravel Facade的原理是什么_深入理解Laravel门面及其工作机制
高防服务器租用首荐平台,企业级优惠套餐快速部署
Laravel如何配置.env文件管理环境变量_Laravel环境变量使用与安全管理
微信小程序 HTTPS报错整理常见问题及解决方案
Python图片处理进阶教程_Pillow滤镜与图像增强


.style.height = '100px';
console.log(el.offsetWidth);
// ✅ 正确:读批量在前,写批量在后 → 最多 1 次回流
console.log(el.offsetHeight);
console.log(el.offsetWidth);
el.style.width = '200px';
el.style.height = '100px';