高输入值下Etch-a-Sketch页面加载卡顿浏览器变慢问题
Etch-a-Sketch 网格加载卡顿问题定位
你的代码性能问题是多个低效写法叠加导致的,输入的网格边长越大,性能开销会呈指数级上涨,具体问题点:
- 重复设置容器样式:你把Grid容器的行列规则写在了生成方块的for循环内部,每生成1个方块就重写一次容器样式,这个操作只需要执行1次,放在循环外即可。
- 核心卡顿原因:指数级重复事件绑定。你每往容器里插入1个新方块,就调用
querySelectorAll选中容器内所有已存在的方块,给每个方块重新绑定mouseenter、mouseleave事件。举个例子,输入边长100需要生成10000个方块,总事件绑定次数是1+2+3+…+10000=50005000次,五千万次DOM查询+事件绑定操作,浏览器必然卡顿。而且同一元素重复绑定的相同事件会多次触发,完全是无效开销。 - 循环边界错误:循环判断条件写的是
i <= input * input,会比目标网格数多生成1个方块,平白增加DOM节点数量。 - 旧网格未清理:每次点击按钮触发
addGrid时,没有清空容器内上一次生成的旧方块,多次点击后DOM节点会持续累积,卡顿会逐次加重。 - 冗余DOM操作:完全没必要每次新增方块就全量查询所有方块节点,更优方案是用事件委托,只给父容器绑定1次事件,就能响应所有子方块的鼠标交互,几乎零额外开销。
修正后代码
HTML
<button id="btn">Click</button> <div id="container"></div>
CSS(补充必要基础样式)
#container { width: 500px; height: 500px; border: 2px solid #333; } .square { background: white; }
JavaScript
const container = document.querySelector('#container'); const btn = document.querySelector('#btn'); // 事件委托:只给容器绑2次事件,即可响应所有方块的鼠标交互 // mouseenter/mouseleave默认不冒泡,第三个参数传true在捕获阶段处理即可实现委托 container.addEventListener('mouseenter', (e) => { if (e.target.classList.contains('square')) { e.target.style.backgroundColor = 'black'; } }, true); container.addEventListener('mouseleave', (e) => { if (e.target.classList.contains('square')) { e.target.style.backgroundColor = 'black'; } }, true); btn.addEventListener('click', addGrid); function addGrid() { // 先清空上一次生成的旧网格 container.innerHTML = ''; let input = prompt("Please enter the number of squares per side (2 - 100)"); while (input == null || input > 100 || input < 2 || isNaN(input)) { input = prompt("Please enter the number of squares per side (2 - 100)"); } input = Number(input); // 容器Grid样式只设置1次,放在循环外 container.style.display = 'grid'; container.style.gridTemplateRows = `repeat(${input}, 1fr)`; container.style.gridTemplateColumns = `repeat(${input}, 1fr)`; // 修正循环边界,用 < 替代 <= 避免多生成方块 for (let i = 0; i < input * input; i++) { const square = document.createElement('div'); square.classList.add('square'); container.appendChild(square); } }
优化提示:如果要实现画板重置功能,直接遍历所有方块把背景色改回白色即可,不用销毁重建DOM,响应速度更快。
内容的提问来源于stack exchange,提问作者daliet
相关产品推荐
相关产品推荐

