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:
On the server
Always optimize:
- 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 Show archive.org snapshot .
- Add database indexes.
- Don't descend into callback hell. Use form models Show archive.org snapshot .
Optimize on demand:
Don't optimize without knowing what's actually slow. Measure first, for example by using a performance monitoring tool like NewRelic Show archive.org snapshot , Scout Show archive.org snapshot , AppSignal Show archive.org snapshot , Skylight Show archive.org snapshot .
Once you know your bottlenecks, you can do things like:
- Add caching Show archive.org snapshot . Since caching is very hard, only cache where it really matters
- Offload work to a background processor like Sidekiq Show archive.org snapshot ?
- 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.
On the client
The biggest issue on the client are loading times. Those primarily increase with the number and size of your assets, especially with CSS and JavaScript.
Always optimize:
-
Keep your JavaScripts small. This is the most important rule.
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.
- Be wary of low quality JavaScript libraries.
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.
- Load your JavaScript with
<script defer>
- 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.
Optimize on demand:
Before optimizing, always measure. Use a tool like
Google's PageSpeed Insights
Show archive.org snapshot
or the Performance
tab in your Chrome DevTools. Then do things like
- Use a CDN.
- Optimize images
- Defer loading of parts of your JavaScripts.
- Optimize rendering performance.
- Move interactions and rendering from the server to the client.
- Improve perceived performance by prefetching pages and following links un
mousedown
, using tools like Unpoly Show archive.org snapshot or fastclick. - Only render the HTML you are going to use.