优化Chrome扩展表格列单元格填充代码以提升运行速度
优化Chrome扩展表格行序号填充速度的方案
问题背景
我正在开发一款Chrome扩展,通过按钮点击实现网站表格行的上下移动,重排功能运行正常。但填充行序号的代码(新第一行填'0'、第二行填'1'……)运行速度极慢,想寻求优化方法。
原实现代码:
if (test.getElementsByClassName("tr").length == 0) { var tr2 = test_otheruser.getElementsByClassName("tr"), l; } else { var tr2 = test.getElementsByClassName("tr"), l; } for (k = 0; k < tr2.length; k++) { let form_control = tr2[k].getElementsByClassName("td"), m; //write number in reorder cell downwards form_control[Reorder_column].getElementsByClassName('form-control')[0].focus(); const inputElement = form_control[Reorder_column].getElementsByClassName('form-control')[0]; //document.execCommand('insertText', false, 'input value'); inputElement.value = k; inputElement.dispatchEvent( new Event("input", { bubbles: true, cancelable: true }) ); form_control[Reorder_column].getElementsByClassName('form-control')[0].blur(); }
问题核心:这段代码功能正常,但循环内的.focus()、dispatchEvent和.blur()操作拖慢了整体速度。尝试过仅更新.value,但网站只接受「选中→填充→取消选中」的操作流程才能识别数据。
网站简化HTML结构:
<div class="grid"> <div class="table" role="table" style="min-height: 1014px;"> <div class="header" role="row"> <div class="th grid-col-text"> <div class="me-1"> <div class="btn-grid ms-1 " role="button" tabindex="-1"> <div class="grid-header"> <div style="display: flex; justify-content: space-between;"><span>User order</span> </div> </div> </div> </div> </div> <div class="th grid-col-text" role="columnheader" draggable="true"> <div class="me-1"> <div class="btn-grid ms-1 " role="button" tabindex="-1"> <div class="grid-header"> <div style="display: flex; justify-content: space-between;"><span>Reorder</span> </div> </div> </div> </div> </div> </div> <div role="row" tabindex="0" class="tr" id="0"> <div class="td" role="presentation cell"> [SVG buttons up & down here] </div> <div class="td" role="presentation cell"> <div class="grid-cell-input-wrap"> <div class="autowidth-input grid-cell-input"><span>[HERE THE NEW ORDER NUMBER]</span><input class="form-control user-input" type="text" value="[HERE THE NEW ORDER NUMBER]"></div> </div> </div> <div class="td empty" role="presentation cell" id="1"> <div class="grid-cell-input-wrap"> <div class="autowidth-input grid-cell-input"><span>*</span><input class="form-control" type="text" value=""></div> </div> </div> </div> </div>
优化方案
1. 减少重复DOM查询
原代码在循环内多次调用getElementsByClassName,每次都会重新遍历DOM,是主要性能瓶颈之一。提前缓存所有目标元素,减少重复查询:
// 先缓存所有需要操作的input元素 const targetInputs = []; const tr2 = test.getElementsByClassName("tr").length ? test.getElementsByClassName("tr") : test_otheruser.getElementsByClassName("tr"); for (let k = 0; k < tr2.length; k++) { const td = tr2[k].getElementsByClassName("td")[Reorder_column]; const input = td.getElementsByClassName('form-control')[0]; targetInputs.push(input); } // 批量处理缓存的元素 for (let k = 0; k < targetInputs.length; k++) { const input = targetInputs[k]; input.focus(); input.value = k; input.dispatchEvent(new Event("input", { bubbles: true, cancelable: true })); input.blur(); }
2. 优化事件触发逻辑
部分网站对普通Event的处理效率较低,可尝试使用更贴近原生输入行为的InputEvent;同时测试是否可以省略focus()或blur()(如果网站允许):
// 使用InputEvent替代普通Event input.dispatchEvent(new InputEvent("input", { bubbles: true, cancelable: true, data: String(k) })); // 若网站允许,尝试省略blur,减少一次DOM操作 input.focus(); input.value = k; input.dispatchEvent(new InputEvent("input", { bubbles: true, cancelable: true }));
3. 分批处理避免主线程阻塞
使用requestAnimationFrame将操作分批执行,避免一次性处理大量DOM操作导致页面卡顿:
const targetInputs = []; const tr2 = test.getElementsByClassName("tr").length ? test.getElementsByClassName("tr") : test_otheruser.getElementsByClassName("tr"); for (let k = 0; k < tr2.length; k++) { const td = tr2[k].getElementsByClassName("td")[Reorder_column]; const input = td.getElementsByClassName('form-control')[0]; targetInputs.push({ input, index: k }); } let currentIndex = 0; const batchSize = 10; // 每次处理10个,可根据实际情况调整 function processBatch() { const endIndex = Math.min(currentIndex + batchSize, targetInputs.length); for (; currentIndex < endIndex; currentIndex++) { const { input, index } = targetInputs[currentIndex]; input.focus(); input.value = index; input.dispatchEvent(new Event("input", { bubbles: true, cancelable: true })); input.blur(); } if (currentIndex < targetInputs.length) { requestAnimationFrame(processBatch); } } requestAnimationFrame(processBatch);
4. 同步更新显示文本
观察HTML结构,输入框旁有<span>用于显示数值,可直接更新该span的文本,避免框架重新渲染导致的额外开销:
const inputWrap = td.querySelector('.autowidth-input'); const displaySpan = inputWrap.querySelector('span'); displaySpan.textContent = k; input.value = k;
内容的提问来源于stack exchange,提问作者Kclemen
相关产品推荐
相关产品推荐

