valueerror Posted October 21, 2014 Share Posted October 21, 2014 Because a new thread on this topic pops up every 2 to 3 days in this forum I would like to fill this thread (this first post to be precise) with tips and tricks to maximize mobile performance or things you should probably avoid if targeting mobile devices. I totally rely on your support because my own knowledge on this topic is quite limited. giving explanations(why a tip actually works), pointing out errors in this post, and new tips to fill this post would be very appreciated. (i don't want to spread false "knowledge" ) thx in advance ! P2:polygon shapes will be more expensive than simple circles - especially huge polygons (keep them simple)enabling p2 impactEvents is expensive - use onBeginContact insteadhaving a bunchload of revolute constraints seems to be expensive Arcade:don't call game.physics.arcade.collide 20 times in the update loop.. try to do the same thing with 5 calls ;-) Both (general programming) :reuse sprites whenever possible - create multiple / kill and revive them (e.g. bullets)be careful with the resolution of your game 640x480 will run faster than 1024x768keep physics simple instead of "game.time.now" use "game.time.time" or one of the physicsElapsed values, as "now" can often contain high precision timer values (depending on the browser)arcade is faster than p2rendering normal text is expensive, using bitmap-fonts seems to be better but is still somehow heavy on mobile using tilemaps with more than 2 layers is going to be slow (depending on your device) - try the new tilemap pluginhuge tilemaps will be slowwhen using webGL use a sprite atlas that contains all your sprites instead of many different image files.make use of the particles system - but not to much ^^ (it may be better to use the particlesystem than to create all particles "by hand" but spawning particles will cause a frame drop on slow devices)try to keep the update loop simple - do not call a function 60 times a second if not definitely neededmake sure the garbage collector can free some memory - use var ^^make sure the garbage collector doesn't have too much to do - don't create new objects all the time (functions are treated in the same way) and finding the balance between to much and to little is the trickdon't use the native webview (especially on older android versions) - use a wrapper (like cocoonjs) or use intel crosswalk (which builds on chromium)intel crosswalk seems to run much better with webgl enabledcocoonjs seems to run much better in canvas modedo not use splice. If you have only one element to cut off an array, use this function, which is multiple times faster that the build in one, and aside it low GC (the built in is the opposite!): 1-item-spliceusing a lot of tweens in parallel can cause lagsusing Prototype simply slows down things. It's faster to use precached functions.do not use classes, no new, no prototype, no this, track length by yourself, use custom splice or avoid it completely by using double linked liststweens that start on creation of a state will be choppy.. use game.time.events.add(1, fadeIn); to delay the tween (it seems that game.time.events will not start before everything is loaded) michaelcalkins, george, shohan4556 and 2 others 5 Link to comment Share on other sites More sharing options...
SolarJS Posted October 22, 2014 Share Posted October 22, 2014 Well, there are a lot of things you should take care for when programming. To get the highest FPS you should especially know how to handle animations and sprites. The second big point is writing your code in a way the browsers can convert it to native code easyly. Third, garbage collection, is hardest to handle since this mostly interferes with performance and you have to find a good way to combine both. But it all leads to one thing: profile, research, optimize, start again. A good example is splice. If you have only one element to cut, use this function, which is multiple times faster that the build in one, and aside it low GC (the built in is the opposite!): 1-item-splice Tilde 1 Link to comment Share on other sites More sharing options...
valueerror Posted October 22, 2014 Author Share Posted October 22, 2014 Well, there are a lot of things you should take care for when programming. To get the highest FPS you should especially know how to handle animations and sprites. The second big point is writing your code in a way the browsers can convert it to native code easyly. Third, garbage collection, is hardest to handle since this mostly interferes with performance and you have to find a good way to combine both. But it all leads to one thing: profile, research, optimize, start again. A good example is splice. If you have only one element to cut, use this function, which is multiple times faster that the build in one, and aside it low GC (the built in is the opposite!): 1-item-splice well that's the point. if you don't know how to optimize and what you just can't do it.. could you give some examples on "how to handle sprites/animations" or "what is browserfriendly code" (or provide some useful links to explanations) ? Link to comment Share on other sites More sharing options...
SolarJS Posted October 22, 2014 Share Posted October 22, 2014 Well, it's mostly in my head due to lot's of experience and it's also mainly focused on mobile. It's mainly build on such things as how you write your code, like this hint: don't use prototypeIt's also important to know that a lot of tutorials out there are simply outdated or wrong. For example in one tutorial on HTML5Rocks it is recommended to use an object pool to lower GC (which is correct). However, in the next step implementations or shown, which are dead wrong! Never ever use an array with pop() and push() to pool your objects, GC will punish you for this for sure ;-) But it is also important to know that a lot of things are only important to know if you build a game / engine completely by your own and target 60fps on mobile / want to get the performance advantage. For most games this massive optimizing is not needed (like Mahjong, smaller games etc.). But beginning with Samsung S3 (Chrome) & iPad 2 you are able to boost your games, even arcade ones, to 60fps without a wrapper and by using plain 2D canvas in HTML5. Maybe I should write a tutorial... Tilde and valueerror 2 Link to comment Share on other sites More sharing options...
defic Posted October 29, 2014 Share Posted October 29, 2014 Please do write one. I am interested in this topic and I don't have a lot of experience with Phaser or javascript in general. What does GC mean? also I used this https://github.com/tutsplus/Monster-Wants-Candy-demo for a reference when I was figuring out how to implement states and it is using prototyping. Is this bad? What does precached function mean? Link to comment Share on other sites More sharing options...
SolarJS Posted October 29, 2014 Share Posted October 29, 2014 I will do so for sure, but don't know when. Some hints can be found in the link below. GC means garbage collection. It means the browser tries to find out which memory isn't used anymore and cleans it up. This can be a heavy job to do.Depending prototyping, try to avoid using it. It simply slows things.Precached function mean you do not declare your function in an object or a class, but rather outside and just link them in the object or class. This is also a nice performance boost if used correctly. However, you should always try to find the parts that take most of your time in your engine. And optimize only that. Optimizing function being only called once or don't eat up much CPU time are not worth the effort. Link to comment Share on other sites More sharing options...
Sam Posted October 30, 2014 Share Posted October 30, 2014 I'm developing mostly in CocoonJS for iOS.There it themes that the particle system slows everything down - extremely. Particle System: SlowiPad Air / iPad Mini, same result: If you use an particle system effect you get lost a lot of FPS.As more complicated the graphics or amount of particle are the slower the game runs. Bitmaps: Very SlowBitmaps. We are now avoiding the use of any kind of bitmaps. Because indifferent for which kind you use it, it slows everything down.Backgrounds, Bitmap font, gradients... only one bitmap causes a few fps.. WebGL: System crasheswe also running cocoonJS in Canvas-Mode. With WebGL we had a lot of crashes and rarely total system crashes of iOS 7 & 8.with Black Screen and no reaction of the device for about 5 - 10 Minutes. Tweenings: laggingOne problem that we were not able to solve is that if you use a few tweenings parallel: All devices which are not at the hardware level of the iPad Air are lagging for a few fps.Hope that helps. Well, it's mostly in my head due to lot's of experience and it's also mainly focused on mobile. It's mainly build on such things as how you write your code, like this hint: don't use prototype That's interesting and one thing we haven't approached yet. It would be very nice if you give some more informations about that. Link to comment Share on other sites More sharing options...
SolarJS Posted October 30, 2014 Share Posted October 30, 2014 I don't know how CocoonJS handles bitmaps, but nowadays bitmaps do not slow down browsers so much, if used properly. I for example use 3 fullscreen-parallax planes about 130 vector polygons and roughly 120 additional bitmap objects. All move in 60fps on iPad 2. Prototype simply slows down things. It's 4x faster to use precached functions. Avoiding classes alltogether increase speed even more. I for example do not use classes, no new, no prototype, no this, track length by myself, custom splice or avoid it completely by using double linked lists etc. So setting up on an engine means always you should know where the strengths and weaks are. Link to comment Share on other sites More sharing options...
valueerror Posted October 30, 2014 Author Share Posted October 30, 2014 how do you create your text without bitmap fonts ? loading "hardcoded" graphics that contain the text? Link to comment Share on other sites More sharing options...
SolarJS Posted October 30, 2014 Share Posted October 30, 2014 No hardcoded text, I want to be free to change the text fast and also support many languages. I use bitmap fonts created with http://kvazars.com/littera/ Link to comment Share on other sites More sharing options...
valueerror Posted October 30, 2014 Author Share Posted October 30, 2014 i use that tool too.. but sam said they do not use bitmap fonts anymore so i was courious.. what are they using instead? Link to comment Share on other sites More sharing options...
valueerror Posted October 30, 2014 Author Share Posted October 30, 2014 ad. particle emitters: if i trigger a bunch of particles to explode on contact with a specific object it slows down the game dramatically on mobile BUT only the first time.. my 55-60 fps drop to 30... the second time everything is smooth.. (maybe 2-5 fps lost) it seems that i would need to preload them somehow to get rid of this problem.. any ideas? Link to comment Share on other sites More sharing options...
SolarJS Posted October 30, 2014 Share Posted October 30, 2014 I don't know who Sam is, but Littera still generates bitmap fonts. Using anything else (except hardcoded bitmaptext) in a game based environment on mobile is a decision which should be reversed. Because when ever you change a value of a textfield you start a DOM reflow, which forces the browser to repaint / rerender. This leads to such strange things, that the first FPS-tracker module I added (build one by myself after) ate about 10fps on a Samsung S3 Mini, which is crazy for an FPS tracker... Link to comment Share on other sites More sharing options...
SolarJS Posted October 30, 2014 Share Posted October 30, 2014 That may not by bound by your engine, but simply by browser optimization. The browser determines your hot functions and optimizes those. At best all your code is optimized to native code. You could force this also by starting a small particle effect in a non visible are. That may also help and let the browser determine what you want to do. Link to comment Share on other sites More sharing options...
valueerror Posted October 30, 2014 Author Share Posted October 30, 2014 SAM is the one who posted here... 7 posts above ;-) i already hat the same experience with normal text (and my fps tracker) lol so you implemented your fps tracker with bitmap fonts? SolarJS 1 Link to comment Share on other sites More sharing options...
Sam Posted October 30, 2014 Share Posted October 30, 2014 Only for those who use CocoonJS.You can simply use an .ttf font into the ./font folder and preload it via <style> @fontface ....</style> in your index.html.Since then you can use this font in game.I embed my fonts always like this and there are no FPS changes.So for those who use cocoonJS, this would be a good alternative to other implementations. the Particle System depends on the amount,let's say I use 3 particle effects which are all creating 20 1px * 1px sprites a second. that drops my fps dramatically.Even the phaser examples of particle effect do - and after a few seconds the fps got slower and slower.() Link to comment Share on other sites More sharing options...
SolarJS Posted October 30, 2014 Share Posted October 30, 2014 @valueerrorLOL, sorry, missed the name, sorry ;-) @samIf you include TTF fonts in CocoonJS then they are handled as TTF fonts. So you slow your game down with them, especially on Android. Have you tried disabling them (if you used them)? I could only recommend to not use TTF fonts, only bitmap font, if you target fast games. Link to comment Share on other sites More sharing options...
defic Posted October 30, 2014 Share Posted October 30, 2014 Thanks for the explanation However, I am still having hard time understanding the "prototyping vs precached functions". Here is an example of my code:BallObject = function(game, x, y) { Phaser.Sprite.call(this, game, x, y, 'basketball'); this.game.physics.p2.enable(this); game.add.existing(this); this.body.setCircle(31); this.body.mass = 10; this.body.damping = 0.0; this.body.data.gravityScale = 1; this.inputEnabled = true; this.events.onInputDown.add(function(){ game.ball = this; game.touchdown = true; }, this); this.events.onInputUp.add(function(){ game.touchdown = false; this.launch(this.getLaunchForceX(),this.getLaunchForceY()); game.firstBall = false; }, this);};BallObject.prototype = Object.create(Phaser.Sprite.prototype);BallObject.prototype.constructor = BallObject;BallObject.prototype.launch = function(Xvelocity,Yvelocity){ this.body.velocity.x = Xvelocity; this.body.velocity.y = Yvelocity;};BallObject.prototype.getLaunchForceX = function(){ return -(game.input.x - this.x) * 5;};BallObject.prototype.getLaunchForceY = function(){ return -(game.input.y - this.y) * 5;};The code is just for throwing basketballs. How should I to change the code to gain better performance (precached functions)? Link to comment Share on other sites More sharing options...
Sam Posted October 30, 2014 Share Posted October 30, 2014 @valueerrorLOL, sorry, missed the name, sorry ;-) @samIf you include TTF fonts in CocoonJS then they are handled as TTF fonts. So you slow your game down with them, especially on Android. Have you tried disabling them (if you used them)? I could only recommend to not use TTF fonts, only bitmap font, if you target fast games.Thanks for the reply If have used Bitmap fonts (only developing for iOS), but it was damn slow. Then changed to TTF and it went fast. Maybe I have made something wrong?But I get much more performance with the ttf solution. (only relating to iOS) Link to comment Share on other sites More sharing options...
hellspawn_bg Posted November 14, 2014 Share Posted November 14, 2014 Thanks for the explanation However, I am still having hard time understanding the "prototyping vs precached functions". Here is an example of my code:BallObject = function(game, x, y) { Phaser.Sprite.call(this, game, x, y, 'basketball'); this.game.physics.p2.enable(this); game.add.existing(this); this.body.setCircle(31); this.body.mass = 10; this.body.damping = 0.0; this.body.data.gravityScale = 1; this.inputEnabled = true; this.events.onInputDown.add(function(){ game.ball = this; game.touchdown = true; }, this); this.events.onInputUp.add(function(){ game.touchdown = false; this.launch(this.getLaunchForceX(),this.getLaunchForceY()); game.firstBall = false; }, this);};BallObject.prototype = Object.create(Phaser.Sprite.prototype);BallObject.prototype.constructor = BallObject;BallObject.prototype.launch = function(Xvelocity,Yvelocity){ this.body.velocity.x = Xvelocity; this.body.velocity.y = Yvelocity;};BallObject.prototype.getLaunchForceX = function(){ return -(game.input.x - this.x) * 5;};BallObject.prototype.getLaunchForceY = function(){ return -(game.input.y - this.y) * 5;};The code is just for throwing basketballs. How should I to change the code to gain better performance (precached functions)? @defic. My code also looks like that and I am interested how to go with the pre-cached functions. @SolarJS: Perhaps you can show an example, based on the code above? Thanks Sam 1 Link to comment Share on other sites More sharing options...
SolarJS Posted November 14, 2014 Share Posted November 14, 2014 Sure, here's how it's done above:classABC = function () {}classABC.prototype.myMethod1 = function () { console.log('myMethod'); } classABC.prototype.myMethod2 = function () { console.log('myMethod2'); }Now change this to: var myMethod1F = function () { console.log('myMethod1'); };var myMethod2F = function () { console.log('myMethod2'); };classABC = function () { return { myMethod1: myMethod1F, myMethod2: myMethod2F } }You might also consider to leave classes at all, if you don't have many balls to handle or do other fancy stuff with it. Know your tools ritherz 1 Link to comment Share on other sites More sharing options...
valueerror Posted November 14, 2014 Author Share Posted November 14, 2014 one simple (general) javascript programming question that came to my mind because of the post above: is there a difference between : var myMethod1F = function () { }andfunction myMethod1F() { }or is it just different notation for the exact same thing ? does this affect memory management in some way? Link to comment Share on other sites More sharing options...
lewster32 Posted November 14, 2014 Share Posted November 14, 2014 In simple terms, the second method will ensure that function can be called regardless of where it's placed in your code, whereas the first method will mean that anything executed before will give 'undefined' if you try to call the function. See this example: http://jsfiddle.net/lewster32/s1p1bcb8/ Link to comment Share on other sites More sharing options...
hellspawn_bg Posted November 14, 2014 Share Posted November 14, 2014 Sure, here's how it's done above:classABC = function () {}classABC.prototype.myMethod1 = function () { console.log('myMethod'); } classABC.prototype.myMethod2 = function () { console.log('myMethod2'); }Now change this to: var myMethod1F = function () { console.log('myMethod1'); };var myMethod2F = function () { console.log('myMethod2'); };classABC = function () { return { myMethod1: myMethod1F, myMethod2: myMethod2F } }You might also consider to leave classes at all, if you don't have many balls to handle or do other fancy stuff with it. Know your tools Thank you very much SolarJS. Your sample was really helpful, but what about inheritance? In the first case we can inherit Phaser.Sprite like this:BallObject = function(game, x, y) { Phaser.Sprite.call(this, game, x, y, 'basketball');};BallObject.prototype = Object.create(Phaser.Sprite.prototype);BallObject.prototype.constructor = BallObject;What would be the analog in the second method? Thank you once again. Link to comment Share on other sites More sharing options...
d0nkeykong Posted November 14, 2014 Share Posted November 14, 2014 Thank you very much SolarJS. Your sample was really helpful, but what about inheritance? In the first case we can inherit Phaser.Sprite like this:BallObject = function(game, x, y) { Phaser.Sprite.call(this, game, x, y, 'basketball');};BallObject.prototype = Object.create(Phaser.Sprite.prototype);BallObject.prototype.constructor = BallObject;What would be the analog in the second method? Thank you once again. I am curious about this too. I am also using this method to extend Phaser.Sprite.What alternatives can we use here? Thanks for the tips so far. Link to comment Share on other sites More sharing options...
Recommended Posts