- Canvas Draw is a graphics tool that enables you to focus on the message and worry less about the execution.
- Create beautiful designs with your team. Use Canva's drag-and-drop feature and layouts to design, share and print business cards, logos, presentations and more.
- Canvas Draw 5 0 1 – Universal Graphics Tools
- Canvas Draw 5 0 1 – Universal Graphics Tool Set
- Canvas Draw 5 0 1 – Universal Graphics Toolbox
- Canvas Draw 5 0 1 – Universal Graphics Tool Kit
Download the latest XP-Pen drivers, User Manual, and software for Windows 7 /8 /10 and Mac operating system. This is XP-Pen's official website. A hardware driver is a small computer program that allows your computer to interact with XP-Pen products.
Introduction
HTML5 canvas, which started as an experiment from Apple, is the mostwidely supported standard for 2D immediate mode graphics onthe web. Many developers now rely on it for a wide variety ofmultimedia projects, visualizations, and games. However, as theapplications we build increase in complexity, developers inadvertentlyhit the performance wall.
There’s a lot of disconnected wisdom about optimizing canvasperformance. This article aims to consolidate some of this body into amore readily digestible resource for developers. This article includesfundamental optimizations that apply to all computer graphicsenvironments as well as canvas-specific techniques that are subject tochange as canvas implementations improve. In particular, as browservendors implement canvas GPU acceleration, some of the outlinedperformance techniques discussed will likely become less impactful. Thiswill be noted where appropriate.
Note that this article does not go into usage of HTML5 canvas. For that,check out these canvas related articles on HTML5Rocks,this chapter on the Dive into HTML5 site or the MDN Canvastutorial.
Performance testing
To address the quickly changing world of HTML5 canvas, JSPerf(jsperf.com) tests verify that every proposed optimizationstill works. JSPerf is a web application that allows developers towrite JavaScript performance tests. Each test focuses on a result thatyou’re trying to achieve (for example, clearing the canvas), andincludes multiple approaches that achieve the same result. JSPerf runseach approach as many times as possible over a short time period andgives a statistically meaningful number of iterations per second. Higherscores are always better!
Visitors to a JSPerf performance test page can run the test on theirbrowser, and let JSPerf store the normalized test results onBrowserscope (browserscope.org). Because the optimizationtechniques in this article are backed up by a JSPerf result, you canreturn to see up-to-date information about whether or not the techniquestill applies. I’ve written a small helper application thatrenders these results as graphs, embedded throughout this article.
![Draw Draw](https://static.macupdate.com/screenshots/99014/m/colorpicker2-screenshot.png?v=1568233806)
All of the performance results in this article are keyed on thebrowser version. This turns out to be a limitation, since we don't know what OSthe browser was running on, or even more importantly, whether or not HTML5canvas was hardware accelerated when the performance test ran. You can find outif Chrome's HTML5 canvas is hardware accelerated by visiting
about:gpu
in the address bar.Pre-render to an off-screen canvas
If you’re re-drawing similar primitives to the screen across multipleframes, as is often the case when writing a game, you can make largeperformance gains by pre-rendering large parts of the scene.Pre-rendering means using a separate off-screen canvas (or canvases) onwhich to render temporary images, and then rendering the off-screencanvases back onto the visible one.
Photo 3 0 10 – view photos in folders. For example, suppose you’re redrawing Mario running at 60 frames asecond. You could either redraw his hat, moustache, and “M” at eachframe, or pre-render Mario before running the animation.
no pre-rendering:
pre-rendering:
Note the use of
requestAnimationFrame
, which is discussed in more detailin a later section. The following graph illustrates the performancebenefits of using pre-rendering (from thisjsperf):This technique is especially effective when the rendering operation(
drawMario
in the above example) is expensive. A good example of this istext rendering, which is a very expensive operation. Here is the sort ofdramatic performance boost you can expect from pre-rendering thisoperation (from this jsperf):However, observe that in the above example, the poor performance of the“pre-rendered loose” test case. When pre-rendering, it’s important tomake sure that your temporary canvas fits snugly around the image youare drawing, otherwise the performance gain of off-screen rendering iscounterweighted by the performance loss of copying one large canvas ontoanother (which varies as a function of source target size). A snugcanvas in the above test is simply smaller:
Compared to the loose one that yields poorer performance:
Batch canvas calls together
![Canvas draw 5 0 1 – universal graphics tool set Canvas draw 5 0 1 – universal graphics tool set](https://static.macupdate.com/screenshots/260198/m/canvas-draw-screenshot.png?v=1589360771)
Since drawing is an expensive operation, it’s more efficient to load thedrawing state machine with a long set of commands, and then have it dumpthem all onto the video buffer.
For example, when drawing multiple lines, it's more efficient to create onepath with all the lines in it and draw it with a single draw call. In otherwords, rather than drawing separate lines:
We get better performance from drawing a single polyline:
This applies to the world of HTML5 canvas as well. When drawing acomplex path, for example, it’s better to put all of the points into thepath, rather than rendering the segments separately(jsperf).
Note, however, that with Canvas, there’s an important exception to thisrule: if the primitives involved in drawing the desired object havesmall bounding boxes (for example, horizontal and vertical lines), itmay actually be more efficient to render them separately(jsperf):
Avoid unnecessary canvas statechanges
The HTML5 canvas element is implemented on top of a state machine thattracks things like fill and stroke styles, as well as previous pointsthat make up the current path. When trying to optimize graphicsperformance, it’s tempting to focus solely on the graphics rendering.However, manipulating the state machine can also incur a performanceoverhead.
If you use multiple fill colors to render a scene, for example, it’scheaper to render by color rather than by placement on the canvas. Torender a pinstripe pattern, you could render a stripe, change colors,render the next stripe, etc:
Or render all odd stripes and then all even stripes:
The following performance test draws an interlaced pinstripe patternusing the two approaches(jsperf):
As expected, the interlaced approach is slower because changing thestate machine is expensive.
Canvas Draw 5 0 1 – Universal Graphics Tools
Render screen differences only, not the wholenew state
As one would expect, rendering less on the screen is cheaper thanrendering more. If you have only incremental differences betweenredraws, you can get a significant performance boost by just drawing thedifference. In other words, rather than clearing the whole screen beforedrawing:
Keep track of the drawn bounding box, and only clear that.
This is illustrated in the following performance test which involves awhite dot crossing the screen(jsperf):
If you are familiar with computer graphics, you might also know thistechnique as “redraw regions”, where the previously rendered boundingbox is saved, and then cleared on each rendering.
This technique also applies to pixel-based rendering contexts, as isillustrated by this JavaScript Nintendo emulator talk.
Use multiple layered canvases for complexscenes
As mentioned before, drawing large images is expensive and should beavoided if possible. In addition to using another canvas for renderingoff screen, as illustrated in the pre-rendering section, we can also usecanvases layered on top of one another. By using transparency in theforeground canvas, we can rely on the GPU to composite the alphastogether at render time. You might set this up as follows, with twoabsolutely positioned canvases one on top of the other.
The advantage over having just one canvas here, is that when we draw orclear the foreground canvas, we don’t ever modify the background. Ifyour game or multimedia app can be split up into a foreground andbackground, consider rendering these on separate canvases to get asignificant performance boost. The following graph compares the naivesingle canvas case to one where you merely redraw and clear theforeground (jsperf):
You can often take advantage of imperfect human perception and renderthe background just once or at a slower speed compared to the foreground(which is likely to occupy most of your user’s attention). For example,you can render the foreground every time you render, but render thebackground only every Nth frame.
Also note that this approach generalizes well for any number ofcomposite canvases if your application works better with a this sort ofstructure.
Avoid shadowBlur
Like many other graphics environments, HTML5 canvas allows developers toblur primitives, but this operation can be very expensive:
The following performance test shows the same scene rendered with andwithout shadow and the drastic performance difference(jsperf):
Know various ways to clear the canvas
Since HTML5 canvas is an immediate mode drawing paradigm,the scene needs to be redrawn explicitly at each frame. Because of this,clearing the canvas is a fundamentally important operation for HTML5canvas apps and games.
Canvas Draw 5 0 1 – Universal Graphics Tool Set
As mentioned in theAvoid canvas state changes section,clearing the entire canvas is often undesirable, but if you must doit, there are two options: calling
context.clearRect(0, 0, width,height)
or using a canvas-specific hack to do it: canvas.width =canvas.width
;.At the time of writing,
clearRect
generally outperforms the widthreset version, but in some cases using the canvas.width
resetting hackis significantly faster in Chrome 14(jsperf):Canvas Draw 5 0 1 – Universal Graphics Toolbox
Be careful with this tip, since it depends heavily on the underlyingcanvas implementation and is very much subject to change. For moreinformation, see Simon Sarris' article on clearing the canvas.
Avoid floating point coordinates
HTML5 canvas supports sub-pixel rendering, and there’s no way to turn itoff. If you draw with coordinates that are not integers, itautomatically uses anti-aliasing to try to to smooth out the lines.Here’s the visual effect, taken fromthis sub-pixel canvas performance article by Seb Lee-Delisle:
If the smoothed sprite is not the effect you seek, it can be much fasterto convert your coordinates to integers using
Math.floor
orMath.round
(jsperf):To convert your floating point coordinates to integers, you can useseveral clever techniques, the most performant of which involve addingone half to the target number, and then performing bitwise operations onthe result to eliminate the fractional part.
The full performance breakdown is here(jsperf):
Note that this sort of optimization should no longer matter once canvasimplementations are GPU accelerated which will be able to quicklyrender non-integer coordinates.
Optimize your animations with`requestAnimationFrame`
The relatively new
requestAnimationFrame
API is the recommended way ofimplementing interactive applications in the browser. Rather thancommand the browser to render at a particular fixed tick rate, youpolitely ask the browser to call your rendering routine and get calledwhen the browser is available. As a nice side effect, if the page is notin the foreground, the browser is smart enough not to render.Canvas Draw 5 0 1 – Universal Graphics Tool Kit
The
requestAnimationFrame
callback aims for a 60 FPS callback rate butdoesn’t guarantee it, so you need to keep track of how much time passedsince the last render. This can look something like the following:Note that this use of
requestAnimationFrame
applies to canvas as well asother rendering technologies such as WebGL.At the time of writing, this API is only available in Chrome, Safari andFirefox, so you should use this shim.
Most mobile canvas implementations are slow
Let’s talk about mobile. Unfortunately at the time of writing, only iOS5.0 beta running Safari 5.1 has GPU accelerated mobile canvasimplementation. Without GPU acceleration, mobile browsers don’tgenerally have powerful enough CPUs for modern canvas-basedapplications. A number of the JSPerf tests described above perform anorder of magnitude worse on mobile compared to desktop, greatlyrestricting the kinds of cross-device apps you can expect tosuccessfully run.
Conclusion
To recap, this article covered a comprehensive set of usefuloptimization techniques that will help you develop performant HTML5canvas-based projects. Now that you’ve learned something new here, goforth and optimize your awesome creations. Or, if you don’t currentlyhave a game or application to optimize, check outChrome Experiments and Creative JS for inspiration.
References
- Immediate mode vs. retained mode.
- Other HTML5Rocks canvas articles.
- The Canvas section of Dive into HTML5.
- JSPerf lets developers create JS performance tests.
- Browserscope stores browser performance data.
- JSPerfView, which renders JSPerf tests as charts.
- Simon's blog post on clearing the canvas, and his book, HTML5 Unleashed which includes chapters on Canvas performance.
- Sebastian's blog post on sub-pixel rendering performance.
- Ben's talk about optimizing a JS NES emulator.
- The new canvas profiler in the Chrome DevTools.