AngularJS Reloaded: Lazy Loading Files

Disponível também em inglês

Nesse artigo vou mostrar como carregar os scripts e estilos de acordo com a necessidade no AngularJS usando técnica de lazy loading e UI route resolver.

Vamos pensar em um problema:

Você tem uma tela “A” que usa o plugin jqGrid plugin e duas outras telas “B” e “C” que não usam esse plugin. Normalmente você referencia o script do plugin na master page da aplicação e todas as telas “A”, “B” e “C” carregarão esse script mas apenas a tela “A” irá usá-lo. Esse é um problema de performance que começa a ficar complexo quando há muitos scripts.

 
AngularJS Reloaded: Lazy Loading Files
 


 

A solução:

Usar uma combinação do plugin de lazy loading para o AngularJS e AngularJS UI router resolver para carregar os scripts conforme a necessidade antes de abrir a tela.

Vamos ver o código:

Arquivo: app.definition.ts:

var definitions = function () {
    var baseFolder = '';
    return {
        grid: {
            devDependencies: [
                baseFolder + 'Css/plugins/jQueryUI/jquery-ui-1.10.4.custom.min.css',
                baseFolder + 'Css/plugins/jqGrid/ui.jqgrid.css',
                baseFolder + 'Css/style.jqGrid.css',
                baseFolder + 'Scripts/plugins/jqGrid/i18n/grid.locale-pt.js',
                baseFolder + 'Scripts/plugins/jqGrid/jquery.jqGrid.min.js',
                baseFolder + 'Scripts/plugins/jquery-ui/jquery-ui.min.js'
            ]
        }
    };
} ();

O container “definitions” guarda a configuração para cada plugin e suas dependências de scripts e css.

Arquivo: app.routes.ts:

(function () {

    class AppRoutes {

        constructor(
            private utilProvider: App.Util,
            private $stateProvider: ng.ui.IStateProvider,
            private $urlRouterProvider: ng.ui.IUrlRouterProvider
        ) {
            let genericRoute = new App.Core.State.GenericState(this.utilProvider);

            this.$urlRouterProvider.otherwise("/login");
            this.$stateProvider.state('homemenu', genericRoute.getState({
                url: '/',
                views: {
                    root: {
                        template: 'The page does not use GRID scripts. Go to <a ui-sref="homeperson">Person Page</a>'
                    }
                }
            }));
            this.$stateProvider.state('homeperson', genericRoute.getState({
                url: '/person',
                dependencies: ['grid'],
                views: {
                    root: {
                        template: 'That page uses GRID scripts. Back to <a ui-sref="homemenu">Home Page</a>'
                    }
                }
            }));
        }
    }

    AppRoutes.$inject = [
        'utilProvider',
        '$stateProvider',
        '$urlRouterProvider'
    ];

    angular
        .module('app')
        .config(AppRoutes);

})();

O código acima eu configurei as rotas para esse artigo. Apenas a rota “/person” usa o jqGrid plugin e suas dependências. O método “getState” a gente configura o lazy loading e verifica as dependências no container “definition” para saber quais scripts ou estilos serão carregados.

Tente você mesmo:

Acesse a homepage:

lazy loading

Veja no “fiddler” que nenhum scripts ou estilo do plugin do GRID serão ou foram carregados:

lazy loading

Clique no link “Person Page”, irá navegar até a outras tela que usa o grid:

lazy loading

Veja no “fiddler” que para essa rota, todos os scripts e estilos para o plugin do grid foram carregados.

lazy loading
 


 

Bom é isso. Esperto que tenha ajudado.

Abaixo encontrará alguns links úteis.

Angular lazy loading: Perguntas, sugestões ou críticas são bem vindas. Boa sorte!

Faça download completo do código fonte no github.

Veja um demo online dessa aplicação no codefinal.
Sobre o Autor:
Trabalha como arquiteto de soluções e desenvolvedor, tem mais de 16 anos de experiência em desenvolvimento de software em diversas plataformas sendo mais de 14 anos somente para o mercado de seguros.