Ленивая загрузка — это метод, используемый для повышения производительности веб-приложений путем загрузки необходимого кода и ресурсов только тогда, когда это необходимо. Это может быть особенно полезно в больших и сложных приложениях, так как может помочь сократить время начальной загрузки и улучшить общее взаимодействие с пользователем.

Недавно мне нужно было внедрить валидатор адресов блокчейна в одну из наших форм. Мои поиски наткнулись на старую библиотеку с открытым исходным кодом, которая могла бы помочь мне в этом, но ее размер превышал 200 КБ. Я не хотел загружать все это просто так, поэтому я создал асинхронный валидатор, который загружает библиотеку только тогда, когда она мне нужна:

function addressValidator(): AsyncValidatorFn {
  return function (control) {
    return import('address-validator-package-name').then((m) => {
      return m.validate(control.value) ? null : { invalidAddress: true };
    });
  };
}

Функция import позволяет нам лениво загружать библиотеку и использовать ее метод validate(). Осталось только добавить его в элемент управления формы:

@Component({ ... })
export class FormComponent {
  addressControl = new FormControl('', {
    asyncValidators: addressValidator(),
  });
}

Текущая реализация addressValidator будет работать, когда мы не используем стратегию обнаружения изменений onPush в компоненте. Всякий раз, когда мы это делаем, нам нужно изменить код и вызвать 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),
  });
}

Подпишитесь на меня в Medium или Twitter, чтобы узнать больше об Angular и JS!