Angularドキュメントを読むと、いくつかの 参照bootstrapあなたの全体Angularアプリ内のWeb Worker ので、JSが頻繁に使用されてもUIはブロックされません。
ただし、現時点ではその方法に関する公式情報はなく、Angular Doc。の唯一の情報は、これが実験的な機能であることです。
この方法を使用してAngularのWebワーカーを活用するにはどうすればよいですか?
Angular 7については、以下の回答を参照してください。
私はそれを行う方法を見つけるために多くの時間を費やしたので、私は これが誰かを助けることができる を願っています。
Angular CLI 1.0以降で生成されたAngularプロジェクト(バージョン2または4)があると仮定しています。
この手順に従うためにCLIでプロジェクトを生成することは必須ではありませんが、webpackファイルに関連して説明する手順は、CLI webpack構成に基づいています。
Angular CLI v1.0以降、「取り出し」機能があり、webpack構成ファイルを抽出して、必要に応じて操作できます。
ng eject
を実行して、Angular CLIがwebpack.config.jsファイルを生成します。
npm install
を実行して、CLIによって生成された新しい依存関係が満たされるようにします
npm install --save @angular/platform-webworker @angular/platform-webworker-dynamic
を実行します
App.module.tsファイルのBrowserModule
をWorkerAppModule
に置き換えます。 @angular/platform-webworker
ライブラリを使用するには、importステートメントを更新する必要もあります。
//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 { }
bootstrapプロセスをbootstrapWorkerUI
に置き換えます(インポートも更新します)。
ウェブワーカーが定義されているファイルにURLを渡す必要があります。 webworker.bundle.js
というファイルを使用してください。心配しないでください。このファイルはすぐに作成されます。
//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');
polyfills.ts
、@angular/core
、および@angular/common
パッケージを含める必要があります。次のステップで、Webpackを更新して、結果を含むバンドルをトランスパイルおよびビルドします。platformWorkerAppDynamic
AppModule
をインポートします(main.tsからインポートを削除します)およびbootstrapを使用して、この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);
自動生成されるwebpackの構成ファイルは非常に長いですが、次のことに注意を集中する必要があります。
workerLoader.ts
ファイルにwebworker
entry pointを追加します。出力を見ると、すべてのチャンクにbundle.jsプレフィックスが付加されていることがわかります。 bootstrapステップでwebworker.bundle.js
を使用したのはそのためです
HtmlWebpackPluginに移動し、webworker
エントリポイントを除外するため、生成されたWeb Workerファイルはindex.htmlファイルに含まれません。
CommonChunksPluginに移動し、inline
共通チャンクに対して、webworker
が含まれないようにエントリチャンクを明示的に設定します。 。
AotPluginに移動し、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...
};
前の手順を正しく実行したら、コードをコンパイルして結果を試すだけで済みます。
npm start
を実行します
AngularアプリのすべてのロジックがWebWorker内で実行されている必要があり、UIがより流toになります。
npm start
はwebpack-dev serverを実行しますが、Webworkerがコンソールログにエラーメッセージを投げるという問題があります。とにかく、ウェブワーカーは正常に動作しているようです。 webpack
コマンドを使用してアプリをコンパイルし、 simplehttpserver などのhttpサーバーから提供すると、エラーはなくなります;)
this repo からコード全体(webpack config、app.module.ts、...)を取得できます。
また、ここで live demo を見て、Web Workersを使用するかどうかの違いを確認することもできます。
良いニュースだ、私はこれをAngular 7!????????????
要件:npm install --save-dev @angular-builders/custom-webpack html-webpack-plugin
単にしたい場合は、envファイルにproduction:true
があることを確認してください以下からコードをコピー/貼り付けます。
ステップ1:次の方法で、angle.jsonファイルを編集します。
"architect": {
"build": {
"builder": "@angular-builders/custom-webpack:browser",
"options": {
"customWebpackConfig": {
"path": "./webpack.client.config.js",
"replaceDuplicatePlugins": true
},
...
}
開発サーバーではワーカー全体を実際に必要としないため、build
部分のみを編集しています。
ステップ2:プロジェクトのルートにwebpack.client.config.js
ファイルを作成します。 SSRを使用していない場合は、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"
}
}
}
ステップ3:AppModuleを編集します:
import { BrowserModule } from '@angular/platform-browser'
import { WorkerAppModule } from '@angular/platform-webworker'
const AppBootstrap =
environment.production
? WorkerAppModule
: BrowserModule.withServerTransition({ appId: 'myApp' })
imports: [
...
AppBootstrap,
...
]
ステップ4: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);
});
}
ステップ5:正常にコンパイルされますが、アプリのDOM操作が原因で実行時の問題が発生する可能性があります。この時点で、DOM操作をすべて削除し、別のものに置き換えるだけで済みます。私はまだこの部分を理解することに取り組んでおり、この問題に関する指示を与えるために後で私の答えを編集します。
野avなDOM操作を行っていない場合は、無料のメインスレッドを使用して、lighthouseを使用したアプリの監査でMinimize main-thread work
が表示されないようにすることをお勧めします。糸。