Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Empacotamento eficiente de aplicações frontend ...

Empacotamento eficiente de aplicações frontend com webpack

O frontend das aplicações precisa ser altamente eficiente e a forma de empacotamento utilizada faz toda a diferença. O foco dessa palestra será sobre o carregamento e algumas técnicas de otimização do frontend. Vamos conhecer o webpack, uma ferramenta capaz de criar e gerenciar vários artefatos para a geração do código final do frontend.

More Decks by Marcelo Emanoel Bezerra Diniz

Other Decks in Technology

Transcript

  1. HTML <head> <meta charset="utf-8"> <title>Agenda</title> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/ libs/materialize/0.98.2/css/materialize.min.css"> <link

    rel="stylesheet" href="style.css"> </head> <body> <div class="container"> <agenda></agenda> </div> <script src="lib/angular/angular.min.js"></script> <script src="lib/lodash/lodash.min.js"></script> <script src="https://code.jquery.com/jquery-2.1.1.min.js"></ script> <script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/ 0.99.0/js/materialize.min.js"></script> <script src="src/agenda/AgendaAPI.js"></script> <script src="src/agenda/AgendaController.js"></script> <script src="src/index.js"></script> </body>
  2. HTML <head> <meta charset="utf-8"> <title>Agenda</title> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/ libs/materialize/0.98.2/css/materialize.min.css"> <link

    rel="stylesheet" href="style.css"> </head> <body> <div class="container"> <agenda></agenda> </div> <script src="lib/angular/angular.min.js"></script> <script src="lib/lodash/lodash.min.js"></script> <script src="https://code.jquery.com/jquery-2.1.1.min.js"></ script> <script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/ 0.99.0/js/materialize.min.js"></script> <script src="src/agenda/AgendaAPI.js"></script> <script src="src/agenda/AgendaController.js"></script> <script src="src/index.js"></script> </body> <head> <meta charset="utf-8"> <title>Agenda</title> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/ libs/materialize/0.98.2/css/materialize.min.css"> <link rel="stylesheet" href="style.css"> </head> <body> <div class="container"> <agenda></agenda> </div> <script src="lib/angular/angular.min.js"></script> <script src="lib/lodash/lodash.min.js"></script> <script src="https://code.jquery.com/jquery-2.1.1.min.js"></ script> <script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/ 0.99.0/js/materialize.min.js"></script> <script src="src/agenda/AgendaAPI.js"></script> <script src="src/agenda/AgendaController.js"></script> <script src="src/index.js"></script> </body>
  3. PROBLEMAS ➤ Escopo global ➤ Ordem das declarações afeta o

    resultado final ➤ Forte tendência a aumentar o número de scripts com a aplicação ➤ Forte tendência a aumentar o número de linhas nos scripts para tentar diminuir o html
  4. PROBLEMAS ➤ Duplicação (dev/produção) ➤ Múltiplas requests bloqueando a renderização

    da página ➤ Atualização de versões tende a se tornar inviável
  5. O HTML QUE QUEREMOS <head> <link rel="stylesheet" href="style.css"> </head> <body>

    <div class=“container”>…</div> <script src="aplicacao.js"></script> </body>
  6. O HTML QUE QUEREMOS <head> <link rel="stylesheet" href="style.css"> </head> <body>

    <div class=“container”>…</div> <script src="aplicacao.js"></script> </body> <head> <link rel="stylesheet" href="style.css"> </head> <body> <div class=“container”>…</div> <script src="aplicacao.js"></script> </body>
  7. PRIMEIROS PASSOS ➤ Instalar o nodeJS e npm ➤ Iniciar

    um pacote do npm npm init . ➤ Instalar os pacotes npm install --save angular lodash materialize-css jquery ➤ Instalar o webpack npm install --save-dev webpack
  8. PRIMEIROS PASSOS ➤ Transformar a aplicação em módulos ➤ Em

    cada arquivo js ➤ Declarar as dependências ➤ Exportar o conteúdo de interesse
  9. PONTO DE ENTRADA DA APLICAÇÃO - SRC/INDEX.JS angular.module('app', []) .service('api',

    AgendaApi) .component('contato', { templateUrl: 'src/agenda/contato.html', bindings: { ngModel: '<' } }) .component('agenda', { templateUrl: 'src/agenda/agenda.html', controller: AgendaController });
  10. PONTO DE ENTRADA DA APLICAÇÃO - SRC/INDEX.JS angular.module('app', []) .service('api',

    AgendaApi) .component('contato', { templateUrl: 'src/agenda/contato.html', bindings: { ngModel: '<' } }) .component('agenda', { templateUrl: 'src/agenda/agenda.html', controller: AgendaController }); import angular from "angular"; import AgendaController from "./agenda/AgendaController"; import AgendaApi from "./agenda/AgendaApi"; angular.module('app', []) .service('api', AgendaApi) .component('contato', { templateUrl: 'src/agenda/contato.html', bindings: { ngModel: '<' } }) .component('agenda', { templateUrl: 'src/agenda/agenda.html', controller: AgendaController });
  11. MÓDULO - SRC/AGENDA/AGENDACONTROLLER.JS class AgendaController { constructor(api) { … }

    filtroPorNomeMudou() { … } filtrar(texto) { … } ordenacaoMudou() { … } selecionouContato(id) { … } } AgendaController.$inject = ["api"];
  12. MÓDULO - SRC/AGENDA/AGENDACONTROLLER.JS class AgendaController { constructor(api) { … }

    filtroPorNomeMudou() { … } filtrar(texto) { … } ordenacaoMudou() { … } selecionouContato(id) { … } } AgendaController.$inject = ["api"]; import _ from "lodash"; class AgendaController { constructor(api) { … } filtroPorNomeMudou() { … } filtrar(texto) { … } ordenacaoMudou() { … } selecionouContato(id) { … } } AgendaController.$inject = ["api"]; export default AgendaController;
  13. MÓDULO - SRC/AGENDA/AGENDAAPI.JS class AgendaApi { constructor($http) { … }

    getAgenda(pesquisa) { … } getContato(contatoId) { … } } AgendaApi.$inject = ["$http"];
  14. MÓDULO - SRC/AGENDA/AGENDAAPI.JS class AgendaApi { constructor($http) { … }

    getAgenda(pesquisa) { … } getContato(contatoId) { … } } AgendaApi.$inject = ["$http"]; class AgendaApi { constructor($http) { … } getAgenda(pesquisa) { … } getContato(contatoId) { … } } export default AgendaApi;
  15. CRIANDO A APLICAÇÃO sts-Manel:agenda $ node_modules/.bin/webpack src/index.js dist/aplicacao.js Hash: f172f9f7d090c75dad2d

    Version: webpack 2.6.1 Time: 667ms Asset Size Chunks Chunk Names aplicacao.js 1.8 MB 0 [emitted] [big] main [0] ./~/angular/index.js 48 bytes {0} [built] [1] ./src/agenda/AgendaApi.js 493 bytes {0} [built] [2] ./src/agenda/AgendaController.js 1.11 kB {0} [built] [3] ./~/angular/angular.js 1.25 MB {0} [built] [4] ./~/lodash/lodash.js 540 kB {0} [built] [5] ./src/index.js 448 bytes {0} [built] [6] (webpack)/buildin/global.js 509 bytes {0} [built] [7] (webpack)/buildin/module.js 517 bytes {0} [built]
  16. CRIANDO A APLICAÇÃO ➤ Execute o webpack que acabei de

    instalar neste caminho node_modules/.bin/webpack src/index.js dist/aplicacao.js
  17. CRIANDO A APLICAÇÃO ➤ Execute o webpack que acabei de

    instalar neste caminho ➤ Com o arquivo de entrada src/index.js node_modules/.bin/webpack src/index.js dist/aplicacao.js
  18. CRIANDO A APLICAÇÃO ➤ Execute o webpack que acabei de

    instalar neste caminho ➤ Com o arquivo de entrada src/index.js ➤ Escreva o resultado no arquivo dist/aplicacao.js node_modules/.bin/webpack src/index.js dist/aplicacao.js
  19. REDUÇÃO DE 28,57% NO Nº DE REQUESTS 4 8 12

    16 Nº DE REQUESTS 10 16 ORIGINAL WEBPACK
  20. REDUÇÃO DE 16% NO TEMPO DE CARREGAMENTO (ms) 700 800

    900 1000 TEMPO DE CARREGAMENTO (ms) 653 782 ORIGINAL WEBPACK
  21. REDUÇÃO DE 4% NO TEMPO DE CARREGAMENTO DO DOM (ms)

    678 785 893 1000 DOM CONTENT LOADED (ms) 575 596 ORIGINAL WEBPACK
  22. REDUÇÃO DE 4% NO LOAD TIME (ms) 678 785 893

    1000 LOAD TIME (ms) 576 603 ORIGINAL WEBPACK
  23. ACRÉSCIMO DE 334% DE DADOS TRANSFERIDOS! 550 1100 1650 2200

    TRANSFERENCIA DE DADOS (KB) 2.048 612 ORIGINAL WEBPACK
  24. const path = require("path"); module.exports = { entry: { "aplicacao":

    "./src/index.js" }, output: { path: path.resolve("./dist"), filename: "aplicacao.js" } }; CONFIGURAÇÃO MÍNIMA DO WEBPACK - WEBPACK.CONFIG.JS
  25. AUTOMATIZAR A GERAÇÃO DOS ARQUIVOS NO PACKAGE.JSON { "name": "agenda",

    "version": "1.0.0", "scripts": { "prebuild": "rm -rf dist && mkdir dist", "build": "webpack", “api:start”: “json-server --watch db.json" }, "devDependencies": { "json-server": "^0.10.1", "webpack": "^2.6.1", "webpack-dev-server": "^2.4.5" }, "dependencies": { "angular": "^1.6.4", "lodash": "^4.17.4", "materialize-css": "^0.98.2" } }
  26. AUTOMATIZAR A GERAÇÃO DOS ARQUIVOS NO PACKAGE.JSON { "name": "agenda",

    "version": "1.0.0", "scripts": { "prebuild": "rm -rf dist && mkdir dist", "build": "webpack", “api:start”: “json-server --watch db.json" }, "devDependencies": { "json-server": "^0.10.1", "webpack": "^2.6.1", "webpack-dev-server": "^2.4.5" }, "dependencies": { "angular": "^1.6.4", "lodash": "^4.17.4", "materialize-css": "^0.98.2" } } { "name": "agenda", "version": "1.0.0", "scripts": { "prebuild": "rm -rf dist && mkdir dist", "build": "webpack", “api:start”: “json-server --watch db.json" }, "devDependencies": { "json-server": "^0.10.1", "webpack": "^2.6.1", "webpack-dev-server": "^2.4.5" }, "dependencies": { "angular": "^1.6.4", "lodash": "^4.17.4", "materialize-css": "^0.98.2" } }
  27. AUTOMATIZAR A GERAÇÃO DOS ARQUIVOS NO PACKAGE.JSON { "name": "agenda",

    "version": "1.0.0", "scripts": { "prebuild": "rm -rf dist && mkdir dist", "build": "webpack", “api:start”: “json-server --watch db.json" }, "devDependencies": { "json-server": "^0.10.1", "webpack": "^2.6.1", "webpack-dev-server": "^2.4.5" }, "dependencies": { "angular": "^1.6.4", "lodash": "^4.17.4", "materialize-css": "^0.98.2" } } { "name": "agenda", "version": "1.0.0", "scripts": { "prebuild": "rm -rf dist && mkdir dist", "build": "webpack", “api:start”: “json-server --watch db.json" }, "devDependencies": { "json-server": "^0.10.1", "webpack": "^2.6.1", "webpack-dev-server": "^2.4.5" }, "dependencies": { "angular": "^1.6.4", "lodash": "^4.17.4", "materialize-css": "^0.98.2" } } { "name": "agenda", "version": "1.0.0", "scripts": { "prebuild": "rm -rf dist && mkdir dist", "build": "webpack", “api:start”: “json-server --watch db.json" }, "devDependencies": { "json-server": "^0.10.1", "webpack": "^2.6.1", "webpack-dev-server": "^2.4.5" }, "dependencies": { "angular": "^1.6.4", "lodash": "^4.17.4", "materialize-css": "^0.98.2" } }
  28. AUTOMATIZAR A GERAÇÃO DOS ARQUIVOS NO PACKAGE.JSON { "name": "agenda",

    "version": "1.0.0", "scripts": { "prebuild": "rm -rf dist && mkdir dist", "build": "webpack", “api:start”: “json-server --watch db.json" }, "devDependencies": { "json-server": "^0.10.1", "webpack": "^2.6.1", "webpack-dev-server": "^2.4.5" }, "dependencies": { "angular": "^1.6.4", "lodash": "^4.17.4", "materialize-css": "^0.98.2" } } { "name": "agenda", "version": "1.0.0", "scripts": { "prebuild": "rm -rf dist && mkdir dist", "build": "webpack", “api:start”: “json-server --watch db.json" }, "devDependencies": { "json-server": "^0.10.1", "webpack": "^2.6.1", "webpack-dev-server": "^2.4.5" }, "dependencies": { "angular": "^1.6.4", "lodash": "^4.17.4", "materialize-css": "^0.98.2" } } { "name": "agenda", "version": "1.0.0", "scripts": { "prebuild": "rm -rf dist && mkdir dist", "build": "webpack", “api:start”: “json-server --watch db.json" }, "devDependencies": { "json-server": "^0.10.1", "webpack": "^2.6.1", "webpack-dev-server": "^2.4.5" }, "dependencies": { "angular": "^1.6.4", "lodash": "^4.17.4", "materialize-css": "^0.98.2" } } { "name": "agenda", "version": "1.0.0", "scripts": { "prebuild": "rm -rf dist && mkdir dist", "build": "webpack", “api:start”: “json-server --watch db.json" }, "devDependencies": { "json-server": "^0.10.1", "webpack": "^2.6.1", "webpack-dev-server": "^2.4.5" }, "dependencies": { "angular": "^1.6.4", "lodash": "^4.17.4", "materialize-css": "^0.98.2" } }
  29. AUTOMATIZAR A GERAÇÃO DOS ARQUIVOS NO PACKAGE.JSON { "name": "agenda",

    "version": "1.0.0", "scripts": { "prebuild": "rm -rf dist && mkdir dist", "build": "webpack", “api:start”: “json-server --watch db.json" }, "devDependencies": { "json-server": "^0.10.1", "webpack": "^2.6.1", "webpack-dev-server": "^2.4.5" }, "dependencies": { "angular": "^1.6.4", "lodash": "^4.17.4", "materialize-css": "^0.98.2" } } { "name": "agenda", "version": "1.0.0", "scripts": { "prebuild": "rm -rf dist && mkdir dist", "build": "webpack", “api:start”: “json-server --watch db.json" }, "devDependencies": { "json-server": "^0.10.1", "webpack": "^2.6.1", "webpack-dev-server": "^2.4.5" }, "dependencies": { "angular": "^1.6.4", "lodash": "^4.17.4", "materialize-css": "^0.98.2" } } { "name": "agenda", "version": "1.0.0", "scripts": { "prebuild": "rm -rf dist && mkdir dist", "build": "webpack", “api:start”: “json-server --watch db.json" }, "devDependencies": { "json-server": "^0.10.1", "webpack": "^2.6.1", "webpack-dev-server": "^2.4.5" }, "dependencies": { "angular": "^1.6.4", "lodash": "^4.17.4", "materialize-css": "^0.98.2" } } { "name": "agenda", "version": "1.0.0", "scripts": { "prebuild": "rm -rf dist && mkdir dist", "build": "webpack", “api:start”: “json-server --watch db.json" }, "devDependencies": { "json-server": "^0.10.1", "webpack": "^2.6.1", "webpack-dev-server": "^2.4.5" }, "dependencies": { "angular": "^1.6.4", "lodash": "^4.17.4", "materialize-css": "^0.98.2" } } { "name": "agenda", "version": "1.0.0", "scripts": { "prebuild": "rm -rf dist && mkdir dist", "build": "webpack", “api:start”: “json-server --watch db.json" }, "devDependencies": { "json-server": "^0.10.1", "webpack": "^2.6.1", "webpack-dev-server": "^2.4.5" }, "dependencies": { "angular": "^1.6.4", "lodash": "^4.17.4", "materialize-css": "^0.98.2" } }
  30. AUTOMATIZAR A GERAÇÃO DOS ARQUIVOS NO PACKAGE.JSON { "name": "agenda",

    "version": "1.0.0", "scripts": { "prebuild": "rm -rf dist && mkdir dist", "build": "webpack", “api:start”: “json-server --watch db.json" }, "devDependencies": { "json-server": "^0.10.1", "webpack": "^2.6.1", "webpack-dev-server": "^2.4.5" }, "dependencies": { "angular": "^1.6.4", "lodash": "^4.17.4", "materialize-css": "^0.98.2" } } { "name": "agenda", "version": "1.0.0", "scripts": { "prebuild": "rm -rf dist && mkdir dist", "build": "webpack", “api:start”: “json-server --watch db.json" }, "devDependencies": { "json-server": "^0.10.1", "webpack": "^2.6.1", "webpack-dev-server": "^2.4.5" }, "dependencies": { "angular": "^1.6.4", "lodash": "^4.17.4", "materialize-css": "^0.98.2" } } { "name": "agenda", "version": "1.0.0", "scripts": { "prebuild": "rm -rf dist && mkdir dist", "build": "webpack", “api:start”: “json-server --watch db.json" }, "devDependencies": { "json-server": "^0.10.1", "webpack": "^2.6.1", "webpack-dev-server": "^2.4.5" }, "dependencies": { "angular": "^1.6.4", "lodash": "^4.17.4", "materialize-css": "^0.98.2" } } { "name": "agenda", "version": "1.0.0", "scripts": { "prebuild": "rm -rf dist && mkdir dist", "build": "webpack", “api:start”: “json-server --watch db.json" }, "devDependencies": { "json-server": "^0.10.1", "webpack": "^2.6.1", "webpack-dev-server": "^2.4.5" }, "dependencies": { "angular": "^1.6.4", "lodash": "^4.17.4", "materialize-css": "^0.98.2" } } { "name": "agenda", "version": "1.0.0", "scripts": { "prebuild": "rm -rf dist && mkdir dist", "build": "webpack", “api:start”: “json-server --watch db.json" }, "devDependencies": { "json-server": "^0.10.1", "webpack": "^2.6.1", "webpack-dev-server": "^2.4.5" }, "dependencies": { "angular": "^1.6.4", "lodash": "^4.17.4", "materialize-css": "^0.98.2" } } { "name": "agenda", "version": "1.0.0", "scripts": { "prebuild": "rm -rf dist && mkdir dist", "build": "webpack", “api:start”: “json-server --watch db.json" }, "devDependencies": { "json-server": "^0.10.1", "webpack": "^2.6.1", "webpack-dev-server": "^2.4.5" }, "dependencies": { "angular": "^1.6.4", "lodash": "^4.17.4", "materialize-css": "^0.98.2" } }
  31. {
 …,
 devServer: { port: 8000, proxy: { "/api/**": {

    target: "http://localhost:3000/", logLevel: "info", pathRewrite: {"^/api" : ""} } } } } CONFIGURAÇÃO DO WEBPACK-DEV-SERVER
  32. EXECUTANDO O WEBPACK-DEV-SERVER { …, "scripts": { "prebuild": "rm -rf

    dist && mkdir dist", "build": "webpack", "prestart": "npm run api:start", "start": "webpack-dev-server", "api:start": "json-server --watch db.json" }, "devDependencies": { …, "webpack-dev-server": "^2.5.0" } }
  33. O QUE JÁ TEMOS ATÉ AGORA ➤ Dependências com número

    de versão ➤ Arquivo único com todo o código da aplicação gerado automaticamente ➤ Diminuição do número de requests ➤ Frontend independente do Backend ➤ Hot deploy
  34. WEBPACK LOADERS ➤ Carregam algum recurso e transformam em um

    módulo da aplicação disponível para ser importado. Ex: ➤ babel-loader: Carrega arquivos ES6, ES7 e compila para ES5 ➤ style-loader: Carrega arquivos .css e cria tags style com o conteúdo desses arquivos ➤ image-loader: Carrega imagens, checa o tamanho, codifica no formato base64 ou gera um link com um nome único ➤ html-loader: Carrega arquivos HTML e injeta no código javascript ➤ sass-loader: Carrega arquivos .scss e transforma em css
  35. module: { rules: [ { test: /\.js$/, exclude: /node_modules/, use:

    { loader: "babel-loader", options: { presets: ["env"] } } } ] } COMPILANDO O CÓDIGO PARA ES5 COM BABELJS - WEBPACK LOADERS
  36. COMPILANDO O CÓDIGO PARA ES5 COM BABELJS - WEBPACK LOADERS

    export default class AgendaApi { constructor($http) { this.$http = $http; } getAgenda(pesquisa) { const params = { params: { 'q': pesquisa, '_limit': 10 } }; return this.$http .get('/api/contatos', params) .then(response => response.data); } getContato(contatoId) { return this.$http .get(`/api/contatos/${contatoId}`) .then(response => response.data); } }
  37. COMPILANDO O CÓDIGO PARA ES5 COM BABELJS - WEBPACK LOADERS

    function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var AgendaApi = function () { function AgendaApi($http) { _classCallCheck(this, AgendaApi); this.$http = $http; } _createClass(AgendaApi, [{ key: 'getAgenda', value: function getAgenda(pesquisa) { var params = { params: { 'q': pesquisa, '_limit': 10 } }; return this.$http.get('/api/contatos', params).then(function (response) { return response.data; }); } }, { key: 'getContato', value: function getContato(contatoId) { return this.$http.get('/api/contatos/' + contatoId).then(function (response) { return response.data; }); } }]); return AgendaApi; }(); exports.default = AgendaApi; /***/ })
  38. WEBPACK PLUGINS ➤ Trechos de código que agregam novas funcionalidades

    ao webpack ➤ UglifyjsPlugin: Provê minificação e ofuscação de código ES5 ➤ CommonsChunkPlugin: Permite a separação do código de bibliotecas do código da aplicação possibilitando o uso de cache ➤ CompressionWebpackPlugin: Gera arquivos comprimidos com gzip ➤ ExtractTextWebpackPlugin: Extrai texto de um ou mais bundles para um ou mais arquivo(s) específico(s) ➤ PurifyCssPlugin: Examina o css gerado e remove seletores não utilizados
  39. const webpack = require(“webpack"); module.exports = { …, plugins: [

    new webpack.DefinePlugin({ "process.env.NODE_ENV": JSON.stringify("production") }), new webpack.optimize.UglifyJsPlugin({ debug: false, minimize: true, sourceMap: false, compress: { warnings: false } }) ] }; WEBPACK PLUGINS - MINIFICAÇÃO E OFUSCAÇÃO
  40. MINIFICANDO O CÓDIGO GERADO COM UGLIFYJS - WEBPACK PLUGINS function(module,

    exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var AgendaApi = function () { function AgendaApi($http) { _classCallCheck(this, AgendaApi); this.$http = $http; } _createClass(AgendaApi, [{ key: 'getAgenda', value: function getAgenda(pesquisa) { var params = { params: { 'q': pesquisa, '_limit': 10 } }; return this.$http.get('/api/contatos', params).then(function (response) { return response.data; }); } }, { key: 'getContato', value: function getContato(contatoId) { return this.$http.get('/api/contatos/' + contatoId).then(function (response) { return response.data; }); } }]); return AgendaApi; }(); exports.default = AgendaApi; /***/ })
  41. MINIFICANDO O CÓDIGO GERADO COM UGLIFYJS - WEBPACK PLUGINS function

    a(t,n){"use strict";function e(t,n){if(!(t instanceof n))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(n,"__esModule",{value:!0});var r=function(){function t(t,n){for(var e=0;e<n.length;e++){var r=n[e];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=! 0),Object.defineProperty(t,r.key,r)}}return function(n,e,r){return e&&t(n.prototype,e),r&&t(n,r),n}} (),a=function(){function t(n){e(this,t),this.$http=n}return r(t,[{key:"getAgenda",value:function(t){var n={params:{q:t,_limit:10}};return this.$http.get("/api/contatos",n).then(function(t){return t.data})}}, {key:"getContato",value:function(t){return this.$http.get("/api/contatos/"+t).then(function(t){return t.data})}}]),t}();n.default=a}
  42. new webpack.optimize.CommonsChunkPlugin({ name: "vendor.js", minChunks: function (module) { return (

    module.context && module.context .indexOf("node_modules") !== -1 ); } }) WEBPACK PLUGINS - VENDOR SPLIT COM COMMONS CHUNK PLUGIN
  43. REDUÇÃO DE ~56% NO Nº DE REQUESTS 4 8 12

    16 Nº DE REQUESTS 7 8 16 ORIGINAL WEBPACK DEV WEBPACK PROD
  44. REDUÇÃO DE ~30% DE DADOS TRANSFERIDOS! 2000 4000 6000 8000

    TRANSFERENCIA DE DADOS (KB) 379 7.884,8 539 ORIGINAL WEBPACK DEV WEBPACK PROD
  45. REDUÇÃO DE ~23% NO TEMPO DE CARREGAMENTO TOTAL (ms) 500

    1000 1500 2000 TEMPO DE CARREGAMENTO TOTAL (ms) 1.370 1.330 1.790 ORIGINAL WEBPACK DEV WEBPACK PROD
  46. REDUÇÃO DE ~36% NO TEMPO DE CARREGAMENTO DO DOM (ms)

    500 1000 1500 2000 DOM CONTENT LOADED (ms) 917 1.170 1.440 ORIGINAL WEBPACK DEV WEBPACK PROD
  47. REDUÇÃO DE ~4% NO LOAD TIME (ms) 1400 1600 1800

    2000 LOAD TIME (ms) 1.380 1.260 1.440 ORIGINAL WEBPACK DEV WEBPACK PROD
  48. APLICAÇÕES NO HEROIC ➤ Sem Webpack ➤ https://javou-10-agenda.herokuapp.com/ ➤ Com

    Webpack ➤ http://javou-10-agenda-webpack.herokuapp.com/ ➤ Código no GitHub ➤ https://github.com/marceloemanoel/javou-10-agenda