You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

高输入值下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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 18:06:32