Angular CLI generated app with Web Workers -
reading angular documentation, can find several references bootstrap whole angular app inside web worker, ui won't blocked heavy js usage.
however, @ moment there's no official information on how that, , info in angular doc. experimental feature.
how can use approach take advantage of web workers in angular?
i spent lot of time figure out how it, hope this can someone.
preconditions
i’m assuming have angular project (version 2 or 4) generated angular cli 1.0 or higher.
it not mandatory generate project cli follow steps, instructions i'll give related webpack file, based on cli webpack config.
steps
1. extract webpack file
since angular cli v1.0, there’s “eject” feature, allows extract webpack config file , manipulate wish.
run
ng ejectangular cli generates webpack.config.js file.run
npm installnew dependencies generated cli satisfied
2. install webworker bootstrap dependencies
run npm install --save @angular/platform-webworker @angular/platform-webworker-dynamic
3. changes in ui thread bootstrap
3.1 changes in app.module.ts
replace browsermodule workerappmodule in app.module.ts file. you’ll need update import statement in order use @angular/platform-webworker library.
//src/app/app.module.ts import { workerappmodule } '@angular/platform-webworker'; import { ngmodule } '@angular/core'; import { appcomponent } './app.component'; //...other imports... @ngmodule({ declarations: [ appcomponent ], imports: [ workerappmodule, //...other modules... ], providers: [/*...providers...*/], bootstrap: [appcomponent] }) export class appmodule { } 3.2 changes in src/main.ts
replace bootstrap process with: bootstrapworkerui (update import).
you’ll need pass url file web worker defined. use file called webworker.bundle.js, don’t worry, create file soon.
//main.ts import { enableprodmode } '@angular/core'; import { bootstrapworkerui } '@angular/platform-webworker'; import { appmodule } './app/app.module'; import { environment } './environments/environment'; if (environment.production) { enableprodmode(); } bootstrapworkerui('webworker.bundle.js'); 3.3 create workerloader.ts file
- create new file src/workerloader.ts.
- as web worker single file containing required stuff, need include
polyfills.ts,@angular/core, ,@angular/commonpackages. on next steps, update webpack in order transpile , build bundle result. - import
platformworkerappdynamic - import
appmodule(remove import main.ts) , bootstrap usingplatformworkerappdynamicplatform.
// workerloader.ts import 'polyfills.ts'; import '@angular/core'; import '@angular/common'; import { platformworkerappdynamic } '@angular/platform-webworker-dynamic'; import { appmodule } './app/app.module'; platformworkerappdynamic().bootstrapmodule(appmodule); 4. update webpack build webworker
the webpack auto generated config file quite long, you’ll need center attention in following things:
add
webworkerentry point ourworkerloader.tsfile. if @ output, you’ll see attaches bundle.js prefix chunks. that’s why during bootstrap step have usedwebworker.bundle.jsgo htmlwebpackplugin , exclude
webworkerentry point, generated web worker file not included in index.html file.go commonchunksplugin, ,
inlinecommon chunk, set entry chunks explicitely preventwebworkerincluded.go aotplugin , set explicitely
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... }; you’re ready
if have followed correctly previous steps, need compile code , try results.
run npm start
all logic of angular app should running inside webworker, causing ui more fluent.
furter notes
npm start runs webpack-dev server, , has kind of problem webworkers throwing error message on console log. anyway, webworker seems run fine. if compile app using webpack command , serve http server simplehttpserver, error goes away ;)
sample code , demo
you can whole code (webpack config, app.module.ts, ...) this repo.
you can watch here live demo, check out differences between using web workers or not
Comments
Post a Comment