html5 canvas general performance tips - javascript

I am developing a game for html5 canvas while mainly targeting mobile devices. The canvas is resized to the biggest available resolution, so that it almost makes a fullscreen game.
On an ipad that would be a 1024x786 canvas; at a resolution like this I notice a significant drop in framerate. On smaller resolution like 480x320 on iphone the game runs smooth! I guess this is because the device is fillrate limited.
Anyhow I would like to optimize as much as possible. I would be very grateful if you could post any general performance tips that you have for html5 canvas development.

Also see this canvas performance optimization article on html5rocks, which contains jsperf data which includes mobile browsers.

You can read Making an iPad HTML5 App & making it really fast by Thomas Fuchs
The key points he make:
Images slow things down immensely– get rid of them
Avoid text-shadow & box-shadow
Hardware-acceleration is quite new… and buggy (concurrent animations is limited)
Avoid opacity if possible (sometimes interferes with hardware-accelerated rendering)
Use translate3d, not translate (the latter is not hard-accelerated)
Some other points that can improve performance significantly:
use getImageData as infrequently as possible (major slowdown) [2]
combine more than one canvas in order to repaint smaller parts that are changing more frequently
You can also benchmark your app with Chrome/Firebug Profile can show you which functions are slow.
[2] http://ajaxian.com/archives/canvas-image-data-optimization-tip

A couple of more links:
HTML5 Games 0.2: Integers are Your Friends
HTML5 Canvas Performance in deviantART muro
Game Engine Listing. See esp. "Other" for extra links.
It's hard to give any specific tips as I'm not familiar enough with your game. You might want to split up rendering to multiple layers, though. This makes sense particularly if you have some static elements there. This way you can avoid some clearing and end up with nicer code overall.

Related

Is WebGL or Canvas the only way to get SVG Keyframe Animations Hardware Accelerated?

What I'm looking is a flash alternative for mobile phones using html5.
I was looking into SVG and it seems the only way to get hardware acceleration is to use CSS transforms on it. But CSS transforms aren't enough, I want to animate the actual nodes that make up a vector (ie, points on a path) so I could get more sophisticated character animation. To do this I was looking at some gui based editors.
I checked what adobe has been up to and they seem to have killed Edge Animate and rebranded Flash as "Animate CC" for 2016.
http://blogs.adobe.com/creativecloud/update-about-edge-tools-and-services/
https://blogs.adobe.com/flashpro/welcome-adobe-animate-cc-a-new-era-for-flash-professional/
But reading up on "Animate CC" I see that it exports vector animations to either Canvas or WebGL. Which I think is due to them not getting hardware acceleration with native SVG via SMIL or using javascript.
https://css-tricks.com/guide-svg-animations-smil/
Another one is http://www.animatron.com which converts everything to canvas as well.
So my question is, in order to do keyframe animations on nodes within a vector path, a vector needs to be converted to either WebGL or Canvas for it to be hardware accelerated on mobile?
p.s I prefer using SVG as it's loaded in the DOM and I can manipulate things with jquery. This is for a mobile game that uses vectors (svg) as its base but I'd like to incorporate animations too - beyond the basic css transforms. I wish there was a way to have a .svg file that not only contains the vector information but also the animation info. so I could load this .svg file. and then in javascript go:
character1.play('animation1') or something. If SMIL worked fast I'm sure editors like adobe would make it as simple as that.
EDIT: I just read that Chrome 45 killed SMIL in favor of "web animations" and css.
https://developer.mozilla.org/en-US/docs/Web/SVG/SVG_animation_with_SMIL
And as Kaiido mentioned in the comments IE never supported smil so maybe that's why adobe never exported to it (?).
http://caniuse.com/#feat=svg-smil
also I never saw any examples online that show hardware accelerated path animation with smil, if any of you guys find a link pls let me know.
EDIT #2: I'm thinking of giving up my wishful thinking and instead looking at vector to canvas exporters like animatron.com. However, it doesn't seem like canvas is even hardware accelerated or fast like css3 transforms. I loaded some animations from animatron in my old iPhone 4s/iOS 8 and it's jittery and slow for example:
https://www.animatron.com/project/1953f3526e5b2ec4eef429c8
whereas css3 transform animations always run very smooth...
I still haven't tested vector to webgl.. but I think that's why adobe eventually chose to use it for their vector animations since canvas is slow and svg is limited.
EDIT #3: sure enough it seems like webgl is the way to go (unless someone finds a way to do this with native svg) http://www.yeahbutisitflash.com/?p=7231 .. this works fast in my iphone 4s/ios8.. I currently think this is the only way to do what I want: hardware accelerated vector based animation (however the graphics don't look as crisp as I'd want them.. webgl kinda messed with that I think).
but this is why I think Edge Animate got killed cause they were trying to create a tool that took advantage of css3 transforms, but ppl want to animate vector nodes so they went back to Flash and rebranded it. (another note: the above webgl anim doesn't work so well on my galaxy S4/kitkat android phone.. so this is mainly for newer devices/OSs)
EDIT #4: come to think of it. it'd be a pain to have multiple webgl contexts running in my program. so if I had 10 animated characters I'd have to have 10 webgl contexts which would be intense for a mobile device.. unless I chose to do the whole game in flash, and then I'd have one big webgl context after I export it. but I prefer to work in the dom. oh well css3 transforms for the meantime.. :/
EDIT #5 - Dec 2016: I'm now using svg/javascript with snap.svg. modern phones seem fast enough.
Other Useful Links I Found:
http://www.crmarsh.com/svg-performance/
Canvas is (as far as i know) software accelerated. So it's rendered by the processor (CPU). The processor (cause of them pixels) ain't that good at graphical stuff but for simple things it would be enough. And it runs everywhere, where there is a processor.
If you want to have better performance on hardware accelerated devices which most modern smartphones are, you need webgl. But you can export your stuff in webgl from adobe CC. Older smartphones are not very optimized on hardware acceleration so please check with your target group what devices they have and try to run your app on one of the slowest devices.
I would not use SVG. SVG is even worse than DOM. You can be faster manipulating HTML in javascript than SVG. I don't know why but it is damn slow. SVG is just an alternative if you want to have scalable graphics or charts and that's what it is made for. To animate in SVG is a pain. Don't do it. It is not optimized for animation.
CSS-Transform is a prototype-like and will not help you with keyframe animation. But it has potential to have an eye on it.
Does this help you?
This library/plugin might be exactly what you are looking for: Greensock SVG Morph Plugin. It seems to perform pretty well on mobile, not sure how well it performs on devices mentioned by you.
It's also not GPU accelerated but Greensock Animation Platform seems to perform extremely well even on mobile devices.
I think its a difficult question to answer as there's so many issues with different browsers. Some don't support SMIL transforms well (or being deprecated, but as mentioned there are fills for it), some don't support CSS3 transforms on SVG elements at all, so most of the 'solutions' out there, have some issue that may need to be compromised on. I think one browser doesn't support d attribute morph properly, but I can't recall which (so test this early on with required browsers if you do go down this route).
Canvas does typically seem to perform better on mobile for most animation I've seen or played with, certainly as the number of objects increases on page.
Other alternatives to webGL that was mentioned..
One option that kinda springs to mind is fabric.js, which is a canvas approach to SVG. It will take the same commands, elements as SVG, but display it on an HTML5 canvas. Turn off drag/freetransform within it (as I think its slowed down a bit with this if it needs extra checks), and I think it will be a bit faster, but its a while since I've played. This could be an interesting approach if you don't need specific DOM element access, but would be fine if you are ok with a similar object based setup.
If you insist on using SVG, then I would look at integrating it with another library (or even 2). Snap or SVG.js are both decent, but can be a bit slow. However, I would experiment with using Velocity.js or React.js with that svg library, as they have some methods that can squeeze out a bit more performance. Also GSAP may be worth a look.
There is no general answer to this, it depends on the browser implementation and your hardware, but ... for the long term solution I would bet on WebGL because it uses the GPU and will ultimately dominate.
WebGL is not well supported right now (2016), and it potentially comes with security issues.
Also see: https://css-tricks.com/rendering-svg-paths-in-webgl/
Canvas is better at working on raw 2d pixel buffers (+ alpha channel) and is slow for higher resolution+animation.
You could use some dual lib like Pixi though.
If you don't mind the k-weight increasing a bit and are comfortable using flash, the easiest and the fastest solution would be to use Animate CC (It's exactly Flash, without the symbol filters and gives canvas output instead of swf).

Most efficient way to draw particles in HTML5 on iPad 2

I'm trying to create moving lights with trails for an HTML5 website/app targeted at iPad 2.
I wonder what the best way to do this is and whether using HTML5 is viable at all. I chose HTML5 because it's easier and cheaper to develop and deploy than native iOS apps with Objective C. Of course if it turns out that HTML5 simply doesn't offer enough performance I might have to swallow the bitter pill.
Anyway to give you an impression what I'm talking about, this is what I got so far:
screenshot http://devdali.no-ip.org/mathias/test-lights/screenshots/1.jpg
Or you can see it in action here (only works in webkit based browsers).
At first I tried using HTML5 canvas and drawing radial gradients as particles in similar manner you see above. It worked but the framerate was horrible even on my desktop computer!
So after a bit of reading I found out that CSS3 transforms may be hardware accelerated, so I build the version you see above. Every "particle" is a 64x64 png image. For each light there is the "head" light (one img) followed by a trail consisting of 115 img elements. Each img element is transformed using "translate3d" (as well as scale and rotation). Also the opacity of each element is adjusted dynamically.
Doing it this way provided much better framerates on my computer, but I doubt the iPad 2 will handle it.
I'd be grateful if anyone could give me some hints on how to improve the performance of this in general and considering the target platform.
Thanks for any help in advance!
If you accept small changes to the effect, some other procedure may work fast:
Instead of drawing the light's trails by the means of many particles, just draw the lights in their current positions in a Canvas element.
You can then darken the whole image at the beginning of a frame by filling a black rectangle with a very low opacity on top. This way the trails fade into dark, but would not alter their color like they do now.
The amount of drawing operations however will reduce vastly. The most costly operation would be filling the fading rectangle for every frame.
This should be built in the canvas. Check out EaselJS and this demo.
http://easeljs.com/
http://easeljs.com/demos/MusicVisualizer/index.html
You could optimize performances a LOT by using WebGL(, which is supported on the iPad2.)... which is not supported for basic html pages on ios safari as stated Nison Maël...
For the time being you only have canvas as a solution. Which will still give you better performances...
(You can check this blog for more info:
http://learningwebgl.com/blog/
With a little faith and time you'll be amazed!)

What's the best solution for rendering a javascript game in Browser (complete viewport)

I think there are two diffrent solutions for the problem:
1) First the solution shown by aves Engine, which renders the whole game with html elements and external stylesheets e.g. CSS3 transfomations. Pro's are that the event-handling is much easier when working with div's than by rendering on canvas.
2) Like isogenicengine.com shows you could render the game on html5 canvas element. Mabye that's the better solution, because rendering on canvas is the way that millions of 2D-games were written before and in future the industry will optimize the drawing methods e.g. with hardware acceleration. At the moment the contra is that rendering on canvas is slow if you would like to render in fullscreen. If you would like to render only in a specific area of 200x200px that's okay, but in fullscreen you get stuck with a framerate of 10fps.
What do you think is the better way to create a game for the web?
Thanks for your opinion!
PS: If you have some articles about the topic please paste some links
I don't think it's a clear one size fits all kind of thing. I really think it depends on what you want to do with your game.
If you are doing a lot of vector graphic manipulation, perhaps canvas is a better choice vs engine like aves. For tiled based, maybe aves will work better.
You can render fast on fullscreen canvas if you're clever about only re-rendering dirty regions. But if your whole canvas needs to change every frame this obviously isn't going to help much.
I've spent alot of time recently looking into this issue and my conclusion is pretty simple.
Use HTML Elements, lets say that HTML5 actually makes progress and in one year the major browser support it. How long does it then take to get the general user base of the web on the latest browser (IE6 still has a choke hold in some sectors). So making the game available to as many people as possible is key! (In my mind anyways)
If however, your looking to learn and develop, go with canvas.

What's the speed difference between drawing with html5 canvas and html and javascript?

I'm interested in making a game using html and javascript. I was wondering if it really is that much faster drawing in html5 and javascript than it is with images and div's in html and javascript.
Example of a game using html and javascript that works nicely:
http://scrabb.ly/
Example of a game using html5 and javascript that works nicely:
http://htmlchess.sourceforge.net/demo/example.html
I've run a bunch of numbers on HTML-made drawing versus Canvas-made drawing. I could make a huge post about the benefits of each, but I will give some of the relevant results of my tests to consider for your specific application:
I made Canvas and HTML test pages, both had movable "nodes." Canvas nodes were objects I created and kept track of in Javascript. HTML nodes were <div>s, though they could be <image> or <video> too.
I added 100,000 nodes to each of my two tests. They performed quite differently:
The HTML test tab took forever to load (timed at slightly under 5 minutes, chrome asked to kill the page the first time). Chrome's task manager says that tab is taking up 168MB. It takes up 12-13% CPU time when I am looking at it, 0% when I am not looking.
The Canvas tab loaded in one second and takes up 30MB. It also takes up 13% of CPU time all of the time, regardless of whether or not one is looking at it.
Dragging on the HTML page is smoother, which I suppose is expected, since the current setup is to redraw EVERYTHING every 30 milliseconds in the Canvas test. There are plenty of optimizations to be had for Canvas for this. (canvas invalidation being the easiest, also clipping regions, selective redrawing, etc.. just depends on how much you feel like implementing)
Video on the HTML page, while I am not moving objects, is actually perfectly smooth.
On canvas the video is always slow, since I am redrawing constantly because I turned off my drawing canvas invalidation. There is of course plenty of room for improvement.
Drawing/loading alone is far faster in Canvas and has far more room for optimizations, too (ie, excluding things that are off-screen is very easy).
Fast as in faster rendering or faster development? I would say the answer to both is HTML5 canvas. Although it is a fairly new technology, and not even supported by all mainstream browsers yet, it already has much more functionality than you would have using DIVs with normal HTML. I've done drawing with divs before and it was incredibly frustrating just getting something to work. With canvas you already have a framework in place to do most basic drawing. Furthermore, html5 is new. Even if it is relatively slower than drawing with divs right now (which it probably isn't), that performance will increase as development and adoption increases. I can't say the same for drawing with divs.
Pros to using HTML5 Canvas:
Similar to other drawing frameworks (OpenGL, DirectX)
Will continue to increase in performance and functionality
May become hardware accelerated in the future
Possible 3D framework in the future
Neither of those games requires HTML 5. scrabb.ly does everything with rectangular objects, which divs handle just fine, and the chess game doesn't even use animation. If that's the kind of game you're thinking of building, then what you use should be decided on the grounds of familiarity and compatibility rather than performance.

What would be quicker Flash or Javascript?

I have an idea for a website which involves a canvas area which has no limit to its size. Basically you would be able to add items to the canvas (notes, photos whatever really). You would then be able to drag the canvas which would move those items along with the canvas until they disappear of screen. If you dragged the canvas back the other way they would appear again.
Question:
Which would be the best suited to this type of thing, Flash or Javacsript?
My main worries are the speed at which javascript/ flash could handle moving multiple items around on screen in the way discribed. Which language would handle better for a user on a slow machine.
UPDATE:
Thanks for your opnions guys, but to clarify what are the benefits of canvas over straight jQuery DOM manipulation? or visa versa. I've never used canvas before.
I don't think this is a question that will get you an objective answer - Flash developers will tell you Flash is better, web developers will say JavaScript. Trying to remain objective, I'd say that both technologies are suitable for what you describe, but have different advantages.
Flash will definitely render faster, even on slow machines, and is much richer graphically.
JavaScript is more accessible and works on a greater number of devices. Use a good JS framework though.
My initial thought would be to go with Javascript - if it's good enough for Google Maps, it's probably good enough for your app too.
Do you need to use canvas, what you're describing could be done with just javascript and the DOM. It would perform perfectly well unless there are a huge number of elements and it would be cross-browser compatible. For canvas you would require exCanvas to support IE which can sometimes slow things down.
The best way would surely be Javascript. And I would even say that you should reconsider the use of canvas. It sounds like it could be done in pure DHTML. In that way you wouldn't lose support for IE.
Consider using one of the javascript frameworks; Prototype or jQuery come to mind. It will ease your coding immensely. Given the development in javascript-engine performance (next versions of Webkit (Squirrelfish Extreme) and Mozilla (TraceMonkey) will be lightning fast) the worries about performance may be moot.
Also if you decide that you can't do it without canvas consider using John Resig's processing.js.
I'd say go with flash (or DOM if you don't need the extra punch). Here's my reasoning:
You can do cool transformations with canvas (skewing, rotations, gradient fade-ins in images, reflection effects, etc) that you can't with DOM. The downside is that doing these cool things is math heavy.
Canvas doesn't work in IE. IE's equivalent (VML) apparently has a root-access security hole.
The DOM has been around for longer than canvas and since it's more widely used (and depended upon), it's more optimized and polished than canvas.
The Flash community has a lot of good free components available that may already do what exactly you want.
Flash and DOM have a lot of good documentation and tutorials, canvas not so much.
Flash can do pretty much everything that the DOM and canvas can, plus audio, video and grabbing input from your web cam.

Categories

Resources