Guides

Making Framer Fast: Measuring Web App Performance

January 24, 2022

Browsers are really fast these days, but a common misconception is that browsers are too slow for fast graphics (this isn't true). What most people mean by that is that the language used in the browser, JavaScript, can be slower than other (native) languages, which is true. But drawing graphics is typically not dependent on JavaScript at all. Even though JavaScript might tell the browser to draw something, the actual drawing is completely native and extremely optimized. Drawing is what the browser does all day, and it's extremely good at it. That's why Framer canvas uses the browser directly for graphics rendering, compared to other tools that build on CoreGraphics, WebGL, or a custom graphics toolkit.

A huge advantage from using the DOM for drawing is that it can do everything, from GPU accelerated graphics, to platform native font rendering, to advanced filters, to animations and videos. It’s a marvel of engineering to optimize for all of those at the same time. Plus it’s truly WYSIWYG, because you’re drawing it where others will see it. For example, under the hood Chrome actually uses Skia, which in its turn uses OpenGL (or even the modern even faster Vulkan or Metal backends), probably the fastest and most versatile graphics toolkit on the planet. If you are using Chrome, you can find your current graphics acceleration settings under chrome://gpu/.

When we say fast, what do we really mean?

When we talk about a fast canvas or fast computer in general, there are three parts that we mean. First, the time it takes things to load. For example, the time it takes for the app to load or for a specific page or document to load before you can see it and start working. Second, the time it takes to draw (every frame), determining how smooth scrolling and animations are. And finally, the time it takes something to respond to your actions, in other words, the latency or lag you feel—or don’t feel.

How we’re making Framer fast

Framer uses lazy loading or virtualization on the canvas. This means that it’s only drawing the actual layers that you can see, not the ones out of view. You can see this lazy loading at work if you scroll quickly or zoom out, the layers can take a second to appear. This is a very typical trick for computers. You’ve probably seen this using Google Maps for example, where it’s loading “tiles” if you scroll quickly to a new place. The browser actually does the exact same thing itself when you scroll too, but it’s so fast that you can’t see it. Even Tables on iOS do this. Or Google Sheets. Your refrigerator light, the double slit experiment, this trick is practically used everywhere.

Additionally, Framer uses the graphics card (GPU) to draw (almost) everything. In CSS you can tell elements to draw on the GPU by using will-change: transform. At that point, the element will basically be converted to a picture, like a jpg, and sent to your graphics card. The graphics card can manipulate those pictures “for free” but it can only do certain things: move, scale, rotate, skew, opacity, and order. But it’s so fast that it can do that for millions of pictures without breaking a sweat. This is why layers in Framer, or other tools, can get blurry for a split second when you zoom out. You probably wouldn't ever have noticed if I hadn't told you, so sorry about that.

While zooming, the GPU is in control, but it has to use the original image. After the zoom is done, it re-renders the image. Zooming in, funnily enough, doesn’t have the same effect as it needs less pixels, but it might have to render more elements in total that now fit on the visible canvas.