画布消耗大量内存 [英] Canvas consumes a lot of memory

查看:213
本文介绍了画布消耗大量内存的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在我的Canvas实现中遇到困难,我在叠加层中打开它。
canvas元素宽度为760px,高度为2640px(我知道,不要问)。



我在每高27.5px绘制线条。 p>

  ctx.moveTo(0,y); 
ctx.lineTo(760,y);
ctx.strokeStyle ='rgb(100,100,100)';
ctx.stroke();

显然,在创建画布时,浏览器似乎最终它通过(1-5秒),内存被提高了20MB。



关闭覆盖不似乎释放这个内存。
当我重新打开覆盖(它重新绘制画布),内存再次增加。
等等...
我的chrome进程从60MB内存到600+在这种方式。



调整大小画布高度为264px,每2.75像素的绘制线的速度更快,只消耗4MB左右(这当然也不会被清除)。



一些指针如何避免这一点。





这里是更多的代码
数据是一个对象数组,包含一个Entries属性也是一个数组。

  [{Entries:[{...},{...} },{...},...] 

var $ canvas = container.find('canvas')
,canvas = $ canvas.get(0)
,maxY = canvas.height
,maxX = canvas.width
,dX = maxX /(data.length + 1)
,ctx = canvas.getContext('2d');


var x1,y1,y2,mh;

$ .each(data,function(i,day){
if(!day.Entries)return;

$ .each(day.Entries,函数(j,entry){
x1 =(i + 1)* dX;
mh = entry.BeginDate.toHourMinutes();
y1 =(((mh.h * 60) + mh.m)/ 1440)* maxY;
mh = entry.EndDate.toHourMinutes();
y2 =((mh.h * 60)+ mh.m)/ 1440)* maxY ;

switch(entry.Type){
case CALENDARTYPES.OPENINGHOUR:
ctx.beginPath();
ctx.rect(x1,y1,dX - 10 ,y2 - y1);
ctx.fillStyle =rgb(125,125,125);
ctx.fill();
ctx.closePath();
;
case CALENDARTYPES.BLOCKING:
ctx.clearRect(x1,y1,dX,y2 - y1);
break;
};
});
});

delete x1,y1,y2,mh;

//在画布上绘制网格。

var x = 0
,y = +0.5
,stepYH = maxY / 24
,stepYQ = stepYH / 4
,isHour = true;

ctx.lineWidth = 1;

while(y< maxY){
isHour =(((y - 0.5)%stepYH)== 0);
ctx.moveTo(isHour?x:x + dX,y);
ctx.lineTo(maxX,y);
ctx.strokeStyle = isHour? 'rgb(175,175,175)':'rgb(100,100,100)';
ctx.stroke();
y + = stepYQ;
};


解决方案

根据意见:



如果你不清除路径,你基本上是扩展路径,因为 .stroke() ,当你使用 .moveTo / .lineTo 添加更多点时,你会最终画出越来越多的点。 p>

使用 .beginPath()可能更有意义,因此您只需敲击新路径而不是旧路径




  • 路径从内存清除 - 少泄漏

  • 不再绘制旧路径 - 性能损失较少


I am having difficulties with my Canvas-implementation which I open in an overlay. The canvas element is 760px wide and 2640px high (I know, don't ask).

I am drawing lines at every 27.5px high.

ctx.moveTo(0, y);
ctx.lineTo(760, y);
ctx.strokeStyle = 'rgb(100,100,100)';
ctx.stroke();

Appearantly the browser seems to 'choke' on this when creating the canvas. Eventually it comes through (1-5secs) and memory is raised by 20MB.

Closing the overlay does not seem to free this memory. When I reopen the overlay (which redraws the canvas), the memory is again increased. And so on, and so on... My chrome process goes from 60MB memory to 600+ in no time this way.

Resizing the canvas to 264px high and drawing lines at every 2.75px goes way faster and consumes only about 4MB (which also does not seem to be cleared of course).

Who has some pointers on how to avoid this.


Here is more code data is an array of objects containing an Entries property which is also an array.

[ { Entries : [{...},{...},...] }, {...}, ... ]

var $canvas = container.find('canvas')
    , canvas = $canvas.get(0)
    , maxY = canvas.height
    , maxX = canvas.width
    , dX = maxX / (data.length + 1)
    , ctx = canvas.getContext('2d');


var x1, y1, y2, mh;

$.each(data, function (i, day) {
    if (!day.Entries) return;

     $.each(day.Entries, function (j, entry) {
         x1 = (i + 1) * dX;
         mh = entry.BeginDate.toHourMinutes();
         y1 = (((mh.h * 60) + mh.m) / 1440) * maxY;
         mh = entry.EndDate.toHourMinutes();
         y2 = (((mh.h * 60) + mh.m) / 1440) * maxY;

         switch (entry.Type) {
             case CALENDARTYPES.OPENINGHOUR:
                 ctx.beginPath();
                 ctx.rect(x1, y1, dX - 10, y2 - y1);
                 ctx.fillStyle = "rgb(125, 125, 125)";
                 ctx.fill();
                 ctx.closePath();
                 break;
             case CALENDARTYPES.BLOCKING:
                 ctx.clearRect(x1, y1, dX, y2 - y1);
                 break;
         };
      });
  });

       delete x1, y1, y2, mh;

       //Draw grid on canvas.

       var x = 0
           , y = +0.5
           , stepYH = maxY / 24
           , stepYQ = stepYH / 4
           , isHour = true;

       ctx.lineWidth = 1;

       while (y < maxY) {
           isHour = (((y - 0.5) % stepYH) == 0);
           ctx.moveTo(isHour ? x : x + dX, y);
           ctx.lineTo(maxX, y);
           ctx.strokeStyle = isHour ? 'rgb(175,175,175)' : 'rgb(100,100,100)';
           ctx.stroke();
           y += stepYQ;
       };

解决方案

As per the comments:

If you do not clear the path, you're basically extending the path, and since .stroke() strokes the (entire) path, you'll end up drawing more and more as you add more points using .moveTo/.lineTo.

It might make more sense to use .beginPath() so that you only stroke the new path and not the old path as well:

  • Path is cleared from memory - less leaks
  • Old path is not drawn again - less performance loss

这篇关于画布消耗大量内存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆