这是我的代码:
<!DOCTYPE html>
<html>
<head>
<title>d3 Practice</title>
</head>
<body>
<script src="./vislibs/d3.v3.min.js"></script>
<canvas id="test" width="1024" height="768" style="border: 1px solid black;"></canvas>
<script>
function generate_data(size){
var randomX = d3.random.normal(width/2 , 80),
randomY = d3.random.normal(height/2, 80);
var data = d3.range(size).map(function() {
return [
randomX(),
randomY()
];
});
return data
}
function main() {
var canvasEl = d3.select('#test').node();
// get 2d context to draw on
var ctx = canvasEl.getContext('2d');
width = canvasEl.width
height = canvasEl.height
data=generate_data(20000000)
alert("data generated")
// set fill color of context
var x = 0
ctx.fillStyle = 'red';
batch_size = 10000
debugger // Cannot step into requestAnimationFrame(draw_loop) at all , freezing eternity
draw_loop = function () {
if (x<=data.length-1) {
for (i in d3.range(0,batch_size)){
//console.log(x)
ctx.fillRect(data[x][0], data[x][1], 2, 2);
x = x+1
}
setTimeout(draw_loop,100);
}
}
requestAnimationFrame(draw_loop)
//alert("done reqanim")
}
main()
//init()
</script>
</body>
</html>
这将在生成后冻结浏览器generate_data(20000000)
,甚至不需要 requestAnimationFrame(draw_loop)
. 我在没有requestAnimationFrame
or的情况下进行了测试,setTimeout
并且一次渲染了所有内容,但工作正常,但它使浏览器冻结了一点。卸载到服务器似乎是一个很好的解决方案,但我想知道为什么暂停(setTimeout 和 requestAnimiationFrame)会导致浏览器无限期冻结而不是控制浏览器。
在 linux 上测试,Chromium 版本 26.0.1410.43 (189671)。
浏览器的内存使用量约为 1.4 GB,仅在完成后打开该脚本的一个选项卡generate_data(20000000)
,但我的笔记本电脑上有 6 GB 的可用内存。那么有什么有效的方法来处理它吗?(不会导致无响应或无限冻结)
编辑:
这是工作JSFiddle 2 mil矩形
这将冻结您的浏览器。 2000 万个矩形
如果没有 setTimeout 或 requestAnimationFrame ,这将导致 1-2 无响应,但可以很好地渲染到最后而不会冻结。 20 00 万个没有暂停功能的矩形
概念证明,无渲染代码,数据生成后,你会看到数据生成后的警告框,但浏览器一点击 requestAnimationFrame 就被冻结。(2000 万点)将冻结浏览器,
function generate_data(size){
var randomX = d3.random.normal(width/2 , 80),
randomY = d3.random.normal(height/2, 80);
var data = d3.range(size).map(function() {
return [
randomX(),
randomY()
];
});
return data
}
function main() {
var canvasEl = d3.select('#test').node();
// get 2d context to draw on (the "bitmap" mentioned earlier)
var ctx = canvasEl.getContext('2d');
width = canvasEl.width
height = canvasEl.height
data=generate_data(20000000)
alert("data generated")
// set fill color of context
var x = 0
ctx.fillStyle = 'red';
batch_size = 10000
//debugger // Cannot step into requestAnimationFrame(draw_loop) at all , freezing eternity
draw_loop = function () {
if (x<=data.length-1) {
nada=""
x=x+batch_size
setTimeout(draw_loop,100);
}
}
requestAnimationFrame(draw_loop)
alert("done reqanim")
}
main()