layui.table渲染万级数据卡死主因是默认全量DOM渲染、前端分页及冗余重绘;须设height触发虚拟滚动、page匹配后端分页、禁用函数模板等优化。
为什么 layui.table 渲染万级数据会卡死?
不是 layui 本身写得差,而是它默认开启全量 dom 渲染 + 前端分页 + 表格重绘逻辑太重。1000 行可能只是稍慢,5000 行开始明显卡顿,1w 行基本卡到鼠标移不动——核心问题在于:每行都生成完整 <tr><td>... 结构,还附带事件绑定、样式计算、虚拟滚动缺失。
常见错误现象:Uncaught RangeError: Maximum call stack size exceeded(递归渲染崩了)、main thread is blocked(浏览器提示页面无响应)、滚动时表格“跳帧”或直接白屏。
关键判断:只要后端能分页,就别在前端硬扛全量数据;如果真要本地全量查(比如离线场景),必须关掉所有非必要渲染项。
怎么关掉 layui.table 的默认性能陷阱?
layui 2.8+ 的 table.render 默认配置里藏着几个“慢开关”,不手动关掉,优化就是空谈:
-
height: 'full-200'或固定高度 → 必须设,否则不触发虚拟滚动(即使数据超 1000 行也不会自动启用) -
page: true→ 如果后端已分页,这里必须设为true并配好limits;如果前端强行全量加载,反而要设为false避免重复计算分页逻辑 -
loading: true→ 看似友好,但大数据下 loading 动画本身也占渲染资源,可设为false,用骨架屏或自定义 loading 更可控 -
cols中每个字段的templet→ 尽量不用函数模板,改用字符串模板('{{d.name}}'),函数模板每次渲染都执行 JS,万级行就是万次函数调用
data 是数组还是接口?选错直接影响首屏速度
两种模式性能差异极大,不能混用:
- 接口模式(
url: '/api/list')→ 推荐。服务端控制分页(page/limit参数),只传当前页数据,DOM 节点数恒定,内存占用低,适合绝大多数业务 - 本地数组(
data: [...])→ 仅限小数据(parseData 做极简处理,且禁用totalRow、toolbar、defaultToolbar等所有统计/工具栏功能(它们会遍历全量 data)
注意:url 模式下,done 回调里不要对 res.data 做深拷贝或 map 处理,避免额外 GC 压力;data 模式下,确保数组是 plain object 数组,不要塞 Date、Map、嵌套对象等复杂类型,layui 内部 JSON 序列化会变慢。
真实压测下还能再挤出 20% 性能的细节
这些点文档不提,但实测有效:
- 去掉
skin: 'line'或'row'→ 默认skin: 'default'样式最轻,line/row 会多加一层 wrapper 和 border 计算 -
cellMinWidth: 60→ 显式设最小宽,避免浏览器反复计算 td 宽度(尤其列多时) - 禁用
checkCol和radioCol→ 如果不需要选择,删掉整列;需要时,用checkbox: false关掉列头全选按钮,减少事件监听器数量 - 表格容器父级加
overflow: hidden→ 防止虚拟滚动区域外溢导致重排
最易被忽略的是:表格初始化后,别在 done 里调 table.cache['id'] 去遍历全量缓存——这个 cache 是 layui 维护的原始数据副本,万级数据下取一次就可能卡住主线程。











