Lazy Loading Performance in Ionic
Lazy loading was introduced in Ionic 3 to reduce application startup time. It started out as an experimental feature, but has since then become the default way for building Ionic applications. However, even with lazy loading enabled, application performance can be tweaked further with different configurations options.
When support for lazy loading was added to Ionic applications, it affected how the project was built into JavaScript files which are then loaded by the web view:
Applications without lazy loading consisted of a single module only, resulting in a single JavaScript file which needed to be loaded and fully parsed before the code could be executed and the first page displayed to the user.
In applications with support for lazy loading, each page is placed in its own module. Each module is then compiled into a separate JavaScript file which can be loaded independently of the others. To display the first page to the user, only its JavaScript file needs to be loaded and parsed (in addition to the main application module JavaScript file, of course).
This change can drastically reduce the time until the user can start interacting with the application. However, JavaScript files for other pages still need to be loaded. This will happen when the user tries to open a particular page for the first time, causing additional delay before that page will be displayed. There will be no such delay at subsequent attepts to open the page.
For some pages, this delay can be quite noticable. To combat the issue, Ionic provides a module preloading feature. When enabled, Ionic will start loading JavaScript files for other pages immediately after the first page is displayed to the user. Unless he navigates to the next page as soon as the first one is displayed to him, there is a big chance that the page was already loaded in the meantime and there will be no additional delay because of loading.
In theory, lazy loading with module preloading enabled should be the best choice as it combines both benefits:
- shorter time till the first page is displayed, and
- no additional delays when accessing other pages for the first time (if the user isn't too quick).
That's not how it works in reality, though. Preloading of other pages interferes with the execution of JavaScript code in the first page because there's only a single thread available to handle both. In our quite large application we have even noticed that asynchronous calls triggered during application startup (e.g. navigation to first page) didn't resolve until the preloading was complete. This effectively rendered the application useless for the user until that point, resulting in an experience not much different from having no lazy loading at all. Disabling the module preloading resulted in a very noticable improvement in startup time:
Module preloading | Low-end device | High-end device |
---|---|---|
Enabled | 19.1 s | 3.0 s |
Disabled | 4.1 s | 1.1 s |
We're currently quite satisfied with the overall application performance as is. The delays when accessing pages for the first time are not too much of a problem. If they were, there's one more trick available in Ionic: priority can be set for each page, specifying how it should be treated by module preloading. Setting it to off
will exclude it from preloading altogether as if preloading was disabled.
If we ever encounter a single page (or a couple of them) which will have too long a delay on first access, we will try re-enabling module preloading and set priority to off
for all pages accept those few problematic ones. It should hopefully keep the startup time short enough while avoiding delays for the selected pages.