Canvas consumes a lot of memory.

I'm having difficulty with my Canvas implementation, which I open in the overlay. The canvas element has a width of 760 pixels and a height of 2640 pixels (I know, don't ask).

I draw lines at each maximum of 27.5px.

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

The appearance of the browser seems to “suffocate” when creating the canvas. In the end, this happens after (1-5 seconds), and the memory is increased by 20 MB.

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

Resizing the canvas to a maximum of 264px and drawing lines on each 2.75px is faster and consumes only about 4 MB (which also does not seem to be cleared, of course).

Who has some guidance on how to avoid this.

<h / "> Here is another data code - this is an array of objects containing the" Records "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;
       };
+5
source share
2 answers

According to the comments:

If you don't clear the path, you basically expand the path, and since it .stroke()removes the (solid) path, you will still draw more and more, adding more points using .moveTo/ .lineTo.

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

  • The path is cleared of memory - less leaks
  • -
+4

: , @pimvdb . .


, ?

Chrome - , , . .

, 20 , , , ( - ) . , , , , .

, .

+2

All Articles