IE11中jQuery DataTables(45+列)脚本超时问题及优化方案咨询
嘿,这个问题我太熟悉了——IE/Edge(尤其是旧版的Edge Legacy)对大量DOM操作和JS循环的容忍度远低于Chrome和Firefox,45列+50行的组合,DataTables默认的渲染逻辑很容易触发那个烦人的“脚本执行耗时过长”报错。下面是几个亲测有效的优化方案,按优先级从高到低排列:
1. 开启
deferRender延迟渲染 这是最容易落地的优化,几乎零成本。默认情况下DataTables会一次性渲染所有行的DOM元素,开启延迟渲染后,它只会渲染当前视口内的行,滚动到新区域时再动态渲染对应行,能大幅减少初始DOM操作的数量。
配置示例:
$('#yourTable').DataTable({ deferRender: true, // 因为你用后端处理分页排序,所以要禁用内置的对应功能 serverSide: false, paging: false, ordering: false, // 其他你需要的配置... });
2. 批量渲染DOM,避免逐行操作
DataTables默认的逐行创建DOM元素的逻辑,在IE里开销极高。你可以自己接管表格内容的渲染,通过拼接完整HTML字符串的方式一次性插入,把DOM操作次数从几十上百次降到1次。
示例代码:
// 假设后端返回的data是行数据数组 const tbodyHtml = data.map(row => { // 拼接当前行的所有列 return `<tr> <td>${row.column1}</td> <td>${row.column2}</td> <!-- 依次拼接剩下的43列... --> </tr>`; }).join(''); // 一次性插入tbody $('#yourTable tbody').html(tbodyHtml); // 再初始化DataTables,只保留必要功能 $('#yourTable').DataTable({ paging: false, ordering: false, autoWidth: false, // 禁用自动列宽计算 });
3. 关闭所有不必要的DataTables功能
DataTables默认带了很多冗余功能,如果你不用,一定要关掉,减少JS的执行量:
autoWidth: false:禁止自动计算列宽,自己用CSS设置固定列宽,避免组件做大量布局计算searching: false:不需要前端搜索的话直接关闭info: false:不需要“显示X-Y条”这类信息的话关闭scrollX: true:表格横向过长时,用滚动代替自动换行,减少布局重排- 全局禁用排序:因为你用后端排序,所以设置
ordering: false,同时在columns配置里给每列加上orderable: false
配置示例:
$('#yourTable').DataTable({ ordering: false, columns: [ { data: 'column1', orderable: false }, { data: 'column2', orderable: false }, // 所有列都设置orderable: false ], autoWidth: false, searching: false, info: false, scrollX: true, });
4. 优化CSS,减少布局重排
IE的CSS渲染引擎对复杂表格的布局处理很慢,通过CSS优化能大幅降低渲染耗时:
- 给表格设置
table-layout: fixed:让表格根据第一行的列宽固定布局,不用遍历所有行计算宽度,渲染速度会快很多 - 给
<th>和<td>设置固定宽度,配合white-space: nowrap和text-overflow: ellipsis避免内容换行触发重排
CSS示例:
#yourTable { table-layout: fixed; width: 100%; } #yourTable th, #yourTable td { width: 100px; /* 根据实际列数调整,确保总宽度足够 */ white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
5. 优化事件绑定与回调逻辑
如果你的代码里用了createdRow、drawCallback这类回调,一定要避免在里面做逐行操作:
- 把逐行绑定事件改成事件委托:给表格父元素绑定一次事件,而不是给每个单元格都绑定,减少事件监听的数量
- 尽量在拼接HTML时就处理好单元格内容,不要在回调里循环修改DOM
事件委托示例:
// 不好的写法:逐行绑定点击事件 $('#yourTable').on('draw.dt', function() { $('#yourTable td').click(function() { // 处理点击逻辑 }); }); // 好的写法:事件委托 $('#yourTable').on('click', 'td', function() { // 处理点击逻辑 });
6. 升级到新版Edge(如果业务允许)
如果用户使用的是旧版Edge(基于IE内核的Edge Legacy),建议升级到基于Chromium的新版Edge——新版的JS和DOM处理效率和Chrome几乎一致,很多这类性能问题会直接消失。当然如果必须兼容旧版,就优先用上面的几个方案。
内容的提问来源于stack exchange,提问作者Hareesh
相关产品推荐
相关产品推荐

