Mathias Schütz

Angular Entwickler

Ionic Entwickler

C# Entwickler

Mathias Schütz

Angular Entwickler

Ionic Entwickler

C# Entwickler

Blogeintrag

Angular – Maximale Performance

16. Dezember 2019 Allgemein
Angular – Maximale Performance

Hallo zusammen, in diesem Beitrag möchte ich euch meine Konfiguration zeigen, mit der ihr die maximale Performance aus eurer Angular Applikation rausholen könnt.

Zunächst einmal eine Zusammenfassung meiner aktuellen Konfiguration, die ich in meiner lokalen Entwicklung und beim Deployen auf Windows-Servern benutze:

  • Angular 9 mit aktiviertem Ivy, Lazy-Loading über Routing und differenziales Laden
  • Angular CLI
  • nginx in seiner letzten stabilen Version
  • Neuester Windows-Server

Angular 9

Konfiguration

Wir gehen davon aus, das du bereits eine Angular Anwendung hast und das größtmögliche Potential an Performance rausholen möchtest.

In deiner angular.json unter projects -> app -> architect -> build -> options fügen wir einen weiteren Tag "aot": true ein. Damit aktivieren wir das Ahead-of-Time (AOT) Kompilieren unserer Applikation. Ein Browser, der unsere Applikation nun lädt, muss in dem Fall nicht mehr viel Arbeit in das Laden unserer Anwendung stecken und kann die Startseite schneller anzeigen. Zudem ist diese Einstellung eine Voraussetzung für den Ivy-Compiler, dazu später mehr. Neben AOT brauchen wir noch folgende Einstellungen. Unter projects -> app -> architect -> build -> configurations -> production fügen wir folgende Optionen hinzu:

...
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
"extractCss": true,
"namedChunks": false,
"extractLicenses": true,
"vendorChunk": false,
 "buildOptimizer": true,
...

In unserer tsconfig.json fügen wir das hier ein:

{
  "compileOnSave": false,
  "compilerOptions": {
    "outDir": "./dist/out-tsc",
    "sourceMap": true,
    "declaration": false,
    "module": "esnext",
    "moduleResolution": "node",
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "importHelpers": true,
    "target": "es2015",
    "typeRoots": [
      "node_modules/@types"
    ],
    "lib": [
      "esnext",
      "dom"
    ]
  }
}

Damit gewährleisten wir kleine Bundles und kein unnötigen Code in unserer produktiven Umgebung.

Angular Ivy

In Angular 9 ist Ivy bereits automatisch aktiviert, da das ab Angular 9 der neue Standard Compiler ist.

Ivy ist der neue Compiler von Angular 9. Ivy soll die Bundles beim AOT-Kompilieren kleiner machen und die allgemeine Performance steigern.

Routing – Lazy-Loading

Um das Lazy-Loading in Angular zu aktivieren, muss im Routing nur das hier angepasst werden (Beispiel):

const routes: Routes = [
  { path: "", loadChildren: () => import("./content/navigation.module").then(m => m.NavigationModule) },
  { path: "error", loadChildren: () => import("./shared/errors/errors.module").then(m => m.ErrorsModule) },
  { path: "notallowed", loadChildren: () => import("./shared/401/notallowed.module").then(m => m.NotAllowedModule) },
  { path: "**", loadChildren: () => import("./shared/404/notfound.module").then(m => m.NotfoundModule) },
];

Die Routen sollten über loadChildren geladen und jede Komponente in ein Modul gepackt werden.

Dadurch lädt sich Angular die jeweiligen Module erst, wenn das entsprechende Routing geöffnet wird. Das verbessert die Startzeit unserer Anwendung.

Keine Services in den Providern

Services sollten nicht in den Providern der Module sein. Seit Angular 6 wurde hier das Lazy-Loading der Services verbessert. Stattdessen sollten in den Direktiven der Services einfach providedIn: 'root' stehen. Angular lädt und injiziert die Services dann nämlich nur noch, wenn sie in den Konstruktoren der Klassen gebraucht werden.

@Injectable({
  providedIn: "root"
})
export class ApiConnectionService implements OnInit {
...

Differenzial-Loading

In der Datei browserslist können wir sagen, in welchen Browsern unsere Applikation laufen soll. Dadurch werden im Hintergrund Polyfills für die jeweiligen Browser generiert, zum Beispiel ES5-Polyfills für den Internet Explorer. Da die meisten keinen Internet Browser mehr nutzen, können wir uns hier auf die neuen Browser konzentrieren.

> 0.5%
last 2 versions
Firefox ESR
not dead

Über Angular CLI kompilieren

Zu guter Letzt kompilieren wir unsere Applikation selbstverständlich mit dem Angular CLI.

ng build --prod

Angular CLI räumt den Code für uns auf, generiert per Ivy aus TypeScript JavaScript, löscht nicht gebrauchten Code, entfernt alle Kommentare und bündelt JavaScript, CSS und Html per Webpack.

nginx

Wir laden uns nginx herunter und platzieren es unter einem Pfad unserer Wahl. In dem Fall C:\app

nginx ist ein hoch performanter Load Balancer, Web-Server und Reverse-Proxy.

https://www.nginx.com/

Anschließend öffnen wir die C:\app\conf\nginx.conf und fügen folgenden Inhalt ein:


# Configuration inspired by https://gist.github.com/denji/8359866
# and https://www.freecodecamp.org/news/powerful-ways-to-supercharge-your-nginx-server-and-improve-its-performance-a8afdbfde64d/
# nginx Configuration Doc: https://nginx.org/en/docs/

worker_processes auto;

# Doc: http://nginx.org/en/docs/ngx_core_module.html#error_log
error_log logs/error.log crit;

events {
    worker_connections 1024;
}

http {
    open_file_cache max=200000 inactive=20s;
    open_file_cache_valid 30s;
    open_file_cache_min_uses 2;
    open_file_cache_errors on;

    include mime.types;
    default_type application/octet-stream;

    # Doc: http://nginx.org/en/docs/http/ngx_http_log_module.html#access_log
    # Log every request recieved and response send
    access_log off;

    sendfile on;
    tcp_nopush on;
    keepalive_timeout 30;
    reset_timedout_connection on;
    client_body_timeout 10;
    send_timeout 2;

    # Hide server information
    server_tokens off; 

    # Gzip Settings
    gzip on;
    gzip_min_length 10240;
    gzip_comp_level 1;
    gzip_vary on;
    gzip_disable msie6;
    gzip_proxied any;
    gzip_buffers 32 16k;
    gzip_types
        # text/html is always compressed by HttpGzipModule
        text/css
        text/javascript
        text/xml
        text/plain
        text/x-component
        application/javascript
        application/x-javascript
        application/json
        application/xml
        application/rss+xml
        application/atom+xml
        font/truetype
        font/opentype
        application/vnd.ms-fontobject
        image/svg+xml;

    server {
        listen 8085; # Port unter dem der nginx Server laufen soll
        server_name localhost;
        root html;

        # pushstate (1)
        location / {
          index index.html;
          try_files $uri /index.html;
        }

        # pushstate (2)
        location ~ ^.+\..+$ {
          try_files $uri =404;	 
        }

        # Client Side Caching
        location ~* \.(jpg|jpeg|png|gif|ico)$ {
            expires 30d;
        }
    }
}

Im Code hab ich die Dokumentationen verlinkt, auf die meine Konfiguration beruht. Dort kannst du gerne nachlesen, warum ich welche Einstellungen vorgenommen habe.

Unter C:\app\html fügen wir nun unsere Angular 9 Applikation ein.

Nun installieren wir unsere nginx Anwendung als Windows Dienst. Dafür musst du nur folgendes machen:

  1. Lade dir den nginx Wrapper runter
  2. Platzier den Wrapper in C:\app und benenn die Exe in nginxservice.exe um
  3. Erstell eine neue Datei namens nginxservice.xml und füg folgenden Inhalt ein:

  angularApp
  Meine Angular Applikation
  Meine Angular Applikation | nginx
  C:\app\nginx.exe
  C:\app\logs
  roll
  
  -p
  C:\app
  C:\app\nginx.exe
  -p
  C:\app
  -s
  stop
  1. Erstell eine installService.bat Datei mit folgendem Inhalt:
start /d %~dp0 nginxservice.exe install
pause
  1. Und eine uninstallService.bat Datei mit:
start /d %~dp0 nginxservice.exe uninstall
pause
  1. Jetzt die installService.bat als Administrator ausführen und voilà dein Angular Dienst läuft nun in den Windows Diensten!

Über localhost kannst du nun deine Applikation aufrufen. Brauchst du deinen Dienst nicht mehr, so kannst du den Dienst über die uninstallService.bat wieder deinstallieren.

Das war’s

Ich hoffe, das ich damit die Performance deiner Angular 9 Anwendung steigern konnte. Sollte man doch noch Performance über die ein oder andere Einstellung herausholen können, so lass es mich wissen, indem du ein Kommentar hinterlässt.

Damit möchte ich mich bei dir bedanken und wünsche dir ein angenehmes Optimieren!

1 Kommentar
Schreib ein Kommentar