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

Etch-a-Sketch项目性能优化求助:大网格下页面卡顿崩溃

Etch-a-Sketch 性能优化方案

你的代码主要存在重复事件绑定、O(n²)级别的DOM操作、低效的手动尺寸计算这几个核心性能问题,导致大网格下页面卡顿甚至崩溃。下面是针对性的优化方案:

核心优化点

  • 用CSS Grid替代手动尺寸计算:直接通过CSS Grid定义网格行列,浏览器自动分配每个单元格的大小,完全省去JS遍历修改样式的步骤。
  • 事件委托减少监听数量:不给每个单元格单独绑定mouseover,而是把事件绑定到网格容器上,利用事件冒泡处理所有单元格的悬停事件,不管网格多大都只需要一个监听。
  • 批量创建DOM元素:先把所有单元格创建好,一次性添加到容器,避免频繁触发页面重排。
  • 修复输入验证逻辑:用循环替代递归,处理非数字输入,避免递归导致的栈溢出。
  • 移除冗余操作:删除循环内重复定义的函数和重复的DOM查询,减少不必要的计算开销。

优化后的完整代码

const body = document.body;
const bodyDiv = document.createElement('div');
bodyDiv.setAttribute('id', 'boxContainer');
body.append(bodyDiv);

const btnDiv = document.createElement('div');
btnDiv.setAttribute('id', 'btnDiv');
bodyDiv.append(btnDiv);

const btn = document.createElement('button');
btn.setAttribute('id', 'changeGridSizeBtn');
btn.innerText = 'Click to change grid size!';
btnDiv.append(btn);

const gridContainer = document.createElement('div');
gridContainer.setAttribute('id', 'gridContainer');
// 初始化CSS Grid样式
gridContainer.style.display = 'grid';
gridContainer.style.width = '960px';
gridContainer.style.height = '720px';
gridContainer.style.gap = '2px'; // 替代原代码中box的间距
bodyDiv.append(gridContainer);

// 随机颜色函数
function randomColor(){
   let randomColorGenerator =  Math.floor(Math.random()*16777215).toString(16);
   return '#' + randomColorGenerator;
}

// 事件委托:单次绑定处理所有单元格悬停
gridContainer.addEventListener('mouseover', (event) => {
    if (event.target.classList.contains('box')) {
        event.target.style.backgroundColor = randomColor();
    }
});

// 按钮悬停效果
btn.addEventListener('mouseenter', () => {
    btnDiv.style.boxShadow = '5px 10px #888888';
});
btn.addEventListener('mouseleave', () => {
    btnDiv.style.removeProperty('box-shadow');
});

// 初始化默认16x16网格
createGrid(16);

// 复用的网格创建函数
function createGrid(size) {
    // 清空现有网格
    gridContainer.innerHTML = '';
    // 设置Grid行列布局
    gridContainer.style.gridTemplateColumns = `repeat(${size}, 1fr)`;
    gridContainer.style.gridTemplateRows = `repeat(${size}, 1fr)`;
    
    // 批量创建单元格,用文档片段减少重排
    const fragment = document.createDocumentFragment();
    for (let i = 0; i < size * size; i++) {
        const boxDiv = document.createElement('div');
        boxDiv.className = 'box';
        boxDiv.style.backgroundColor = '#fff';
        fragment.appendChild(boxDiv);
    }
    gridContainer.appendChild(fragment);
}

// 按钮点击处理逻辑
btn.addEventListener('click', () => {
    let userGridSize;
    // 循环验证输入,替代递归避免栈溢出
    while (true) {
        userGridSize = prompt('Please enter a number between 1-100 for the grid size.');
        if (userGridSize === null) break; // 处理用户取消输入
        const num = parseInt(userGridSize);
        if (!isNaN(num) && num >=1 && num <=100) {
            createGrid(num);
            break;
        } else {
            alert('Invalid input! Please enter a number between 1 and 100.');
        }
    }
});

优化效果说明

  • 网格尺寸超过40时不会再卡顿:CSS Grid的布局效率远高于手动JS计算,事件委托也避免了大量重复监听。
  • 代码结构更清晰:把创建网格的逻辑封装成复用函数,减少冗余代码。
  • 输入验证更健壮:处理了非数字、超出范围以及用户取消输入的情况。

内容的提问来源于stack exchange,提问作者benjamin1

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 08:30:47