Keeping web applications fast
Our applications not only need to be functional, they need to be fast.
But, to quote Donald Knuth,
premature optimization is the root of all evil (or at least most of it) in programming
The reasoning is that you should not waste your time optimizing code where it does not even matter. However, I believe there are some kinds of optimizations you should do right away, because
- they are either obvious and easy
- or they are very hard to do optimize later
This is an attempt to list some of those things:
- Don't do stupid things with the database. Avoid "n + 1" queries. Don't do costly calculations live when you can precalculate and cache. Don't instantiate 1000s of records. Use query_diet.
- Add database indexes.
- Don't descend into callback hell. Use form models.
Don't optimize without knowing what's actually slow. Measure first, for example by using something like Skylight. Then you can do things like:
- Add caching. Since caching is very hard, only cache where it really matters
- Offload work to a background processor like Sidekiq?
- Split pages into multiple request. Perhaps you can load that complicated table, or crazy visualization in a separate AJAX call?
- Move work from the server to the client.
Don't add big libraries you don't really need. Don't add a framework like Angular just to build one little component. Don't add 3 different lightbox libraries, if you only need one. Don't load the complete jQuery-UI, if you only need one component.
- If you need a library only on a few pages (e.g. TinyMCE), only load it on those pages.
You need to have a rough understand how a library works. This is especially true for all polyfill that fix browser behaviours with all weird kinds of tricks.
- In your own scripts, don't add event handles to 100s of elements. Don't casually rewrite huge parts of the DOM.
- Keep your stylesheets small when possible. If you use a framework like bootstrap, only include the parts you need, not everything.
- Keep your stylesheets flat. This improves rendering performance and you probably do it already, since you're using BEM.
- Make sure your assets are minified, compressed, and cacheable.
- Split your assets when there is an obvious opportunity.
If your application has big separate parts - say a public frontend and an admin backend - that work very differently, keep their stylesheets and scripts separate. Only share what you need.
Before optimizing, always measure. Use a tool like Google's PageSpeed Insights. Then do things like
- Use a CDN.
- Optimize images
- Optimize rendering performance.
- Move interactions and rendering from the server to the client.
- Improve perceived performance by using tools like Unpoly fastclick.
- Improve perceived performance by prefetching pages before the user clicks by using tools like Unpoly.