Sie sind hier: Weblog

Angular 2 in Web Worker auslagern

Foto ,
06.12.2015 01:00:00

Angular 2 bietet mit seiner flexiblen Rendering-Architektur neben der Möglichkeit eines Server-seitigen Renderings auch die Möglichkeit, den großteil der der Anwendung in einen Web Worker auszulagern. Dies erhöht die Performance der Anwendung sowie ihr Reaktionsverhalten.

Nutzt man diese Möglichkeit, ist man mit zwei Teilen von Angular 2 konfrontiert: Der eine läuft mit dem Anwendungscode im Web Worker; der andere wird im "UI-Thread" des Browsers ausgeführt und kümmert sich um die Aktualisierung des DOM.

In diesem Beitrag, der auf [1] aufbaut, zeige ich, wie man eine Angular 2 Anwendung für den Betrieb mit Web Worker auslagern kann. Dabei orientiere ich mich an den Informationen aus [2]. Das Ergebnis findet man auch im Beispiel unter [3].

Schritt-für-Schritt-Beschreibung

Zum Bootstrapping der Anwendung eine Datei app/index.ts bereitstellen. Diese ist u. a. für das Laden des Codes in den Web Worker verantwortlich. Daneben übernimmt sie die Kommunikation mit dem Web Worker:

import {platform, Provider} from "angular2/core";
import {WORKER_RENDER_PLATFORM, WORKER_RENDER_APP , WORKER_SCRIPT} from "angular2/platform/worker_render";

platform([WORKER_RENDER_PLATFORM])
    .application([
        WORKER_RENDER_APP, 
        new Provider(WORKER_SCRIPT, {useValue: "/app/loader.js"})]);

Die Datei app/loader.ts, welche im letzten Listing referenziert wurde, anlegen. Sie importiert u. a. die Datei worker.dev.js. Dabei handelt es sich um jenen Teil von Angular 2, der im Web Worker läuft. Am Ende delegiert sie an das Kompilat der Datei app.ts. Diese kümmert sich um das Bootstrapping der Root-Component im Web-Worker:

declare var System: any;

importScripts(
    "https://cdnjs.cloudflare.com/ajax/libs/es6-shim/0.33.3/es6-shim.js", 
    "../node_modules/systemjs/dist/system.src.js", 
    "../node_modules/angular2/bundles/web_worker/worker.dev.js");

System.import("app.js");

Die Datei app.ts wie folgt gezeigt anpassen. Wichtig ist hier auch die Tatsache, dass das Modul angular2/platform/worker_app referenziert wird. Dieses beinhaltet Teile von Angular 2, die in Web Workern laufen.

import { Component, View, platform } from "angular2/core";
import { WORKER_APP_PLATFORM, setupWebWorker } from angular2/platform/worker_app;

@Component({
    selector: my-app,
    template: <h1>My First Angular 2 App!</h1>
})
class AppComponent { }


platform([WORKER_APP_PLATFORM])
    .asyncApplication(setupWebWorker)
    .then((ref) => ref.bootstrap(AppComponent));

Die Datei index.html anpassen, sodass sie anstatt dem Bundle angular.dev.js das Bundle ui.dev.js referenziert. Dieses ist bei Nutzung von Web-Workern für die Ausführung im "UI-Thread" gedacht:

<html>
  <head>
    <title>Angular 2 QuickStart</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/es6-shim/0.33.3/es6-shim.js"></script>
    <script src="node_modules/systemjs/dist/system.src.js"></script>
    <script src="node_modules/angular2/bundles/web_worker/ui.dev.js"></script>

    <script>
      System.config({
        packages: {app: {defaultExtension: js}}
      });
      System.import(app/index);
    </script>
  </head>
  <body>
    <my-app>loading...</my-app>
  </body>
</html>

Kompilieren und die Anwendung ausführen.

[1] http://www.softwarearchitekt.at/post/2015/07/21/visual-studio-code-mit-typescript-und-angular-2-nutzen.aspx
[2] https://github.com/angular/angular/blob/master/modules/angular2/docs/web_workers/web_workers.md
[3] https://github.com/manfredsteyer/angular2-web-worker