tutorial proyecto iniciar español crear change angular web-worker

proyecto - iniciar angular



Aplicación CLI angular generada con Web Workers (2)

Al leer la documentación angular, puede encontrar varias referencias para iniciar su aplicación Angular completa dentro de un Web Worker , para que su UI no se bloquee por el uso intensivo de JS.

Sin embargo, en este momento no hay información oficial sobre cómo hacer eso, y la única información en Angular Doc. es que esta es una característica experimental.

¿Cómo puedo usar este enfoque para aprovechar a los trabajadores web en Angular?


Buenas noticias chicos, ¡tengo esto para trabajar con Angular 7! 🎉🎉🎉

Requisito : npm install --save-dev @angular-builders/custom-webpack html-webpack-plugin Asegúrese de tener production:true en su archivo env si solo desea copiar / pegar el código desde abajo.

Paso 1 : Edite su archivo angular.json de la siguiente manera:

"architect": { "build": { "builder": "@angular-builders/custom-webpack:browser", "options": { "customWebpackConfig": { "path": "./webpack.client.config.js", "replaceDuplicatePlugins": true }, ... }

Solo está editando la parte de build porque realmente no necesita todo el elemento trabajador en el servidor de desarrollo.

Paso 2 : Cree el archivo webpack.client.config.js en la raíz de su proyecto. Si no está utilizando SSR, puede eliminar la exclude: [''./server.ts''],

const path = require(''path''); const webpack = require(''webpack''); const HtmlWebpackPlugin = require(''html-webpack-plugin''); const { AngularCompilerPlugin } = require(''@ngtools/webpack''); module.exports = { entry: { webworker: [ "./src/workerLoader.ts" ], main: [ "./src/main.ts" ], polyfills: [ "./src/polyfills.ts" ] }, plugins: [ new HtmlWebpackPlugin({ template: ''./src/index.html'', excludeChunks: [ "webworker" ], chunksSortMode: "none" }), new AngularCompilerPlugin({ mainPath: "./src/main.ts", entryModule: ''./src/app/app.module#AppModule'', tsConfigPath: "src/tsconfig.app.json", exclude: [''./server.ts''], sourceMap: true, platform: 0 }), ], optimization: { splitChunks: { name: "inline" } } }

Paso 3 : Edita tu AppModule:

import { BrowserModule } from ''@angular/platform-browser'' import { WorkerAppModule } from ''@angular/platform-webworker''

const AppBootstrap = environment.production ? WorkerAppModule : BrowserModule.withServerTransition({ appId: ''myApp'' })

imports: [ ... AppBootstrap, ... ]

Paso 4 : edita tu archivo main.ts.

import { enableProdMode } from ''@angular/core''; import { platformBrowserDynamic } from ''@angular/platform-browser-dynamic''; import { bootstrapWorkerUi } from ''@angular/platform-webworker''; import {AppModule} from ''./app/app.module''; import {environment} from ''./environments/environment''; if (environment.production) { enableProdMode(); bootstrapWorkerUi(''webworker.bundle.js''); } else { document.addEventListener(''DOMContentLoaded'', () => { platformBrowserDynamic().bootstrapModule(AppModule); }); }

Paso 5 : se compilará bien, pero es posible que tenga un problema de tiempo de ejecución debido a la manipulación del DOM en su aplicación. En este punto, solo tiene que eliminar cualquier manipulación DOM y reemplazarla por otra cosa. Todavía estoy trabajando para resolver esta parte y editaré mi respuesta más tarde para dar instrucciones sobre este problema.

Si no está haciendo una manipulación DOM salvaje, entonces es bueno ir con un hilo principal gratuito y auditar su aplicación usando lighthouse ya no debería mostrar Minimize main-thread work , ya que la mayoría de su aplicación, excepto la IU, se carga en un segundo hilo.


Para Angular 7, vea la respuesta a continuación.

Pasé mucho tiempo para descubrir cómo hacerlo, así que espero que esto pueda ayudar a alguien .

Condiciones previas

Supongo que tiene un proyecto Angular (versión 2 o 4) generado con Angular CLI 1.0 o superior.

No es obligatorio generar el proyecto con CLI para seguir estos pasos, pero las instrucciones que daré relacionadas con el archivo del paquete web se basan en la configuración del paquete web CLI.

Pasos

1. Extraer el archivo webpack

Desde Angular CLI v1.0, existe la función de "expulsión", que le permite extraer el archivo de configuración del paquete web y manipularlo como desee.

  • Ejecute ng eject para que Angular CLI genere el archivo webpack.config.js .

  • Ejecute npm install para que se satisfagan las nuevas dependencias generadas por CLI

2. Instalar dependencias de arranque de webworker

Ejecute npm install --save @angular/platform-webworker @angular/platform-webworker-dynamic

3. Cambios en el arranque de subprocesos de la interfaz de usuario

3.1 Cambios en app.module.ts

Reemplace BrowserModule por WorkerAppModule en el archivo app.module.ts. También deberá actualizar la declaración de importación para usar la biblioteca @angular/platform-webworker .

//src/app/app.module.ts import { WorkerAppModule } from ''@angular/platform-webworker''; import { NgModule } from ''@angular/core''; import { AppComponent } from ''./app.component''; //...other imports... @NgModule({ declarations: [ AppComponent ], imports: [ WorkerAppModule, //...other modules... ], providers: [/*...providers...*/], bootstrap: [AppComponent] }) export class AppModule { }

3.2 Cambios en src / main.ts

Reemplace el proceso bootstrap con: bootstrapWorkerUI (actualice también la importación).

Deberá pasar una URL con el archivo donde está definido el trabajador web. Use un archivo llamado webworker.bundle.js , no se preocupe, crearemos este archivo pronto.

//main.ts import { enableProdMode } from ''@angular/core''; import { bootstrapWorkerUi } from ''@angular/platform-webworker''; import { AppModule } from ''./app/app.module''; import { environment } from ''./environments/environment''; if (environment.production) { enableProdMode(); } bootstrapWorkerUi(''webworker.bundle.js'');

3.3 Crear archivo workerLoader.ts

  • Cree un nuevo archivo src / workerLoader.ts .
  • Como su Web Worker será un solo archivo que contiene todo lo necesario, debe incluir @angular/common paquetes polyfills.ts , @angular/core y @angular/common . En los próximos pasos, actualizará Webpack para transpilar y crear un paquete con el resultado.
  • Importar platformWorkerAppDynamic
  • Importe el AppModule (elimine la importación de main.ts ) y arranque utilizando esta platformWorkerAppDynamic platformWorkerAppDynamic.

// workerLoader.ts import ''polyfills.ts''; import ''@angular/core''; import ''@angular/common''; import { platformWorkerAppDynamic } from ''@angular/platform-webworker-dynamic''; import { AppModule } from ''./app/app.module''; platformWorkerAppDynamic().bootstrapModule(AppModule);

4. Actualice webpack para construir su webworker

El archivo de configuración generado automáticamente por webpack es bastante largo, pero solo deberá centrar su atención en lo siguiente:

  • Agregue un punto de entrada de webworker para nuestro archivo workerLoader.ts . Si observa la salida, verá que adjunta un prefijo bundle.js a todos los fragmentos. Es por eso que durante el paso de arranque hemos utilizado webworker.bundle.js

  • Vaya a HtmlWebpackPlugin y excluya el punto de entrada de webworker , por lo que el archivo Web Worker generado no se incluye en el archivo index.html.

  • Vaya a CommonChunksPlugin y, para el fragmento común en inline , configure los fragmentos de entrada explícitamente para evitar que se webworker al webworker .

  • Vaya a AotPlugin y configure explícitamente el entryModule

// webpack.config.js //...some stuff... const HtmlWebpackPlugin = require(''html-webpack-plugin''); const { CommonsChunkPlugin } = require(''webpack'').optimize; const { AotPlugin } = require(''@ngtools/webpack''); //...some stuff... module.exports = { //...some stuff... "entry": { "main": [ "./src/main.ts" ], "polyfills": [ "./src/polyfills.ts" ], "styles": [ "./src/styles.css" ], "webworker": [ "./src/workerLoader.ts" ] }, "output": { "path": path.join(process.cwd(), "dist"), "filename": "[name].bundle.js", "chunkFilename": "[id].chunk.js" }, "module": { /*...a lot of stuff...*/ }, "plugins": [ //...some stuff... new HtmlWebpackPlugin({ //...some stuff... "excludeChunks": [ "webworker" ], //...some more stuff... }), new BaseHrefWebpackPlugin({}), new CommonsChunkPlugin({ "name": "inline", "minChunks": null, "chunks": [ "main", "polyfills", "styles" ] }), //...some stuff... new AotPlugin({ "mainPath": "main.ts", "entryModule": "app/app.module#AppModule", //...some stuff... }) ], //...some more stuff... };

Estas listo

Si ha seguido correctamente los pasos anteriores, ahora solo necesita compilar el código y probar los resultados.

Ejecute npm start

Toda la lógica de su aplicación Angular debería estar ejecutándose dentro de un WebWorker, haciendo que la IU sea más fluida.

Notas adicionales

npm start ejecuta el servidor webpack-dev , y tiene algún tipo de problema con los trabajadores web que arrojan un mensaje de error en el registro de la consola. De todos modos, el trabajador web parece funcionar bien. Si compila la aplicación usando el comando webpack y la sirve desde cualquier servidor http como simplehttpserver , el error desaparece;)

Código de muestra y demostración

Puede obtener el código completo (webpack config, app.module.ts, ...) de este repositorio .

También puede ver aquí una demostración en vivo , para ver las diferencias entre usar Web Workers o no