Grunt concurrent und time-grunt

Florian Müller Datum: 29. September 2016
Autor: Florian Müller


Gestern Abend bin ich auf einen Artikel gestoßen, welcher sich mit der Optimierung von Grunt Tasks beschäftigt hat. Vieles davon ist schon im Einsatz, aber eins hat dann doch noch gefehlt – die Parallelisierung. Dies habe ich heute morgen testweise bei einem Projekt integriert. Um vergleichbare Ergebnisse zu bekommen, welche unabhängig von anderen Build Tasks des Build Scripts sind, habe ich time-Grunt zum Einsatz gebracht.

Um Time-Grunt zu verwenden, muss der Task einmal via NPM installiert werden (npm install time-grunt --save-dev) und zum Gruntfile hinzugefügt werden (require('time-grunt')(grunt);). Das war es schon. Nun zeigt Grund nach allen Tasks eine Übersicht der Zeiten aller Tasks und die Gesamtzeit an.

Execution Time (2016-09-29 08:29:35 UTC+2)
loading tasks               2.1s  ▇▇▇ 9%
lesslint:src                5.9s  ▇▇▇▇▇▇▇▇▇ 24%
jshint:scripts              1.5s  ▇▇▇ 6%
jasmine:src                 1.4s  ▇▇ 6%
less:production             4.1s  ▇▇▇▇▇▇ 17%
uglify:production           5.3s  ▇▇▇▇▇▇▇▇ 22%
imagemin:dist               1.3s  ▇▇ 5%
filerev_replace:production  2.6s  ▇▇▇▇ 11%
Total 24.5s

Nun konnte ich mit der Parallelisierung der Grunt Tasks beginnen. Hierzu kam grunt-concurrent zum Einsatz. Um eine Vergleichbarkeit zu haben, habe ich den Grunt build Task mehrfach ausgeführt. Die Zeiten waren wie folgt:

  • 25.6s
  • 24.5s
  • 24.6s

Mittelwert: 24.9s

Nun habe ich Concurrent integriert. Die Syntax ist dabei denkbar einfach. Es werden einfach alle Tasks, die gleichzeitig lauten sollen, in ein Array geschrieben.

module.exports = {
  production: [
    'less:production',
    'uglify:production',
    'copy',
    'imagemin'
  ]
};

Nun wurde in der aliases.js der entsprechende Part durch concurrent ersetzt. Der Deployment Task sieht somit folgendermaßen aus:

...
  build: {
    ...
    tasks: [
      'test',
      'clean',
      'concurrent:production',
      'filerev',
      'filerev_replace',
      'filerev_assets',
      'usebanner'
    ]
  },
...

Hierbei war schon eine große Performance Optimierung von knapp 5 Sekunden zu bemerken. Klingt nicht viel, ist aber in Prozent ausgedrückt 20%.

  • 19.5s
  • 19.6s
  • 19.7s

Mittelwert: 19.6s

Nun ging es noch einen Schritt weiter. Ich habe zusammen mit Benni geschaut, welche Tasks man noch parallelisieren kann. Dabei kamen wir noch auf die Tests. Dazu habe ich die concurrent.js erweitert.

...
  test: [
    'lesslint',
    'jshint',
    'jasmine'
  ]
...

Dies wurde dann noch in die aliases.js eingetragen (concurrent:test).

Die Tests auf dem DEV ergaben folgende Ergebnisse:

  • 19.6s
  • 19.4s
  • 22.6s
  • 20.1s
  • 19.8s
  • 19.2s
  • 19.6s
  • 19.3s

Mittelwert: 19,95s

Auffällig hier sind die Ausreißer nach oben. Hier kann ich nur vermuten, dass diese durch zusätzliche Belastung des DEV kamen. Lässt man diese nun außen vor (19.8s-22.6s), so kommt man auf einen Mittelwert von 19.42 Sekunden. Wenn ein Test fehlschlägt, bricht sofort die ganze Abarbeitung an der Stelle ab und auch die anderen parallel laufenden Tasks werden gestoppt.

Insgesamt haben wir hiermit eine Performance Optimierung von 5,48 Sekunden.

Man muss Aufpassen, wenn man parallelisiert. Jeder Grunt Prozess lädt nochmals alle Tasks. Dies dauerte im Test jeweils 2.1s. Das muss man einrechnen, ob dann noch ein Performance Gewinn vorhanden ist. Auch kann nicht jeder Task parallel ablaufen, da sie aufeinander aufbauen oder beispielsweise nur durchgeführt werden dürfen, wenn der vorherige erfolgreich war (beispielsweise Löschen des dist Ordners darf nur passieren, wenn die Tests erfolgreich waren, damit immer gültiges JS und CSS vorhanden ist auf dem DEV).

Quelle: http://www.html5rocks.com/en/tutorials/tooling/supercharging-your-gruntfile/

Kommentare

Selber kommentieren:






Weitere Beiträge zum Thema Technologie


Google Maps und der Wikipedia-Layer

Autor: Benjamin Hofmann


Technologie


Seit dem Release von Google Maps v3 gab es keinen Wikipedia-Layer mehr, den man einfach so einblenden konnte. Laut diesem Issue bei Google wird das auch nicht mehr passieren, da der Layer zu wenig genutzt wird und der Aufwand für die Integration in keiner Relation zum Nutzen steht. Jedoch wurde dort eine API von einem …


Beitrag lesen
17.
Juli
2012

lory

Autor: Benjamin Hofmann


Technologie // User Experience & Design


Und schon wieder habe ich eine kleine schöne Javascript-Library gefunden: lory. Diesmal ist es keine Lightbox-Lösung wie PhotoSwipe gestern, sondern ein simpler Slider. Auch dieses Skript ist auf den mobilen Anwendungsfall ausgelegt und kann von Haus aus mit Swipes umgehen. Auch das sogenannte Infinite-Sliding ist möglich und auch dieses Skript lässt sich über RequireJS nutzen …


Beitrag lesen
23.
Sep.
2016

Styling von Checkboxen und Radiobuttons

Autor: Benjamin Hofmann


Technologie // User Experience & Design


Wieder einmal ein Linktipp: Customizing web forms with CSS3 and WebKit Leider funktionieren diese Styles, so wie sie im Artikel dargestellt werden, nur in WebKit-basierten Browsern, also im Safari, Chrome oder den Standard-Browsern von Android und iOS. Aber wenn diese Styles nicht angewandt werden können springt der jeweilige Browser auf die normale Darstellung zurück, wie …


Beitrag lesen
23.
Februar
2012

GOTO Berlin 2017 – Teil 2

Autor: Christian Göbel


Technologie


Hier nun Teil 2 meines Berichts zur GOTO Berlin. Nach dem Container & Kubernetes Security Workshop am Mittwoch und dem ersten Haupt-Konferenztag am Donnerstag (Bericht hier), rundete der ML-Track am Freitag, 17. November, meine Themenwahl ab. Einen beeindruckenden Einstieg in den Tag lieferte Prof. D’Andreas Keynote „Drones on Broadway“, bei der auf die Forschung im …


Beitrag lesen
19.
Dez.
2017