I have implemented a renderer for shapes described with a [L-System grammar][1]. Implementation of that is not important. Basically you feed it an angle and some rules, and it spits out a string of characters that represents instructions. For example, "+" means turn right *n* radians and vice versa. The instructions will only be computed once.

The job of `.draw` is to read the instructions and draw it on a canvas continuously. The angle is always changing (however the instructions stay the same) and therefore this method will be called repeatedly:

    LSystem.prototype.draw = function(ctx, x, y) {
        var self = this;
        var path = this.path;
        var table = {
            "F": function(ctx) {
                // draw forward
                ctx.moveTo(0, 0);
                ctx.lineTo(0, -5);
                ctx.translate(0, -5);
            },
            "+": function(ctx) {
                // turn right
                ctx.rotate(self.angle);
            },
            "-": function(ctx) {
                // turn left
                ctx.rotate(-self.angle);
            },
            "[": function(ctx) {
                // save location and rotation
                ctx.save();
            },
            "]": function(ctx) {
                // restore location and rotation
                ctx.restore();
            }
        };
        ctx.save();
        ctx.beginPath();
        ctx.moveTo(x + 0.5, y + 0.5);
        ctx.translate(x + 0.5, y + 0.5);
        for (var i = 0; i < path.length; i++) {
            // take a character from the path
            // and call the corresponding function (if exists)
            var char = path[i];
            var cmd = table[char];
            cmd && cmd(ctx);
        }
        ctx.stroke();
        ctx.restore();
    };

A path (in my case) consists of over 6000 characters. It has no problem in drawing at 60FPS. However the main problem is that it uses a lot of CPU and I can hear the fans in my laptop starts spinning. This is not optimal and I'm looking for a way to solve this.

By looking at the profiling tool in Chrome, we can see that it doesn't like `.rotate` and `.restore` being called repeatedly. On a 16ms budget it already takes up half of it:

[![enter image description here][2]][2]

What is a good way of optimizing the rendering and minimize CPU usage? Would calculating the coordinates for the entire path first then pass it to `.lineTo` a better choice? Keep in mind that the angle is different every time `.draw` is called, so the coordinates cannot be cached and reused.

A demo can be viewed [here][3].


  [1]: https://en.wikipedia.org/wiki/L-system
  [2]: https://i.sstatic.net/0rp2I.png
  [3]: https://jsfiddle.net/DerekL/d4f2u66j/