One of the common complaints from mobile developers is how hybrid apps such as those built with Ionic/Cordova/Phonegap simply aren't on a par with native apps when it comes to performance.
Often such performance issues exist not as a result of the underlying frameworks but more as a consequence of development oversights and mistakes.
As hybrid developers there's a lot we can do to improve the performance of our applications as detailed in the following insights.
1. Make use of Ionic/Angular
This one's pretty much a no-brainer but taking advantage of the underlying Angular framework and Ionic's built-in components, API and Native plugin ecosystem guarantees a high level of optimisation and performance gains over vanilla TypeScript.
Issues with DOM rendering, event handling, browser quirks and memory management have all been figured out (or, at the very least, most of these have!) which begs the question...
Why reinvent the wheel when solutions already exist?
NOTE: It's going to be interesting to see what performance changes are going to occur with the release of Ionic 4. As web components will be generated using Stencil we should expect to see an increase in performance gains (I.e. reduced template compilation time and reduced launch times). That said how will the planned ability to implement different frameworks impact on that performance?
2. Ahead-of-Time compiling
Building applications to run on IOS & Android? Don't forget to implement Ahead-of-Time (AoT) compiling with the addition of the --prod flag:
ionic cordova build ios --prod ionic cordova build android --release --prod
Ahead-of-Time compiling improves performance by compiling templates at build time NOT runtime. This leads to faster rendering of views and decreased launch times for applications.
Additionally any template binding errors that may exist are reported during the build process allowing developers to resolve such issues BEFORE they ship their code.
3. Minimise system intensive processes
Handling asynchronous operations inside your applications?
Use callbacks or, given Ionic/Angular's built-in support, Promises and Observables wherever possible as these do not lock up your application or any underlying processes that are taking place.
Implementing CSS animations?
Use CSS transitions and transforms together to take advantage of GPU hardware acceleration BUT do so sparingly as this can be very system intensive causing your device battery to drain while simultaneously raising thermal output.
Can service workers be used to handle background tasks?
What about using battery status to limit certain operations within your application? For example, you might want to prevent CSS/JS animations being triggered if the battery level falls below 60%.
4. Use DOM rendering sparingly
Consider lazy loading large items of content that are being rendered to the screen as this reduces memory consumption, browser repaints and CPU cycles. When you are iterating through large lists of data to be output to the DOM only render what can be seen within the browser viewport. Reduce the load on your device's system resources by re-using DOM items wherever possible.
5. Collect your garbage
Clear out unused variables, objects and arrays so that they are not kept in memory.
Additionally, test the use of different loop operators (I.e. while, for, for in, forEach) to determine which are the most efficient for optimising system resource usage (also look into whether the array map operator could be used instead of loops).
6. Data persistence
Avoid local storage in favour of a database solution wherever possible.
Local storage has limitations in the quantity of data that can be stored, doesn't always behave consistently across different browsers and, bizarrely, sometimes "empties" itself without being prompted to do so.
I have written a number of articles discussing building Ionic applications with PouchDB.
7. Manage network requests
Intelligently handle network requests and/or how remote content is deployed within your application.
Don't hammer the network with repeated requests. If network connectivity is unavailable or patchy at best how does your application deal with this?
If your application requires remote content how is this best retrieved? How can you effectively design your application logic so that network connectivity issues are handled with the least impact to the app functionality and the user experience?
8. Efficiently handle media content
Can images be deployed as SVG's to cut down on file size (and aid with responsiveness over different screen sizes without requiring multiple different files to accomplish this)?
Have bitmap images been compressed to reduce file sizes - particularly if being loaded/requested remotely?
Could CSS sprites be used to optimise image sizes?
Would an application's images/video/audio assets be better handled through a Content Delivery Network?
When removing media from the component template view be sure to remove any and all references to that media element within the component logic (see point 5).
9. Test, test and test some more
Test non-cordova related application logic in your desktop browser with the developer tools of your choice (substitute the following examples using Safari with Google or Firefox if you use those browsers).
Make extensive use of console logging where relevant. Analyse network request/response times and test DOM rendering/browser repaint times with Safari's Timelines. Verify application logic flows with Safari's Debugger.
Run performance tests that measure timings for different operations (I.e. network requests, array iterations etc).
Use Xcode and Android simulators if you don't have a suite of testing devices (and how many developers can afford to continually add to and update the new devices being released every year?)
Alternatively investigate how your application performs on different devices using opendevicelabs.com.
I would recommend these at a bare minimum but, as with all things development related, you can test and test to the point where it becomes an obsession.
Simply find what works for your project needs and run with that.
Ionic applications are no slouch when it comes to performance but, as developers, there are measures we can take to reduce or remove performance bottlenecks.
From Ahead-of-Time compiling and media management to garbage collection and handling network requests efficiently there are a number of improvements we can implement to make our apps run faster and smoother.
Given plans for Ionic 4 to use components developed exclusively with Stencil I expect applications built using this version of the framework to be even speedier and snappier.
If you've enjoyed what you've read and/or found this helpful please feel free to share your comments, thoughts and suggestions in the comments area below.
I explore other areas of using the Ionic framework within my e-book featured below and if you're interested in learning more about my e-books please sign up to my FREE mailing list where you can receive updates on current/forthcoming e-books and blog articles.