React项目中高效渲染可交互棋盘格的优化方案咨询
优化棋盘格渲染与交互方案(React环境)
一、性能优化:替代大量<rect>的方案
1. SVG Pattern 方案
不用逐个渲染<rect>,而是定义棋盘格图案作为SVG填充,DOM节点数从N²降到个位数,性能大幅提升:
function Chessboard({ canvasSize }) { return ( <svg style={{ width: canvasSize * 100, height: canvasSize * 100 }}> <defs> <pattern id="chessboard" width="200" height="200" patternUnits="userSpaceOnUse"> <rect width="100" height="100" fill="#fff" /> <rect x="100" y="100" width="100" height="100" fill="#fff" /> <rect x="100" width="100" height="100" fill="#ccc" /> <rect y="100" width="100" height="100" fill="#ccc" /> </pattern> </defs> <rect width="100%" height="100%" fill="url(#chessboard)" /> </svg> ); }
如果你的calcFillColor是动态逻辑,可直接修改pattern内的填充色,或根据需求动态生成pattern内容。
2. CSS 背景渐变方案
用CSS线性渐变实现棋盘格,完全无需大量DOM或SVG,性能最优:
function Chessboard({ canvasSize }) { return ( <div style={{ width: `${canvasSize * 100}px`, height: `${canvasSize * 100}px`, backgroundImage: `linear-gradient(45deg, #ccc 25%, transparent 25%, transparent 75%, #ccc 75%, #ccc), linear-gradient(45deg, #ccc 25%, white 25%, white 75%, #ccc 75%, #ccc)`, backgroundSize: '200px 200px', backgroundPosition: '0 0, 100px 100px' }} /> ); }
动态颜色需求可直接替换渐变中的色值。
二、交互实现(hover高亮、点击选中)
若需单个单元格交互,推荐CSS Grid+React状态方案,平衡性能与交互性:
import { useState } from 'react'; function Chessboard({ canvasSize }) { const [selectedCells, setSelectedCells] = useState(new Set()); const getCellColor = (r, c) => (r + c) % 2 === 0 ? '#fff' : '#ccc'; const handleCellClick = (r, c) => { const key = `${r}-${c}`; setSelectedCells(prev => { const newSet = new Set(prev); newSet.has(key) ? newSet.delete(key) : newSet.add(key); return newSet; }); }; return ( <div style={{ display: 'grid', gridTemplateColumns: `repeat(${canvasSize}, 100px)`, gridTemplateRows: `repeat(${canvasSize}, 100px)`, }} > {Array.from({ length: canvasSize }, (_, r) => Array.from({ length: canvasSize }, (_, c) => { const key = `${r}-${c}`; const isSelected = selectedCells.has(key); return ( <div key={key} onClick={() => handleCellClick(r, c)} style={{ width: '100px', height: '100px', backgroundColor: getCellColor(r, c), border: isSelected ? '2px solid blue' : 'none', transition: 'background-color 0.2s', }} onMouseEnter={(e) => e.target.style.backgroundColor = '#aaa'} onMouseLeave={(e) => e.target.style.backgroundColor = getCellColor(r, c)} /> ); }) )} </div> ); }
hover效果也可改用纯CSS实现(更简洁):
.cell:hover { background-color: #aaa !important; }
三、SVG vs Table 性能对比
100×100网格下,Table方案性能远不如优化后的SVG或CSS Grid方案:
- Table需要渲染100个
<tr>+10000个<td>,DOM节点量巨大,重排重绘成本高,交互或滚动时易卡顿。 - SVG Pattern方案仅需少量DOM节点,性能最优;即便用原始
<rect>方案(10000个元素),性能也与Table持平,但优化后碾压Table。 - CSS Grid方案的DOM节点数虽与Table相当,但React虚拟DOM优化+浏览器对Grid的高效渲染,实际表现优于Table。
总结:无交互需求优先选CSS渐变,有交互选CSS Grid,SVG Pattern适合需矢量缩放但交互少的场景,Table方案不推荐用于大网格。
内容的提问来源于stack exchange,提问作者crystaltine
相关产品推荐
相关产品推荐

