I've noticed lately a lot of confusion regarding performance of web applications. This post tries to clarify a few points while delivering a method for optimising your code.
tl;dr: In case of slow web app:
- Profile your application and optimise the code logic
The first thing to do is to investigate to find out where the performance issue is coming from. The causes can be multiple:
- Relying too much on the connexion
- Extensive DOM manipulation
- Rendering issues (forced layout...)
- io (e.g. repeated usage of
Use the Network tab of your favourite browser's development tool. Make sure your requests don't have any impact on your application at start and run time. Repeated Ajax calls can slow down applications too.
Identifying slow DOM manipulation is a bit harder. The Timeline tab of Chrome's dev tools can help you pinpointing such issues. Of course, you must get familiar with the best practices. For example, when rendering a list of items in a templating engine, move the loop to the template and append all items to the DOM in one operation.
There are a lot of valuable resources on the net about how to track down and fix these issues, so I won't cover them here. Once fixed, your application should work smoother. Not the case with yours? Keep reading then.
Nice, my favourite part of the optimisation process starts here! You need to profile your application.
Grab your modern browser. Start the profiler then your app and interact with it like a normal user would. After a while, stop the profiler.
You can now drill down to the most frequently called functions. If you're using closures or generated functions, make sure to name them to get meaningful results.
Now, have a look at the logic of the calls. There is certainly room for optimisation. Common mistakes include:
- Calling a function too many times, where the result could be cached and reused
- Deeply nested loops
- Iterating too many times when you could stop the iteration prematurely
You also need to profile the memory used and track potential leak or heavy garbage collections.
You found and fixed these bottlenecks and now your application is running faster and smoother. You are now done, no need to read further.
You are still reading? I assume you are working on a signal processing tool, a game or a fundamental piece of software that must run fast.
Trust the VM.
ifare faster than
- bitwise operations are faster than mathematical operators.
- join array to do strings concatenation
Also, VM are constantly evolving. What perform best today might not tomorrow. VM implementors take code from the real world to see what developers do and what patterns to optimise. Using weird syntax is likely to never be optimised. Just write your code in a way that makes sense and that should be enough.
After reading and understanding the statements above, you are now ready to improve your code using advanced optimisations. These crazy techniques include:
- Enforcing type stability
- Tracking deoptimisations
- Use web workers to do parrallel processing
In the 2nd part of this talk, Vyacheslav shows a tool to inspect the code generated by V8. It's complex to dive into the VM internals, but that's the only way to gain some performance points.
To track deoptimisations, using Chrome or V8, you can pass some flags like
--trace_deopt (trace deoptimization). You'll get a more or less descriptive message about why V8 is not able to optimise your code. Fix it if possible.