(Currently) best practice for lazy-loading and module per component?

Hello fellow Ionites

I’m confused regarding best practices regarding best-practices on lazy-loading, component grouping in modules.

I’ve been with Ionic since early Beta, and I have seen the CLI changing in the way it makes components and pages. It has gone from creating ‘bare’ pages, to lazy-loading pages and each page in its own module. And creating ‘bare’ components and a single module per component, and now a single module with for all components.

So I’m really confused…

What is the best practice for using pages, lazy-loading pages, and components regarding performance but also code duplication?

Shall I stick every page to be in its own module and lazy-loaded? Then each component in its own module that can be imported to root component and each page component? or group components to a single module and import everywhere?

Or totally avoid lazy-loading and have all pages declared in my root app component?

We are building an app that constantly evolves and pages and components are added, and I would like to stick to best practice. Avoid large refactors in the future or see it having degraded performance because or ‘early’ bad practices…

Any suggestion, comment from more experienced members of this forums appreciated.

Thank you in advance.

It may have changed the last time I really looked into it, but it kinda depends.

If you have a “lot” of pages without many components, lazy loading makes a good bit of sense.

If you have lots of components, then it will wind up with a good bit of code duplication which will (or at least will likely) undo the benefits of lazy loading.

As far as components and having one module per each or one large module, unfortunately I don’t have a horse in that race.

My horse is one module per component, as it mitigates the impact of the code duplication and makes more clear what functionality is being used where. I cannot think of a single benefit of the ComponentsModule idiom.

Here’s two benefits re ComponentsModule:

  • Ease of use when importing components into your page - saves importing a big bunch of individual components modules into your pages, annoying.

  • Tidier app.components.ts file - you just need to throw the ComponentsModule into the app.components.ts and all your individual lazy loaded files will not need to be packed with those components on an individual basis resulting in a smaller payload.

I disagree that that’s a benefit. Extending that logic to its extreme, we should just put the entire app into a giant single file. My IDE’s autocompletion feature offers to add the import for me with a single keystroke; I’m sure yours has something similar.

Static code analysis tools can know what other parts of the app are potentially affected when a component they use is modified. That gets thwarted with monolithic ComponentsModules, as does human readability.

I’m going to assume you mean app.module.ts here instead. I guess we have different definitions of “tidy”, because all you’re doing here is introducing a needless layer of indirection. If you’re going to put all the components in the app module, just put them in the app module directly. ComponentsModule is a middleman that delivers no value.

It also seems to me to be contrary to the philosophy of lazy loading. If code splitting actually worked right, every component and page would include only what it needs. Since it doesn’t, you have the schizoid hack of lazily loading pages but throwing all the subcomponents into the app module in some fashion.

So, at the end of the day, I think for most apps, lazy loading offers more in the way of hassle and problems than it does value. Obviously, reasonable people can disagree with that assessment.

First of all, thank you all for your valuable feedback.

I’m leaning toward dropping lazy loading of pages altogether, since I have a lot of pages. If Lazy loading each one of them independently and then having to import quite some custom components that are to be used for each one of them, leads to these components code to be doubled, tripled, etc. then it’s not worth it.

What it would be really helpful for me is if possible to Lazy load an entire module that can contain multiple pages, and the components they are suppose to use. Because my app’s activity is based on user roles, so there are set of pages that they are never going to be used at all by individual users. Do you know if this is feasible with latest Ionic version?

Regards

That’s an extremely reasonable and worthwhile goal.

To the best of my knowledge, no. Although I can’t place the blame squarely on Ionic, because webpack needs to get involved as well.

However, if your components are only used in single pages, the code duplication issue shouldn’t affect you.

TBH knockout did it better in terms of lazy loading.

You could call a component like so…

<div data-bind=“component: { name: ‘whatever’, params: someObject }” />

Notice the name is just a string…? That was lazy loading similar to how we can now do it with pages and modals, and was seriously clean in terms of not having to have files with big silly lists of items.

If that ever becomes a reality I’ll be a happy boy.

At this moment, the tradeoff is space for time. For UX, startup time has to be at a minimum. Within reason, the user does not care or notice how large an app is. The least tech savvy user notices a 10 second startup time. So I think all sane devs need to lazy load if they have a lot of pages, at least as long as Ionic requires Angular, which preloads page factories.

That doesn’t mean I’m a fan of code duplication, and I wish things were better, and maybe they will be. The Ionic devs are reporting a huge speedup in tests of the Ionic 4 proto. If that holds up in real life, maybe we can have a more nuanced conversation here. But at the moment, I think you have to lazy load if you want a genpop publishable app with more than a few pages.

Without a doubt lazy loading is a necessary pursuit.

The annoying thing that gets me about people’s snobbery towards web apps is the gripe about performance. And in fairness they’re usually right. Most are friggin awful.

But remember… the vast majority of native apps are equally poor and slow - but we never see them coz we’re all staring at the biggys like Facebook and YouTube - and take that as an undeserved baseline.

What we need are better ambassadors and more efficient coders, not better technologies to go on repeating the same nonsense you see everywhere.

1 Like

Hello, like everyone who knows a bit the plug between a database and lazyload, is that everything effectively use it. For my part in a current Magento build, i’d have to change every module that is coded (very crappy) before me. Hence the task of lazy loading is a very nice endeavour, but not worthing a good implementation of Redis for instance.

Still, in an app, there are strong reasons why not to lazy load in ecommerce, for example in a case you have more than 50 products with variations per category (and this whatever app can kill load times because of db lag - 50 products x 6 sizes x 3 colors can lead to huge database calls). Avoiding that fact can lead to issues.

I have to agree with you. I had the same exact conversation yesterday about how, in general, mobile apps of any kind just are not very good.

I would guess that many of the developers that have had the good fortune and work-ethic to be career mobile app developers are pretty good at what they do.

But I suspect that many declare the job done when it gets to a point that it just “works”. I don’t know that many have a relentless need to pick apart lines of code to improve performance even to slight degrees. It’s too bad, because those slight gains add up.

But, overall, mobile apps are just not very good.

I tried to list all the issue and PR about that subject, I wrote then down in following post:

Both following PR for webpack exists since a while but where never merged :frowning:

In his last Ionic blog post, @danbucholtz briefly spoke about the introduction of angular ngo, maybe not gonna solve this problem but should help to improve the major effect of not using lazy loading, respectively increase the boot time

When it comes to me I decided a while ago to not use yet lazy loading even if my app has quite a size (something like > 30 pages, > 40 components) … maybe I should give another try with one module pro component and see how my boot time improve and how the size of the app goes bigger…

In terms of boot time I found lazy loading to be the single biggest factor. I would recommend eager loading only what you need on app initialization the lazy-loading everything else (with pre-loading)

Is code duplication (e.g. of a component being imported in separate lazy-loaded pages) supposed to affect app performance while running (not when loading)? For example having two or three separately lazy-loaded pages having a copy of the same component. Or it is just the memory that is affected by code duplication?

It is easy to fall into that trap.

That’s why I put em all into a components.module.ts and import that in the app.component.ts.

@Judgewest2000

Yes I agree.

My question has surfaced because I’m thinking of going lazy-loading per page (as it is now) and then having each component in its own module. This will allow to import only the necessary components in each page. I know it’s harder to maintain as code. But will it affect my “after-loading” performance or only the memory size of the app?

Thanks

This is a pretty good approach if you manage it properly.

Certainly I have two sets of components. A bunch of form controls with the labels and validations all uniform - and ones more custom to individual parts of the application.

You can guess which set is included in the main app.component.ts and which are not.

I’m good at managing this stuff and I get it wrong a lot!

@rapropos I followed your idea, one component = one module

my bundle.js grew, while building with --prod, from a main.js of 1.1 Mb to 1.6 Mb (if I sum up main.js and all 0,1,etc.js) … don’t know if I should take that as “not that bad” or “hell no, no go”

although to speak frankly, I ask my self if that is not a lot of work for a small win because I don’t really have the feeling that my app boot faster :joy:

Update: Nah I like it, “not that bad”, feel overall smoother don’t no why…gonna go live with lazy loading, alea jacta est :wink:

Btw. bonus, look like using lazy loading (at least in this form) in comparison to no lazy loading speed up my build time :slight_smile:

About component and code “duplication”, one pull request has been merged about that subject in webpack today (and included in the new version of webpack 3.7.0)