Lazy Loading con AngularJS

Introducción

Una de las preguntas que suelo escuchar sobre AngularJS una vez superada la fase inicial de aprendizaje es como se pueden cargar módulos, controllers, vistas etc bajo demanda. En circunstancias normales toda aplicación hecha con AngularJS necesita conocer toda esta información por adelantado. Por ejemplo si quieres añadir una dependencia tienes que especificar el módulo del que tu aplicación va a depender a la hora de crearlo. Si quieres utilizar un controller tienes que crearlo utilizando el API de Module; si quieres especificar una vista con el router y asignarle el controller este tiene que estar cargado… Es decir, una vez que una aplicación Angular está funcionando no puedes crear o cargar controllers, modulos, servicios, directivas etc etc.

¿Y qué tiene esto de malo? Pues es cuestión de opiniones, pero hay sobre todo dos problemas derivados de esta forma de hacer las cosas:

  • Rendimiento: Es posible que determinados módulos o controllers o vistas no lleguen a ser utilizadas, al tener que cargarlas todas al inicio estamos asegurando que la aplicación va a gastar siempre el máximo de memoria y recursos. Con los problemas que conlleva.
  • No es dinámico: Es posible, aunque debo decir que realmente poco frecuente, que yo quiera crear una aplicación extensible en la que los componentes a cargar no son conocidos o fijos y que quiera poder definirlos y cargarlos de forma programática. Como digo, muy poco frecuente pero posible sobretodo en aplicaciones muy complejas.

La solución

Aunque utilizando el API de Module no es posible hacer esto (en la rama 1.x, la 2.x ya lo tiene en cuenta), si trasteamos un poquito con las tripas de Angular y sabemos como funciona por dentro, la solución es bastante sencilla. La clave está en entender que realmente el API de Module es poco más que un wrapper sobre los diferentes providers que forman el API interna de Angular. Y por lo tanto quien realmente registra un controller no es el módulo sino el $controllerProvider mediante su método register y este método funciona aún estando la aplicación inicializada.

Al ser un provider solo podemos acceder a él en un bloque config lo que nos impide poder inyectarlo en nuestros controllers para poder utilizarlo; o eso parece. Pero dada la naturaleza de Javascript orientado a prototipos lo tenemos tan fácil como hacer lo siguiente:

 

De esta forma ya tenemos un método en el módulo de nuestra aplicación que nos permite registrar controllers de forma dinámica y bajo demanda. Técnicas similares pueden usarse para registrar servicios, templates o directivas.

Si alguien está interesado en saber algo más tengo un pequeño ejemplo en Bitbucket (https://bitbucket.org/raul_arabaolaza/raul_arabaolaza.bitbucket.org)

Y lo mejor de todo esto, alguien ha utilizado esta técnica y ha creado una librería de Lazy Loading para Angular que es de lo mejorcito que conozco. Se llama OcLazyLoad y se puede encontrar en https://github.com/ocombe/ocLazyLoad. Absolutamente recomendable si alguien necesita Lazy Load.

Esta librería se puede utilizar para cargar módulos, controllers, directivas o incluso templates de forma sencilla y además se puede integrar fácilmente con UI-Router. Con lo cual ya tenemos la posibilidad de manera muy sencilla de hacer que las vistas y el código javascript que controla estas vistas sea cargado bajo demanda en una aplicación Angular.

Post By Raul Arabaolaza (3 Posts)

Hay quien programa para crear cosas, yo creo cosas para poder programar

Connect

, , , ,

One Response to “Lazy Loading con AngularJS”

  1. Felipe Vengoechea
    27 enero, 2015 at 6:36 pm #

    Una fuerte sirena para aquellos que desarrollan bajo influencia. Para Webdev, sugiero leer la fuente firefox especialmente la parte de prueba de unidad. Ejecute ellos, consulte que hacen.

Deja un comentario

Leave your opinion here. Please be nice. Your Email address will be kept private.

Este sitio web utiliza cookies para que usted tenga la mejor experiencia de usuario. Si continúa navegando está dando su consentimiento para la aceptación de las mencionadas cookies y la aceptación de nuestra política de cookies, pinche el enlace para mayor información.plugin cookies

ACEPTAR
Aviso de cookies
Translate »