So Im tinkering around making an old school game for fun using the canvas. Firefox is slow, but chrome dosent have firebug, which I find almost a requirement when developing with javascript. So 1st question : how are people developing these complex games without the aid of firebug?
Second question. What are some performance tips that can help the draw functions (or just javascript in general) execute faster? It seems to me that this is the area that is the bottleneck (for firefox at least).
Final question. From experimenting with profiling in firebug, I can see performance gains from what some would call 'bad practices', such as : I have organized code into a list of functions that each do one thing. This runs slower than if I just dump all the code between the beginPath() and closePath(), but doing it that way leads to spaghetti code and is difficult to follow. How do you manage the balance?
I am using 100% Chrome for development and then testing other browsers later.
Chrome has a built in inspector that is (in my opinion) better than firebug. Much easier stack inspection, stepping, and object inspection.
Right click on a page and click "Inspect element." (or press CTRL SHIFT + I)
Then click the "Scripts" tab. You'll see the call stack, scope variables, breakpoints, callstack, etc on the right. Hovering over variables not only lets you see their value but lets you explore their nested values as well.
For your final question - there's nothing wrong with optimisation - the only thing that's bad is premature optimisation. If you've found there's a problem and the only way to solve it is to make your code less readable then you have to make a trade-off between readability/maintainability and performance. If performance is the number one factor then by all means turn your beautifully factored code into ugly spaghetti code. But only after you've exhausted the other options.
Related
I entered a question yesterday and I'd like to change tactics while still keeping the previous thread alive, if possible. (The previous question was concerning variable frame rates in Three.js.)
Rather than address the question directly, I'd like to know what WebGL/Three.js developers use to diagnose their code (to find performance bottlenecks specifically).
I'm starting a large-ish, long-term project and I assume I'll run into all sorts of problems along the way. How to we peer behind the curtain?
I saw a related question and came to WebGL-Inspector, which I will look into. Just looking for all the options. I'm willing to spend money to get professional diagnostic tools. Whatever it takes.
Thanks.
Good day, sir.
I use:
chrome javascript profiler
chrome canvas inspection (http://www.html5rocks.com/en/tutorials/canvas/inspection/)
occasionally try tools like webgl-inspector but it doesn't seem quite as good as chrome's canvas inspector
Also:
standard profiling techniques for javascript, use unminified code to see what's going on everywhere during profiling
basic sanity checks: for frame rate issues, make sure your frame flipping run loop code is up to snuff. Standard practice is using requestAnimationFrame.
make sure your canvas is not being stretched
I have not yet tried applying a pure desktop opengl type of debugger (nvidia nsight, for example) to webgl running inside the browser.
From what I can tell about this message, it appears when the driver encounters an error. The implication seems to be that the JavaScript code can't trigger this warning even if there's some kind of mistake in it, because of higher-level error checking.
But my code recently triggered it, just once and I haven't been able to reproduce it (and the code — in theory at least — sends the exact same commands to WebGL every time). So I just want to know if I should be debugging my code (I can't see any obvious errors), or if I should put it down to a hardware random / browser bug.
I can post semi-reduced code on request, but it's still about half a thousand lines and I certainly don't expect people to debug it for me, hence the more general is-it-possible question.
I'm struggling a little with what your question means by "trigger". When this error occurs, javascript is always in the causal chain, because WebGL doesn't run without javascript executing it, right? So certainly it's possible to trigger the error accidentally (unless you always trigger it on purpose, which I'm sure is not the case).
However, graphics drivers are notorious for being affected by many factors that are not under programmer control or necessarily detectable by the programmer, and therefore seem non-deterministic. That's why Google recommends that you try reloading the page when the error occurs. (A link to their guidance was here, but they moved or removed the page.) I've often had Chrome successfully display some WebGL after reloading a page, when the previous attempt ended in the "snag" error. (And I know you're aware of that.)
There are certainly times when WebGL code (like the various shaders on http://shadertoy.com/) work fine on some machines and not others, and work fine one minute and not the next, on the same machine. So that suggests that the "snag" error doesn't necessarily imply that your code is at fault.
However, articles like How to write portable WebGL can help you minimize risky practices in your code, and reduce the frequency of these errors.
I'm very experienced in C/C++/Objective-C and over the last few days have been trying my hand at html/css/JS and am finding it very frustrating.
Time and time and time again I've been caught out as I've a syntax error or undeclared variable due to copying / pasting etc. with the consequence being that the code suddenly stops working then I have to scratch my head and figure out why.
The most painful thing is resorting to sprinkling alerts in the code everything something fails in order to track down the reason. I know there is the new console object for logging but it doesn't seem to work with Komodoedit or jsFiddle? Which is what I've been using.
Is there a way of using these tool, or alternative tools where I can step through the code line by line in a debugger like I can with other languages? Or any tricks for easy detection of problems with the code before executing it in addition to jslint?
[I don't want to use any libraries that might have built-in support for logging etc. as I'm finding they (well JQuery/JQuery mobile is) are drastically slowing down loading times on an iPhone so want to concentrate on pure JS.]
[My target browser is just iOS, but am using Komodoedit with Chrome most of the time and every few hours try it on an iPhone]
Thanks
You need several tools.
First, get yourself a real debugger. I use the one built into Chrome. There's a similar one built into Safari and Firebug available as an add-on for Firefox. This will allow you to set breakpoints and step through your code and see exactly what is happening.
Second, get very used to running your code through jsLint. This will show you many obvious typos and encourage you to write robust code from day one.
Third, start writing in strict mode. This will again prevent some obvious typos and force you to start some good habits.
Fourth, use console.log() when needed. Once you have a debugger, it's output will show in the debug console of the debugger for any page in your browser, including jsFiddle pages. You will have to invoke the debugger on the right frame in jsFiddle and then it will work fine. I use both a regular debugger and console.log() all the time with jsFiddle. It takes a little figuring in jsFiddle and the debugger to find where your own code is to set breakpoints, but once you find it, it's easy to use.
Fifth, javascript is simply not C++. While the syntax will seem quite familiar, the way you do things with anonymous functions and closures and objects and prototypes is very different. As one who programmed in C++ for many, many years before learning javascript, I very much appreciate what I can do now in javascript that was a lot more work in C++, but it took awhile to get my brain into a new mode of thinking. I spent too much time in my first years of javascript development trying to emulate C++ techniques rather than just learning the better way to accomplish the goal in javascript.
Sixth, you will have to change how you write and test code because of the lack of a compiler that finds errors for you. I remember in the days of C++, when I needed to refactor something, I could make a bunch of changes and then let the compiler find all the other places I need to fix the syntax. You can't do that with javascript. When you make mass changes, you can run through jsLint to find some issues and then you literally need to execute every path to make sure everything works. It is a bit of a pain.
Seventh, find a strategy/tools for unit testing. Once a project gets more than a few functions long, you will benefit greatly from building unit tests that you can run anytime you make significant changes. They will both find issues for you in a lot less time than without the unit tests and they will give you the courage to refactor and clean up your code when you see the need for that because you know the unit tests will tell you if everything is working again. It's extra work up front that pays dividends many times over down the road.
Firefox has an add-on called FireBug that is very helpful for debugging CSS/javascript, and yes, it does have the ability to step through a script as well as a command line where you can try out various javascript expressions. I'm pretty sure Chrome has a similar feature.
Here is the article in which you get a list of tools to debug the javascript
advance-javascript-debugging-techniques
Since you're using Chrome, you just need to open the developer console (spanner -> tools -> javascript console, or Ctrl+Alt+J (at a guess)). Instead of sprinkling your code with alerts, use console.log, console.error, and console.info to print to it. All of those are variadic, so you can pass as much to one call as you need.
In addition to this, you can use the console to test and modify parts of your code on the fly, or to just try out a few snippets to see if they work. It's a fully functional REPL that also works with the current document.
In the sources tab of the developer console, you are able to set breakpoints and step through your code, analysing state at each point. This page goes into some detail about it: http://chromedevtools.googlecode.com/svn-history/r421/trunk/tutorials/breapoints/index.html
In the elements tab, you are able to set breakpoints on changes to elements in the DOM, including changes to attributes and child nodes. Right click a node and select the option you want. This will come in handy when debugging code that is asynchronous and plays with the document (eg. AJAX calls inserting new content).
In addition to this, you can scroll to the bottom of the styles pane to the right, and open the event listeners section. Here, you can inspect all the events bound to the selected DOM node.
You can enter debugger (without a semicolon) into your code, and it will open the sources tab at that point so you can inspect the code further. I think this may be Chrome specific.
Finally, tools like JSlint will help you spot undeclared variables as you code, as well as cases where the formatting of your code creates unexpected errors, and some might even go as far as using syntax highlighting to make you notice variables that are undefined.
This is also just scraping the surface. Your editor and JSlint can make your code look right and parse without error, but the browser and its console is where you will spend most of your time.
I wrote this small game at http://amarnus.me/games/dodge. Now if you trying playing the game in both Firefox and Chrome, you would clearly notice that it is significantly slower in Firefox. You can call it an unintentional cheat code, yes. ;-)
So my question is - Is this because of a slower Javascript engine in Firefox when compared to Chrome's? Or does it have something to do with bad coding? (In my defence, I am a Javascript newb)
Assuming that it is the former, then is this not a point against (disadvantage of) HTML5 games? (The ones using the <canvas> tag like mine)
Firefox is slower than chrome in javascript. However, I believe that it's also slower using the canvas-tag. This will probably improve with ff4 (have you tried the beta?).
There is also a nes emulator out on the web somewhere using js and canvas, and it runs in about 30fps on chrome (if I remember about correctly), but only about 10 in ff.
Time is probably your best friend :-P, though you can alwasy try to optimize.
I believe that browser-games will come in time, but it's not ready as of yet to anything too advanced. Maybe about the time ie12 comes out :-P.
[Edit]
Btw: I tried the game in FF4b1, and I thought it ran great. Probably not as fast as in chrome, but not far from it :).
In order to get help you might consider providing a non-minified version of your script.
I see that there are 8ms setIntervals in your code. As mentioned above, Firefox never goes below 10 ms (yet). Playing your game in FFox 4 it is very enjoyable, though. I saw two very small hickups that clearly were caused by garbage collection. Chrome has an edge over the Fox in that regard. Even though SpiderMonkey (that handles GC in Firefox) has improved dramatically from 3.5 to 3.6 it's still not good enough for many games. In 4.0 it is a lot better, but still not quite as good as in Chrome or Opera. (It is being worked on.)
Playing the game and looking briefly at your code, I see no complexity that would cause Firefox not to be able to handle what's going on. Also Firefox 4 has hardware accelerated Canvas that is marginally faster than IE9 and a lot faster than Chrome.
There is a notion on the web that Chrome is faster than Gecko when it comes to canvas, but that is because people rarely profile their pages. In fact, canvas in Firefox 3.6 is already at least as fast as in Chrome, but many tests don't show it since the JavaScript is slower. (And some JavaScript tests are slower because Firefox does not handle the test harness well.)
All this leads to lots of confusion and misinformation. The bottom line is that your game should be OK in Firefox 4. You should see if there is anything you can do to avoid triggering unnecessary GC. E.g. are you re-using variables or creating unnecessary new ones?
However, in Opera 10.53 it was not enjoyable. Not because Opera could not keep up with the speed, but since instead of moving the bottom piece, it was kept stationary and the whole playing field moved instead. (I managed to go to level 17 in my first try in spite of this.) In Opera 10.6 the page fails to load properly.
You probably need to debug your code - or perhaps file a bug with Opera if it's a regression. (I'll tweet this to get their attention.)
I'd blame a large part of it on setTimeout and setInterval having a ~10ms minimum in browsers such as IE and Firefox. This was originally adopted to stop pages from consuming the entire CPU should they naively use 0ms to run as fast as possible. Chrome launched without a limit but is now moving to a 4ms minimum to match the recommendation in HTML5.
John Resig has some awesome posts investigating setTimeout limits and accuracy.
Mozilla browsers can actually tell you how late (or early!) they're running with each setInterval call. Check out the MDC setTimeout article (google "mdc settimeout" and check out the grey note in the syntax section).
Apart from timer problems, Firefox is just generally slower in JS execution (for now at least) and it feels as if Skia (Chrome's graphics lib) is just faster at rasterising too.
Hope this helps :)
(I originally had a bunch of useful links here, but it's my first post and the spam filter slapped me down.)
jQuery animate does something similar to your DOM object movement.
I would look into their code and see how they do the actual movement, it's probably the most efficient way since it's built in jQuery.
Chrome is designed to have a faster Javascript engine.
I don't think it says anything about HTML5 games. You will always find users with faster or slower setups than others, be it hardware, software or a user's personal habit of keeping many applications running at once. If your game were written in Flash or Java, then a user with slower hardware would see a similar slowdown.
You may be able to make changes to your code in order to speed it up. I haven't examined it in great detail, but I see you have constructs like if(dodge.goRight == true .... Although not a source of slowness, this does hint that you may not have used the optimal solution everywhere.
You can test your browser javascript engine with IE site.
http://ie.microsoft.com/testdrive/
They assert to the highest speed javascript engine they have with IE9
Try out this technique: setTimeout with a shorter delay
Let me know if it helps. I'm kinda curious now. :)
Good luck!
Consider a complex rich internet application with lots of user interaction. I'm thinking of extensive drag-drop support, server-side user input validation, custom drawn UI controls such as an Outlook-like calendar, real-time UI feedback, etc... Would such an application be debuggable? I mean, can you easily step through the source code, place breakpoints, view the contents of variables, see the current call stack, use a profiler to pinpoint performance issues, etc...
Yes, why wouldn't it be?
Complexity just means more code to dig through, but tools like console.trace() from Firebug makes that easier.
Yes, it would be debug-able.
If you're using IE8 to test your site, you could use the Developer Tools to inspect individual HTML elements and change their CSS on the fly. There's also the ability to break into Javascript from the same interface.
If you're using Firefox, Firebug has almost identical abilities with a different interface.
Safari also has developer tools installed by default, you just have to go through the hoops of enabling them.
When you are designing your application, design it with debugability and testability in mind. Make sure that individual parts are independently testable, you have enough test data, you have appropriate debug/probe points in your program logic, etc. Essentially if the complexity is properly managed, debugability won't be an issue at all.
If your job depended on it, you would find a way! :)
Seriously... a passenger jet has literally millions of parts and yet there are regular routine maintenance checks and if it breaks down it gets fixed. It's a very rare piece of software that approaches that much complexity.
Web app front ends tend to be relatively simple. Essentially you're just pushing some text from the server to the browser and making it pretty; and you're using various parts of the in-browser display as controls, some of which initiate some more text conversations with the server. There are lots of little things that can go wrong, of course, but much of the hardship is simply getting the browser (all of them!) to Do What You Mean.
The only truly difficult problems are those that are intermittent and/or timing sensitive. Those can be a bear to reproduce and trace. That calls for in-depth logical analysis of your source code and/or some specialized testing methods.