IBM Cognos Analytics 11.1.7大数据量JS读取性能优化求助
优化IBM Cognos ControlHost中70万行数据的JavaScript代码性能
核心问题分析
代码在小数据量下正常,70万行时卡顿的核心原因:
- DOM操作过载:循环创建70万个
<div>元素,浏览器DOM渲染、重排重绘的开销远超承载能力 - 冗余计算与低效数据读取:
setData中逐行调用getCellValue的循环方式、draw阶段重复遍历数组计算最大值
具体优化方案
1. 替换DOM渲染为Canvas绘制(解决最大性能瓶颈)
70万个DOM元素完全超出浏览器承载上限,改用Canvas绘制条形可将渲染性能提升数个数量级,修改draw方法:
D3BarChart.prototype.draw = function(oControlHost) { var o = oControlHost.configuration; var iWidth = (o && o.Width) ? o.Width : 500; var iHeight = (o && o.Height) ? o.Height : 16; var sBackgroundColor = (o && o["Background color"]) ? o["Background color"] : "#C8F08F"; var barMargin = 4; var totalBarHeight = iHeight + barMargin; // 创建或获取Canvas元素 var container = d3.select(oControlHost.container); var canvas = container.select("canvas").node(); if (!canvas) { canvas = container.append("canvas").node(); } canvas.width = iWidth; canvas.height = this.m_aData.length * totalBarHeight; var ctx = canvas.getContext("2d"); // 使用预处理好的最大值,避免重复遍历 var scale = d3.scale.linear() .domain([0, this.m_maxValue]) .range([0, iWidth]); // 批量绘制所有条形 ctx.fillStyle = sBackgroundColor; ctx.strokeStyle = "gray"; this.m_aData.forEach(function(d, index) { var barWidth = scale(d); var y = index * totalBarHeight; // 绘制条形背景 ctx.fillRect(0, y, barWidth, iHeight); // 绘制边框 ctx.strokeRect(0, y, barWidth, iHeight); // 绘制文本(70万行文本会密集,可根据需求关闭) ctx.fillStyle = "black"; ctx.font = iHeight + "px sans-serif"; ctx.fillText(d, 5, y + iHeight - 2); ctx.fillStyle = sBackgroundColor; }); };
2. 优化数据读取与预处理
在setData阶段完成数据提取和最大值计算,避免重复遍历数组:
D3BarChart.prototype.setData = function(oControlHost, oDataStore) { this.m_oDataStore = oDataStore; var iRowCount = oDataStore.rowCount; // 预先分配数组空间,性能优于push this.m_aData = new Array(iRowCount); var maxValue = 0; // 缓存方法引用,减少属性查找开销 var getCellValue = oDataStore.getCellValue; for (var iRow = 0; iRow < iRowCount; iRow++) { var value = getCellValue(iRow, 1); this.m_aData[iRow] = value; // 同步计算最大值 if (value > maxValue) { maxValue = value; } } this.m_maxValue = maxValue; };
3. 可选:虚拟滚动优化(针对超大量数据显示)
如果无需一次性展示全部70万行,可实现虚拟滚动:监听滚动事件,计算当前视口的索引范围,仅渲染可见区域内的条形,进一步降低渲染压力。
优化效果说明
- Canvas替代DOM后,70万行数据的渲染时间会从几十分钟缩短至几秒内
- 数据提取阶段的优化减少了函数调用和数组操作开销
- 预处理最大值避免了
draw阶段的额外数组遍历
内容的提问来源于stack exchange,提问作者temeribrahim
相关产品推荐
相关产品推荐

