Optimizing Angular Form Validation with Lazy Load
Lazy loading is a technique used to improve the performance of web applications by only loading the necessary code and resources when needed. This can be especially useful in large and complex applications, as it can help reduce the initial load time and improve the overall user experience.
Recently I needed to implement a blockchain address validator in one of our forms. My search turned up an old open-source library that could help me with that, but its size was over 200kb. I didn’t want to load it all for no reason, so I created an async validator that loads the library only when I need it:
function addressValidator(): AsyncValidatorFn {
return function (control) {
return import('address-validator-package-name').then((m) => {
return m.validate(control.value) ? null : { invalidAddress: true };
});
};
}
The import
function allows us to lazy load the library and use its validate()
method. All that’s left is to add it to the form control:
@Component({ ... })
export class FormComponent {
addressControl = new FormControl('', {
asyncValidators: addressValidator(),
});
}
The current addressValidator
implementation will work when we’re not using the onPush
change detection strategy in the component. Whenever we do, we’ll need to alter the code and call markForCheck
:
export const ADDRESS_VALIDATOR = new InjectionToken<AsyncValidatorFn>(
'ADDRESS_VALIDATOR'
);
const addressValidator = {
provide: ADDRESS_VALIDATOR,
useFactory(): AsyncValidatorFn {
const cdr = inject(ChangeDetectorRef);
return (control) => {
return import('address-validator-package-name').then((m) => {
cdr.markForCheck();
return m.validate(control.value) ? null : { invalidAddress: true };
});
};
},
};
@Component({
providers: [addressValidator]
})
export class FormComponent {
addressControl = new FormControl('', {
asyncValidators: inject(ADDRESS_VALIDATOR),
});
}
Follow me on Medium or Twitter to read more about Angular and JS!