Showing posts with label 2023-august. Show all posts
Showing posts with label 2023-august. Show all posts

Thursday, September 7, 2023

Lazy Loading in Angular | Lazy-loading feature modules | Chunk Loading of Components

NgModules are eagerly loaded by default, which means that as soon as the application loads, so do all of the NgModules, whether or not they are immediately required.

Consider lazy loading in angular — a design strategy that loads NgModules as needed — for big apps with many routes. Lazy loading helps to keep initial bundle sizes smaller, which reduces load times.
As Angular generates a SPA (Single Page Application), all of its components are loaded at the same time. This implies that a large number of unneeded libraries or modules may also be loaded.

Lazy loading in angular is the process of loading website components, modules, or other assets when they are needed.
You can utilize lazy loading (or asynchronous loading) with the router if you're constructing your application and utilising feature modules to arrange code. This allows a whole module to load only when needed, reducing the file size of the core bundles and maybe limiting access to bundles to just those who are permitted to use it (like administrative modules).

Because there is no logical isolation if your application has not been split into various modules, lazily loading them into the application is not feasible. The core notion is that the Angular build process can examine code pathways and optimize code depending on how it's used to produce other files, but it relies heavily on Angular modules to know how code is connected.
Steps to Implement Lazy Loading

You need to create your first angular project, you can get help from here how-to-create-multi-layout-application.html

Create a directory under app directory named routes, then create a file under that directory lazy-users-routing.module.ts with below content:
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';

const routes: Routes = [];

@NgModule({
    imports: [RouterModule.forChild(routes)],
    exports: [RouterModule],
})
export class LazyUsersRoutingModule {}


Now create another file in same directory named lazy-user.module.ts with below content:
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';

@NgModule({
    declarations: [ ],
    imports: [
        CommonModule
    ]
})
export class LazyUserModule { }


I assume you have already several component, if not you can create components by your own. Now lets check how we implement Lazy Loading with loadChildren.
Our main routing file app-routing.module.ts will be look like below:
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import {HomeComponent} from "./modules/home/home.component";
import {DefaultLayoutComponent} from "./layouts/default/default.component";
import {LoginComponent} from "./modules/login/login.component";
import {StaticLayoutComponent} from "./layouts/static/static.component";

const routes: Routes = [
    {
        path: '',
        component: DefaultLayoutComponent,
        children: [
            {
                path: '',
                component: HomeComponent,
            }, {
                path: 'users',
                //component: UsersComponent,
                loadChildren: () => import('./routes/lazy-user.module').then(m => m.LazyUserModule)
            }
        ]
    }, {
        path: '',
        component: StaticLayoutComponent,
        children: [
            {
                path: 'login',
                component: LoginComponent,
            }
        ]
    },
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }


This is the main part of app-routing.module.ts file where we enabled lazy loading of our components:
{
    path: 'users',
    //component: UsersComponent,
    loadChildren: () => import('./routes/lazy-user.module').then(m => m.LazyUserModule)
}


Now we will define UsersComponent in LazyUsersRoutingModule like below:
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import {UsersComponent} from "../modules/users/users.component";

// This route is prefixed by /users
const routes: Routes = [
    {
        path: '', component: UsersComponent
    }
];

@NgModule({
    imports: [RouterModule.forChild(routes)],
    exports: [RouterModule],
})
export class LazyUsersRoutingModule {}


Our final lazy-user.module.ts is as below:
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import {UsersComponent} from "../modules/users/users.component";
import {LazyUsersRoutingModule} from "./lazy-users-routing.module";

@NgModule({
    declarations: [
        UsersComponent,
    ],
    imports: [
        CommonModule,
        LazyUsersRoutingModule,
    ]
})
export class LazyUserModule { }


We have enabled lazy loading of component, if we check our network tab we have evidence of that:


GitHub link for this example is https://github.com/pritomkucse/angular-layout/tree/lazy-loading

Monday, August 28, 2023

Grails / GORM apply criteria query with hasmany String for filter

I have a domain object (User) like this:
class User {
   String name

   static hasMany = [
      permissions: String
   ]
}
And I am trying to query all the User with certain permissions. So I have to join and check permissions property. Here how we can do this -
User.withCriteria {
    createAlias('permissions', 'n') 
    ilike 'n.elements', '%permission_1%'
}
The trick is to use 'n.elements'