<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Beiträge von Alexander Schuster - Mobile USTP MKL</title>
	<atom:link href="https://mobile.fhstp.ac.at/author/it201516/feed/" rel="self" type="application/rss+xml" />
	<link>https://mobile.fhstp.ac.at/author/it201516/</link>
	<description>Die &#34;Mobile Forschungsgruppe&#34; der USTP, sie  sammelt hier alles zu den Themen Design, UX und Entwicklung mobiler Applikationen</description>
	<lastBuildDate>Wed, 29 Mar 2023 23:25:17 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	

<image>
	<url>https://mobile.fhstp.ac.at/wp-content/uploads/2025/03/icon-120x120.webp</url>
	<title>Beiträge von Alexander Schuster - Mobile USTP MKL</title>
	<link>https://mobile.fhstp.ac.at/author/it201516/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>WebAssembly (Einsteiger*innen-Workshop im WS2022/23)</title>
		<link>https://mobile.fhstp.ac.at/development/webassembly-einsteigerinnen-workshop-im-ws2022-23/</link>
		
		<dc:creator><![CDATA[Alexander Schuster]]></dc:creator>
		<pubDate>Thu, 23 Mar 2023 12:41:19 +0000</pubDate>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Webdevelopment]]></category>
		<category><![CDATA[Workshop]]></category>
		<guid isPermaLink="false">https://akirchknopf-21110.php.fhstp.cc/?p=10923</guid>

					<description><![CDATA[<p>Warum WebAssembly? In den meisten klassischen Web-Applikationen, an deren Entwicklung ich beteiligt war, stellte das de-facto Monopol der Sprache JavaScript im Frontend kein Problem dar. Weder war das Bedürfnis nach Performance-Optimierung in einem solchen Maße gegeben, dass die Suche nach einer Lösung außerhalb des JavaScript-Ökosystems notwendig war, noch wurde die Beschränkung auf JavaScript-Librarys und -Frameworks <a class="read-more" href="https://mobile.fhstp.ac.at/development/webassembly-einsteigerinnen-workshop-im-ws2022-23/">[...]</a></p>
<p>The post <a href="https://mobile.fhstp.ac.at/development/webassembly-einsteigerinnen-workshop-im-ws2022-23/">WebAssembly (Einsteiger*innen-Workshop im WS2022/23)</a> appeared first on <a href="https://mobile.fhstp.ac.at">Mobile USTP MKL</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading"><strong>Warum WebAssembly?</strong></h2>



<p class="wp-block-paragraph">In den meisten klassischen Web-Applikationen, an deren Entwicklung ich beteiligt war, stellte das de-facto Monopol der Sprache JavaScript im Frontend kein Problem dar. Weder war das Bedürfnis nach Performance-Optimierung in einem solchen Maße gegeben, dass die Suche nach einer Lösung außerhalb des JavaScript-Ökosystems notwendig war, noch wurde die Beschränkung auf JavaScript-Librarys und -Frameworks als etwas angesehen, das man realistischerweise umgehen kann. Doch welchen Weg könnte man einschlagen, sollte das plötzlich in einem Projekt nicht mehr zutreffen? Die Antwort darauf könnte WebAssembly lauten. Um mir selbst und der Masterklasse Mobile einen Überblick über das Thema und einen Einblick in potenzielle neue Problemlösungsstrategien für die erwähnten Problemstellungen zu geben, hielt ich einen Workshop, dessen Inhalte ich im Folgenden zusammenfassend dokumentieren möchte.</p>



<h2 class="wp-block-heading"><strong>Ziele und Nicht-Ziele des Workshops</strong></h2>



<p class="wp-block-paragraph"><strong>Ziele</strong>:</p>



<ul class="wp-block-list">
<li>Das Konzept von WebAssembly veranschaulichen<ul><li>Mögliche Einsatzbereiche ausfindig machen</li></ul>
<ul class="wp-block-list">
<li>Alle – auch mich selbst – mit neuem Wissen bereichern</li>
</ul>
</li>
</ul>



<p class="wp-block-paragraph"><strong>Nicht-Ziele</strong>:</p>



<ul class="wp-block-list">
<li>Neue Programmiersprachen lernen<ul><li>Große Applikationen bauen</li></ul>
<ul class="wp-block-list">
<li>Eine reine Frontal-Präsentation abhalten</li>
</ul>
</li>
</ul>



<h2 class="wp-block-heading"><strong>Die Problemstellung im Detail</strong></h2>



<p class="wp-block-paragraph">Wie erwähnt ist unsere Ausgangslage, dass Browser grundsätzlich nur JavaScript als Frontend-Programmiersprache ausführen können. Dies hat erhebliche Nachteile im Hinblick auf Performance, denn JavaScript ist eine interpretierte Sprache (im Gegensatz zu kompilierten Sprachen). Konkret heißt das, dass der Code nicht zuerst in Maschinensprache umgewandelt werden muss, sondern direkt im Browser zur Laufzeit übersetzt wird. Hier setzt WebAssembly an. Die Performance von Webanwendungen soll durch das browserseitige Ausführen vorher kompilierten Codes verbessert werden, denn es entfällt der Extra-Schritt der Übersetzung zur Laufzeit. Jedoch ist der Einsatz von WebAssembly nicht auf den Webbrowser beschränkt. Auch serverseitig und in Stand-Alone-Runtimes ist es möglich, dieselbe Technologie einzusetzen.</p>



<h2 class="wp-block-heading"><strong>Was ist nun WebAssembly genau?</strong></h2>



<p class="wp-block-paragraph">Von w3.org wird WebAssembly (kurz WASM) als binäres Instruktionsformat für eine Stack-basierte virtuelle Maschine bezeichnet. Das Ziel ist es also, eine im Browser vorhandene virtuelle Maschine mit Instruktionen in einem bestimmten standardisierten Format zu versorgen. Diese ist als Stack-Machine konzipiert, d. h. es kann jeweils nur auf den obersten Eintrag ein einem Stapel an gespeicherten Werten zugegriffen werden. Dies soll uns aber als Web-Entwickler*innen nicht zu sehr abschrecken, denn im Normalfall ist es Aufgabe des Compilers, lauffähige Instruktionen in Maschinensprache zu erzeugen.</p>



<p class="wp-block-paragraph">Wir benötigen also einen geeigneten Compiler, um für unser Nicht-JavaScript-Projekt ein WASM-File zu erzeugen. Hiervon gibt es bereits einige, wie z. B. „emscripten“ für C und C++, „Pyodide“ für Python, Rust, und AssemblyScript für eine syntaktisch auf TypeScript beruhenden Sprache. Zumal WebAssembly standardisiert ist, können Compiler für so gut wie alle erdenklichen Programmiersprachen entwickelt werden.</p>



<h2 class="wp-block-heading"><strong>Code-Beispiele</strong></h2>



<p class="wp-block-paragraph">Zusätzlich zu WASM-Dateien generieren viele Compiler auch WAT-Dateien (WebAssembly Text Format), welche als für den Menschen lesbare Variante des Outputs diesen. Zwar kann man wie im folgenden Beispiel auch selbst WAT-Dateien schreiben und diese dann in WASM umwandeln, jedoch dient dieses Format in der Praxis in erster Linie dem Debugging.</p>



<pre class="wp-block-code"><code>(module
  (func $add (param $lhs i32) (param $rhs i32) (result i32)
&nbsp;&nbsp;&nbsp; get_local $lhs
&nbsp;&nbsp;&nbsp; get_local $rhs
&nbsp;&nbsp;&nbsp; i32.add)
&nbsp; (export "add" (func $add))
)</code></pre>



<p class="wp-block-paragraph">Hier wird eine simple Additions-Funktion implementiert, welche die Summe der beiden Parameter „lhs“ und „rhs“ liefert. Sie wird dann exportiert, sodass im Frontend mit JavaScript das definierte Modul geladen und ein Funktionsaufruf getätigt werden kann. Letzteres könnte dann wie folgt umgesetzt werden:</p>



<pre class="wp-block-code"><code>fetch("foo.wasm")
  .then((res) =&gt; res.arrayBuffer())
&nbsp; .then((bytes) =&gt; WebAssembly.instantiate(bytes))
&nbsp; .then((res) =&gt; {
&nbsp;&nbsp;&nbsp; const result = res.instance.exports.add(5, 7);
&nbsp; });</code></pre>



<p class="wp-block-paragraph">Zu beachten ist, dass in diesem Beispiel die WASM-Datei „foo.wasm“ mittels HTTP-Request vom Server geladen wird. Es wäre aber auch denkbar, den Bytecode einer kompilierten WASM-Datei direkt als Literal in JavaScript an den Client mitzugeben. Auch sei an dieser Stelle festgestellt, dass WebAssembly keinen gänzlichen Ersatz für JavaScript darstellt, zumal ein WASM-Modul aus JavaScript-Code heraus aufgerufen wird. Es handelt sich also grundsätzlich um eine Möglichkeit, rechenintensive Prozesse auszulagern, während der Ausgangspunkt immer noch eine JavaScript-Anwendung bleibt.</p>



<h2 class="wp-block-heading"><strong>Anwendungsfälle</strong></h2>



<p class="wp-block-paragraph">Es wurde bereits eine Vielzahl an Projekten mit WebAssembly umgesetzt. Ein prominentes Beispiel stellt die von Google entwickelte App „Squoosh“ dar, welche es erlaubt, Bilddateien hochzuladen und diese clientseitig in ein anderes Format umzuwandeln. So kann der Server dahingehend entlastet werden, dass die Umwandlung von z. B. JPEG nach WebP mit vom User festgelegten Qualitätsparametern clientseitig erfolgt und auf Funktionalität zurückgegriffen werden kann, die aus einer Nicht-JavaScript-Library stammt. Ferner wurden bereits Spiele, welche ursprünglich für Spielkonsolen entwickelt wurden, oder 3D- bzw. Grafikprogramme mittels WebAssembly browserfähig gemacht.</p>



<h2 class="wp-block-heading"><strong>Fazit</strong></h2>



<p class="wp-block-paragraph">WebAssembly ist eine Technologie, welche die Lösung für einige spezifische Problemstellungen liefert, und potenziell performante und sichere Web-Apps hervorbringen kann bzw. dies bereits unter Beweis gestellt hat. Jedoch sollte hierbei beachtet werden, dass es sich nicht um eine Konkurrenz-Technologie zu herkömmlichen JavaScript-Apps handelt, sondern viel mehr um eine Ergänzung, welche das Auslagern rechenintensiver Prozesse in eine kompilierte Datei ermöglicht. Es wäre also gegenwärtig verfrüht, das Ende von JavaScript zu proklamieren.</p>
<p>The post <a href="https://mobile.fhstp.ac.at/development/webassembly-einsteigerinnen-workshop-im-ws2022-23/">WebAssembly (Einsteiger*innen-Workshop im WS2022/23)</a> appeared first on <a href="https://mobile.fhstp.ac.at">Mobile USTP MKL</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Defrost: Eine JavaScript-Library</title>
		<link>https://mobile.fhstp.ac.at/studium/studium-projekte/defrost-eine-javascript-library/</link>
		
		<dc:creator><![CDATA[Alexander Schuster]]></dc:creator>
		<pubDate>Wed, 22 Sep 2021 19:04:26 +0000</pubDate>
				<category><![CDATA[Projekte]]></category>
		<category><![CDATA[Webdevelopment]]></category>
		<guid isPermaLink="false">https://akirchknopf-21110.php.fhstp.cc/?p=9118</guid>

					<description><![CDATA[<p>Für reaktive JavaScript-Web-Applikationen gibt es bereits seit geraumer Zeit eine Vielzahl an Librarys und Frameworks. Dabei ist das Konzept meist ähnlich: Der Client erhält mit dem HTML-Dokument ein Skript-Bundle, welches ihn dazu befähigt, dynamisch Änderungen im DOM anzuzeigen. Das ist in vielen Fällen eine performante Herangeheinweise, wird doch der Server entlastet, da der Browser die <a class="read-more" href="https://mobile.fhstp.ac.at/studium/studium-projekte/defrost-eine-javascript-library/">[...]</a></p>
<p>The post <a href="https://mobile.fhstp.ac.at/studium/studium-projekte/defrost-eine-javascript-library/">Defrost: Eine JavaScript-Library</a> appeared first on <a href="https://mobile.fhstp.ac.at">Mobile USTP MKL</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph"><strong>Für reaktive JavaScript-Web-Applikationen gibt es bereits seit geraumer Zeit eine Vielzahl an Librarys und Frameworks. Dabei ist das Konzept meist ähnlich: Der Client erhält mit dem HTML-Dokument ein Skript-Bundle, welches ihn dazu befähigt, dynamisch Änderungen im DOM anzuzeigen. Das ist in vielen Fällen eine performante Herangeheinweise, wird doch der Server entlastet, da der Browser die mit dem Rendern verbundene Arbeit übernimmt. Allerdings ist es somit nicht mehr möglich, Inhalte direkt aus dem HTML-Dokument auszulesen. Bekanntlich können zwar die wichtigsten Suchmaschinen Skripte ausführen und gelangen so doch zu Texten, Bildern etc., jedoch sind auch Szenarien bekannt, in welchen direkt das erhaltene HTML-Dokument ausgelesen werden soll und somit eine zumindest teilweise vorgerenderte Antwort von Server nötig erscheint. Hier kommt Defrost ins Spiel.</strong></p>



<h2 class="wp-block-heading">Was ist Defrost?</h2>



<p class="wp-block-paragraph">Defrost ist ein Open-Source-Projekt (siehe <a href="https://github.com/alex-schuster/defrost">GitHub</a> und <a href="https://www.npmjs.com/package/@alex-schuster/defrost">npm</a>), welches es erlaubt, Templates für anzuzeigende Webseiten zwischen dem Backend und dem Frontend zu teilen (um bloß nicht an mehreren Stellen im Projekt Dateien duplizieren zu müssen) und diese dann server-seitig anhand vorhandener Daten zu rendern und anschließend client-seitig wieder zu entschlüsseln, welche Daten am Server gerendert wurden. Somit kann ein Ausgangszustand für eine Web-App hergestellt werden, welcher sich direkt aus dem HTML-Dokument ergibt. Darüber hinaus kann durch simple Reaktivität anschließend der „State“ wieder abgeändert und ein Update gerendert werden.</p>



<p class="wp-block-paragraph">Es sei erwähnt, dass sich die Verwendung von Defrost und bekannten Frontend-Frameworks zugleich nicht unbedingt ausschließt. Da Defrost nicht unbedingt ein einzelnes leeres DOM-Element als Basis nutzt, sondern im gesamten Dokument inklusive <code>&lt;head></code> funktioniert, können somit etwa <code>&lt;meta></code>-Tags dynamisch gerendert und das eigentliche User-Interface mit anderen Librarys umgesetzt werden.</p>



<h2 class="wp-block-heading">Wie kann ich ein Defrost-Projekt am einfachsten anlegen?</h2>



<p class="wp-block-paragraph">Dafür gibt es ein CLI-Tool, welches via npm installiert werden kann. Führe <code>npm i -g @alex-schuster/defrost-cli</code> aus, um es global zu installieren. Anschließend kann mit <code>defrost create &lt;Projektname></code> ein neues Projekt innerhalb des gegenwärtigen Ordners angelegt werden. Darauf kann anschließend aufgebaut werden.</p>



<h2 class="wp-block-heading">Learnings</h2>



<p class="wp-block-paragraph">Für mich gab es einige wichtige Learnings während der Arbeit am Projekt. Zumal ich gerne zusammengehörige Teilprojekte (in diesem Fall CLI und Library) an einem zentralen Ort managen möchte, habe ich mich hier für den Monorepo-Ansatz entschieden. Dabei ist npm mit entsprechender Funktionalität behilflich, welche ich im Zuge des Projekts kennenlernen durfte – Stichwort „Workspaces“. Ebenso wichtig erscheint mir die weitgehende Konformität der Library mit Ansätzen aus dem „Functional Programming“-Paradigma, mit welchem ich mich neuerdings vermehrt befasst habe. Und schließlich sein auch noch mein (zwar nicht überwältigender, aber dennoch stattgefundener) Fortschritt in Bezug auf TypeScript erwähnt.</p>



<h2 class="wp-block-heading">Schlusswort</h2>



<p class="wp-block-paragraph">Wie erwähnt handelt es sich bei Defrost um ein Open-Source-Projekt. Pull-Requests sind entsprechend ausdrücklich willkommen. Es gibt mit Version 0.0.0 – wie man vermutlich beim Verwenden der Library recht schnell feststellen wird – noch einige Features nicht, welche äußerst wünschenswert zu haben wären, wie z. B. If-Bedingung oder Loops in Templates etc. Dies könnte auch noch in naher Zukunft folgen.</p>
<p>The post <a href="https://mobile.fhstp.ac.at/studium/studium-projekte/defrost-eine-javascript-library/">Defrost: Eine JavaScript-Library</a> appeared first on <a href="https://mobile.fhstp.ac.at">Mobile USTP MKL</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Einfache CI/CD-Pipelines bauen (mit GitLab CI/CD)</title>
		<link>https://mobile.fhstp.ac.at/development/einfache-ci-cd-pipelines-bauen-mit-gitlab-ci-cd/</link>
		
		<dc:creator><![CDATA[Alexander Schuster]]></dc:creator>
		<pubDate>Mon, 30 Aug 2021 21:22:30 +0000</pubDate>
				<category><![CDATA[Development]]></category>
		<guid isPermaLink="false">https://akirchknopf-21110.php.fhstp.cc/?p=8977</guid>

					<description><![CDATA[<p>Oftmals haben Tasks wie Testing oder Deployment äußerst repetitiven Charakter, sodass deren Automatisierung fast schon die logische Konsequenz dieser Erkenntnis zu sein scheint. Es ist schlichtweg sehr zeitaufwändig und mühsam, nach jedem Commit in einem Git-Repository manuell Tests auszuführen und die neue gebuildete Version auf den Production-Server zu kopieren. Die gute Nachricht: All das kann <a class="read-more" href="https://mobile.fhstp.ac.at/development/einfache-ci-cd-pipelines-bauen-mit-gitlab-ci-cd/">[...]</a></p>
<p>The post <a href="https://mobile.fhstp.ac.at/development/einfache-ci-cd-pipelines-bauen-mit-gitlab-ci-cd/">Einfache CI/CD-Pipelines bauen (mit GitLab CI/CD)</a> appeared first on <a href="https://mobile.fhstp.ac.at">Mobile USTP MKL</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph"><strong>Oftmals haben Tasks wie Testing oder Deployment äußerst repetitiven Charakter, sodass deren Automatisierung fast schon die logische Konsequenz dieser Erkenntnis zu sein scheint. Es ist schlichtweg sehr zeitaufwändig und mühsam, nach jedem Commit in einem Git-Repository manuell Tests auszuführen und die neue gebuildete Version auf den Production-Server zu kopieren. Die gute Nachricht: All das kann man längst in Code gießen. In diesem Artikel soll anhand von <em>Gitlab CI/CD </em>erläutert werden, wie eine solche Lösung umgesetzt werden kann und wie man dabei Schritt für Schritt vorgehen könnte. Die vorgestellten Konzepte lassen sich in der Regel auch auf andere CI/CD-Services anwenden, wenngleich es Unterschiede in der Konfiguration gibt.</strong></p>



<h2 class="wp-block-heading">Schritt 0: Erfordernisse feststellen</h2>



<p class="wp-block-paragraph">Zunächst muss man festhalten, dass Projekte sehr unterschiedlich sein können und entsprechend individuelle Abfolgen von Instruktionen in einer CI/CD-Pipeline erforderlich bzw. erwünscht sind. Es gilt also zunächst festzustellen, was genau eigentlich automatisiert werden soll. Ein beliebtes Schema, aus welchen Phasen sich die Pipeline zusammensetzt, beinhaltet etwa die Abschnitte „Test“, „Build“ und „Deploy“. Diese Abfolge kann nach Bedarf verkürzt und erweitert werden. Der Artikel orientiert sich jedoch stark daran und liefert Beispiel-Lösungen für Problemstellungen aus den genannten drei Phasen.</p>



<h2 class="wp-block-heading">Schritt 1: Runner</h2>



<p class="wp-block-paragraph">Zunächst gilt es zu beachten, dass bei gitlab.com – im Gegensatz zu selbst (oder von einer Organisation) gehosteten GitLab-Instanzen – bereits ohne eigenes Zutun sogenannte „Runner“ zur Verfügung stehen. Dabei handelt es sich um Software, welche für das Ausführen bzw. das Abarbeiten der Tasks innerhalb einer Pipeline verantwortlich ist. Möchte man keine Begrenzung der Dauer, wie lange Pipelines pro Monat arbeiten dürfen, so lohnt es sich ebenso wie bei selbst gehosteten Instanzen, einen eigenen Runner aufzusetzen. Hierzu muss die <a href="https://docs.gitlab.com/runner/">Runner-Software</a> auf einem mit dem Internet verbundenen Gerät installiert und eingerichtet werden. Es kann sich hierbei um die Maschine selbst handeln, auf welche später deployt werden soll, oder aber auch um ein separates Gerät. Detaillierte Instruktionen finden sich in der <a href="https://docs.gitlab.com/runner/install/">offiziellen Dokumentation</a>.</p>



<p class="wp-block-paragraph">Nach erfolgreicher Installation kann ein Runner mit einem GitLab-Repository verbunden werden, sodass dieser schließlich Jobs entgegennehmen und abarbeiten kann. Unter <code>Settings > CI/CD</code> befindet sich ein Punkt „Runners“. Hier stehen nun entweder bereits verfügbare Runner aufgelistet, oder aber man muss die Verbindung (oder korrekt genannt „Registrierung“) erst mittels Registrierungstoken vornehmen. Per Klick auf einen Button erhält man genauere Informationen, welche Kommandos auf der Host-Maschine des Runners auszuführen sind.</p>



<figure class="wp-block-image size-large is-resized"><img decoding="async" src="https://akirchknopf-21110.php.fhstp.cc/wp-content/uploads/2021/08/runner.png" alt="" class="wp-image-8979" width="354" height="104"/><figcaption>Beispiel für einen verfügbaren Runner</figcaption></figure>



<h2 class="wp-block-heading">Schritt 2: Variablen anlegen</h2>



<p class="wp-block-paragraph">Ebenfalls unter <code>Settings > CI/CD</code> ist der Punkt „Variables“ zu finden. Hier können allerlei Werte, wie etwa SSH-Keys, Zugangsdaten, etc. gespeichert werden, sodass diese beispielsweise nicht von regulären Repository-Besucher*innen eingesehen werden können, so wie es der Fall wäre, wenn diese fix in die Konfigurationsdatei geschrieben wären. Das ist bei öffentlichen Repositorys relevant, aber auch bei privaten Repositorys, in welchen nicht alle Mitglieder Zugriff auf derlei Daten haben sollen. Vorsicht ist geboten, zumal Pipelines lesbare Job-Logs produzieren, in welche die Mitglieder immer noch Einsicht nehmen könnten. Die Lösung hierfür besteht im <a href="https://docs.gitlab.com/ee/ci/variables/index.html#mask-a-cicd-variable">„Maskieren“ von Variablen</a>. Es können freilich auch nicht-geheime Werte in Variablen gespeichert werden, welche man schlichtweg nicht „hard-coden“ will.</p>



<p class="wp-block-paragraph">Neben den selbst definierten existieren automatisch erzeugte Variablen, welche meist mit dem aktuellen Repository zusammenhängen bzw. Informationen über dieses liefern. Diesbezüglich existiert eine (meiner Meinung nach hilfreiche) <a href="https://docs.gitlab.com/ee/ci/variables/predefined_variables.html">Liste</a>. In der Praxis erweist sich der Gebrauch der besagten automatisch erzeugten Variablen auch dann als nützlich, wenn der Wert über die gesamte Projektlaufzeit hinweg konstant bleibt, da der Code in der Pipeline-Konfigurationsdatei somit in anderen Projekten auf einfache Weise wiederverwendet werden kann.</p>



<h2 class="wp-block-heading">Schritt 3: Pipeline-Konfiguration</h2>



<p class="wp-block-paragraph">Um nun Jobs zu definieren, fügt man im Root des Repositorys eine Datei mit dem Namen <code>.gitlab-ci.yml</code> hinzu. Zunächst werden die übergeordneten Phasen (die sogenannten „Stages“) aufgelistet. Dies könnte beispielsweise wie folgt aussehen:</p>



<pre class="wp-block-preformatted">
stages:
  - test
  - build
  - deploy
</pre>



<p class="wp-block-paragraph">Die vergebenen Stage-Namen können danach in den einzelnen Arbeitsschritten („Jobs“) referenziert werden, um den jeweiligen Job einer Stage zuzuordnen. Es können prinzipiell mehrere Jobs pro Stage definiert werden. Ferner kann einfach bestimmt werden, auf welche Git-Branches sich ein Job beschränkt.</p>



<pre class="wp-block-preformatted">
beispiel_job:
  stage: test
  only:
    - build
    - deploy
    - a_feature_branch
</pre>



<p class="wp-block-paragraph">Um nun tatsächlich Instruktionen für einen Job zu definieren, wird der Job um ein script ergänzt. Nun kann ein Runner prinzipiell so aufgesetzt worden sein, dass dieser Docker unterstützt. Dies bietet den Vorteil, eine vordefinierte Umgebung nutzen zu können, in welcher die Anweisungen abgearbeitet werden. Hier ein Beispiel für Unit-Tests in einem Node.js-/npm-Projekt; der Befehl <code>npm install</code> installiert hier diverse Abhängigkeiten, <code>npm run test</code> startet die eigentlichen Unit-Tests:</p>



<pre class="wp-block-preformatted">
unit-tests:
  image: node:lts-alpine
  stage: test
  before_script:
    - npm install
  script:
    - npm run test
  only:
    - develop
    - main
</pre>



<p class="wp-block-paragraph">Schlägt eine Instruktion fehl, so wird die gesamte Pipeline an der betreffenden Stelle abgebrochen. Über das UI ist es später möglich, einen Job bzw. die Pipeline neu zu starten. Liegt der Fehler außerhalb des Repositorys kann auf diese Weise ein neuer Versuch unternommen werden, die Jobs abzuarbeiten. Im Fall von fehlgeschlagenen Unit-Tests hingegen entspricht ein Abbruch der Pipeline üblicherweise dem gewünschten Verhalten. Immerhin soll meist kein fehlerhafter Code deployt werden.</p>



<p class="wp-block-paragraph">Um nun z. B. eine React-App zu veröffentlichen, möchte man anschließend an den Test-Job ein für die Production-Umgebung optimiertes Skript erzeugen und selbiges im darauffolgenden Job auf den Server kopieren – beispielsweise mittels <code>lftp</code>. Um erzeugte Dateien in späteren Jobs verfügbar zu machen, kommen „Artifacts“ zum Einsatz. Hier wird nun der erzeugte build-Folder zu einem Artifact erklärt und auf den Production-Server kopiert. Man beachte den Einsatz von Variablen:</p>



<pre class="wp-block-preformatted">
build-job:
  stage: build
  image: node:lts-alpine
  before_script:
    - npm install
  script:
    - npm run build
  artifacts:
    paths:
      - build
    expire_in: 1 day
  only:
    - main

deploy-job:
  stage: deploy
  image: alpine:latest
  before_script:
    - apk add openssh
    - apk add --no-cache lftp
  script:
    - mkdir /root/.ssh
    - chmod 700 /root/.ssh
    - touch /root/.ssh/known_hosts
    - chmod 600 /root/.ssh/known_hosts
    - ssh-keyscan -H $HOST >> /root/.ssh/known_hosts
    - lftp -e "mirror -e -P 4 --transfer-all --reverse -X .* --verbose build/ $HOST/; quit" -u $USER,$PASSWORD sftp://$HOST -p 22
  only:
    - main
</pre>



<h2 class="wp-block-heading">Fazit</h2>



<p class="wp-block-paragraph">Auch in kleineren Projekten kann viel Zeit gespart werden, indem man sich wiederholende Arbeitsschritte, welche etwa oft nach Code-Commits anfallen, automatisiert. Zwar erscheint der Einstieg in die Thematik manchen Programmierer*innen sicherlich herausfordernd, jedoch kann eine Konfigurationsdatei, so sie einmal wie gewünscht funktioniert, beliebig weiterverwendet und adaptiert werden, sodass sich die Arbeit schon bald lohnt.</p>
<p>The post <a href="https://mobile.fhstp.ac.at/development/einfache-ci-cd-pipelines-bauen-mit-gitlab-ci-cd/">Einfache CI/CD-Pipelines bauen (mit GitLab CI/CD)</a> appeared first on <a href="https://mobile.fhstp.ac.at">Mobile USTP MKL</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Wie veröffentlicht man eigentlich ein eigenes npm-Package?</title>
		<link>https://mobile.fhstp.ac.at/development/wie-veroeffentlicht-man-eigentlich-ein-eigenes-npm-package/</link>
		
		<dc:creator><![CDATA[Alexander Schuster]]></dc:creator>
		<pubDate>Thu, 18 Feb 2021 18:39:03 +0000</pubDate>
				<category><![CDATA[Allgemein]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Webdevelopment]]></category>
		<guid isPermaLink="false">https://akirchknopf-21110.php.fhstp.cc/?p=8842</guid>

					<description><![CDATA[<p>Es gibt Situationen, in welchen man selbst geschriebene Funktionalität auslagern und wiederverwendbar machen möchte. Dafür eignen sich Paketmanager wie npm hervorragend. Ich selbst habe mich vor einiger Zeit dazu entschlossen, ein solches Paket zu schnüren und möchte in diesem Beitrag Schritt für Schritt erklären, wie dies funktioniert. Ich setze jedoch Grundkenntnisse über die Verwendung von <a class="read-more" href="https://mobile.fhstp.ac.at/development/wie-veroeffentlicht-man-eigentlich-ein-eigenes-npm-package/">[...]</a></p>
<p>The post <a href="https://mobile.fhstp.ac.at/development/wie-veroeffentlicht-man-eigentlich-ein-eigenes-npm-package/">Wie veröffentlicht man eigentlich ein eigenes npm-Package?</a> appeared first on <a href="https://mobile.fhstp.ac.at">Mobile USTP MKL</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph"><strong>Es gibt Situationen, in welchen man selbst geschriebene Funktionalität auslagern und wiederverwendbar machen möchte. Dafür eignen sich Paketmanager wie <em><a href="http://npmjs.com" target="_blank" rel="noreferrer noopener">npm</a></em> hervorragend. Ich selbst habe mich vor einiger Zeit dazu entschlossen, ein solches Paket zu schnüren und möchte in diesem Beitrag Schritt für Schritt erklären, wie dies funktioniert. Ich setze jedoch Grundkenntnisse über die Verwendung von <em>npm</em> als NutzerIn von Paketen anderer voraus, um hier den Fokus auf die <em>wirklich interessanten Aspekte</em> zu lenken.</strong></p>



<h2 class="wp-block-heading">1. Projekt-Setup</h2>



<p class="wp-block-paragraph">Zunächst – wer hätte es geahnt – benötigt man npm lokal installiert. Um ein neues Paket zu initialisieren navigiert man einfach in der Kommandozeile in den gewünschten Ordner und führt den Befehl <code>npm init</code> aus. Es folgt ein Dialog, dessen Ziel darin besteht, eine <code>package.json</code>-Datei mit einigen Angaben zu erstellen. Möchte man den Dialog überspringen und mit den Standardwerten starten, so kann man stattdessen <code>npm init -y</code> ausführen.</p>



<p class="wp-block-paragraph">„package.json“ sollte nun einen Paket-Namen, eine Versionsnummer (hier bietet sich „<a href="https://semver.org/" target="_blank" rel="noreferrer noopener">Semantic Versioning</a>“ an), eine kurze Beschreibung sowie ein Haupt-Skript (der Einstiegspunkt für den geschriebenen Code) enthalten. Darüber hinaus kann eine Lizenz, wie beispielsweise <code>MIT</code> für Open-Source-Projekte und der Name des Autors/der Autorin angegeben werden. <code>package.json</code> könnte nun folgendermaßen aussehen:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
{
  &quot;name&quot;: &quot;mein-tolles-package&quot;,
  &quot;version&quot;: &quot;1.0.0&quot;,
  &quot;description&quot;: &quot;Ein wirklich tolles Package&quot;,
  &quot;main&quot;: &quot;index.js&quot;,
  &quot;author&quot;: &quot;Manuela Musterfrau&quot;,
  &quot;license&quot;: &quot;MIT&quot;
}
</pre></div>


<p class="wp-block-paragraph">Es bietet sich an, den Projektordner mit einer <code>README.md</code>-Datei auszustatten. Diese wird dann später, ähnlich wie auf GitHub, als Info-Text in der Vorschau auf npmjs.com herangezogen. Wer außerdem ohnehin Git verwendet, kann noch ein paar weitere Angaben in <code>package.json</code> machen, nämlich wo das Git-Repository gehostet wird und wo etwaige Bugs verfolgt werden.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
{
  &quot;name&quot;: &quot;mein-tolles-package&quot;,
  &quot;version&quot;: &quot;1.0.0&quot;,
  &quot;description&quot;: &quot;Ein wirklich tolles Package&quot;,
  &quot;main&quot;: &quot;index.js&quot;,
  &quot;author&quot;: &quot;Manuela Musterfrau&quot;,
  &quot;license&quot;: &quot;MIT&quot;,
  &quot;repository&quot;: {
    &quot;type&quot;: &quot;git&quot;,
    &quot;url&quot;: &quot;git@github.com:manuela-musterfrau/mein-tolles-package.git&quot;
  },
  &quot;bugs&quot;: {
    &quot;url&quot;: &quot;https://github.com/manuela-musterfrau/mein-tolles-package/issues&quot;
  }
}
</pre></div>


<p class="wp-block-paragraph">Nun kann das eigentliche Coden erfolgen. Etwaige Abhängigkeiten von anderen Paketen werden wie gewohnt mit <code>npm install &lt;Paket-Name&gt; &lt;--save | --save-dev</code>&gt; hinzugefügt. Als Haupt-Skript haben wir index.js definiert; es kann aber prinzipiell ein beliebiger Name gewählt werden.</p>



<h2 class="wp-block-heading">2. Erstveröffentlichung</h2>



<p class="wp-block-paragraph">Um das Package entweder einem geschlossenen Personenkreis oder der Öffentlichkeit zugänglich zu machen, benötigt man zunächst einmal einen Account bei npmjs.com. Es gibt hier verschiedene Pläne mit mehr oder weniger verfügbaren Features. So ist es aktuell mit der kostenlosen Variante nicht möglich, private Pakete hochzuladen. Wer jedoch ein Open-Source-Projekt betreibt, braucht sich darüber keine Gedanken zu machen. In unserem Beispiel begnügen wir uns mit dieser Einschränkung und veröffentlichen unseren Code.</p>



<p class="wp-block-paragraph">Eine Sache, die es zu beachten gilt, ist die Verfügbarkeit des gewählten Paket-Namen. Dieser darf noch nicht von einem anderen Paket verwendet worden sein. Sollte der Name bereits vergeben sein, so kann man stattdessen im eigenen „<a href="https://docs.npmjs.com/cli/v7/using-npm/scope" target="_blank" rel="noreferrer noopener">Scope</a>“ arbeiten. Jeder User und jede Organisation haben einen eigenen Namespace, welchem einzelne Projekte untergeordnet werden können. Der Paket-Name erhält dann ein Präfix (z. B. <code>@manuela-musterfrau/mein-tolles-package</code>).</p>



<p class="wp-block-paragraph">Bevor das Paket nun veröffentlicht wird, müssen die Zugangsdaten zum jeweiligen npm-Account eingegeben werden, und zwar nach dem Kommando <code>npm adduser</code>. Nach der erfolgreichen Anmeldung kann nun mit <code>npm publish</code> die Veröffentlichung gestartet werden. Sucht man anschließend auf <a href="http://npmjs.com" target="_blank" rel="noreferrer noopener">npmjs.com</a> mittels Eingabefeld nach dem eigenen Paket, sollte es bereits in den Suchergebnissen aufscheinen und zur Installation bereitstehen (siehe Abschnitt 4). Möchte man einzelne Dateien ignorieren, so kann eine Datei <code><a href="https://npm.github.io/publishing-pkgs-docs/publishing/the-npmignore-file.html" target="_blank" rel="noreferrer noopener">.npmignore</a></code> angelegt werden, welche – ähnlich wie in einer .<code>gitignore</code>-Datei – ein Liste mit zu ignorierenden Dateinamen und Verzeichnissen enthält. Die betreffenden Dateien werden beim Publizieren nicht in das Paket aufgenommen, bleiben aber selbstverständlich lokal und im Git-Repository erhalten.</p>



<h2 class="wp-block-heading">3. Updates</h2>



<p class="wp-block-paragraph">Um ein Update zu publizieren, sollte zunächst die <a href="https://docs.npmjs.com/cli/v7/commands/npm-version" target="_blank" rel="noreferrer noopener">Versionsnummer erhöht werden</a>. Je nach Update-Typ (<code>major</code>, <code>minor</code> oder <code>patch</code>) lautet der Kommandozeilenbefehl dafür unterschiedlich, folgt aber dem Schema <code>npm version &lt;Update-Typ&gt;</code>. Auch Pre-Release-Nummern werden unterstützt. Man braucht zum Erhöhen dieser Nummer den Befehl <code>npm version prerelease --preid=&lt;alpha|beta|rc&gt;</code>. Die in <code>package.json</code> enthaltene Versionsnummer wird so automatisch angepasst. Mit <code>npm publish</code> kann die neue Version schließlich wieder veröffentlicht werden.</p>



<h2 class="wp-block-heading">4. Nutzung des Packages</h2>



<p class="wp-block-paragraph">Die Nutzung des Pakets durch andere erfolgt nun genau gleich wie man dies bereits von anderen Projekt-Abhängigkeiten kennt. Durch Ausführen des Befehls <code>npm install mein-tolles-package &lt;--save | --save-dev&gt;</code> erhält man die aktuelle Version. Wird eine bestimmte Version benötigt, so kann die Versionsnummer folgendermaßen an den Namen des Pakets angehängt werden: <code>npm install mein-tolles-package@&lt;Versionsnummer&gt;</code>.</p>
<p>The post <a href="https://mobile.fhstp.ac.at/development/wie-veroeffentlicht-man-eigentlich-ein-eigenes-npm-package/">Wie veröffentlicht man eigentlich ein eigenes npm-Package?</a> appeared first on <a href="https://mobile.fhstp.ac.at">Mobile USTP MKL</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Möglichkeiten zur Optimierung von Bildern im Web im Hinblick auf Performance</title>
		<link>https://mobile.fhstp.ac.at/allgemein/moeglichkeiten-zur-optimierung-von-bildern-im-web-im-hinblick-auf-performance/</link>
		
		<dc:creator><![CDATA[Alexander Schuster]]></dc:creator>
		<pubDate>Wed, 17 Feb 2021 01:46:15 +0000</pubDate>
				<category><![CDATA[Allgemein]]></category>
		<category><![CDATA[User Experience]]></category>
		<category><![CDATA[Webdevelopment]]></category>
		<guid isPermaLink="false">https://akirchknopf-21110.php.fhstp.cc/?p=8791</guid>

					<description><![CDATA[<p>Zusammenfassung Einen beliebten Bereich zur Performance-Optimierung moderner Websites und Web-Apps stellen Bilder dar. In diesem Artikel sollen Strategien zur Verringerung der Ladezeit von Bildern in HTML5-Dokumenten erläutert werden. Dies umfasst konkret den Einsatz effizienter Bild-Dateiformate und das Zurverfügungstellen mehrerer alternativer Versionen desselben Bilds, sodass der Client aus dem Markup die für ihn passende Auswahl treffen <a class="read-more" href="https://mobile.fhstp.ac.at/allgemein/moeglichkeiten-zur-optimierung-von-bildern-im-web-im-hinblick-auf-performance/">[...]</a></p>
<p>The post <a href="https://mobile.fhstp.ac.at/allgemein/moeglichkeiten-zur-optimierung-von-bildern-im-web-im-hinblick-auf-performance/">Möglichkeiten zur Optimierung von Bildern im Web im Hinblick auf Performance</a> appeared first on <a href="https://mobile.fhstp.ac.at">Mobile USTP MKL</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading">Zusammenfassung</h2>



<p class="wp-block-paragraph"><strong>Einen beliebten Bereich zur Performance-Optimierung moderner Websites und Web-Apps stellen Bilder dar. In diesem Artikel sollen Strategien zur Verringerung der Ladezeit von Bildern in HTML5-Dokumenten erläutert werden. Dies umfasst konkret den Einsatz effizienter Bild-Dateiformate und das Zurverfügungstellen mehrerer alternativer Versionen desselben Bilds, sodass der Client aus dem Markup die für ihn passende Auswahl treffen und von den damit einhergehenden Daten-Einsparungen profitieren kann.</strong></p>



<div class="wp-block-file"><a href="https://akirchknopf-21110.php.fhstp.cc/wp-content/uploads/2021/02/bilder-im-web.pdf">Dieser Artikel ist auch als PDF verfügbar.</a><a href="https://akirchknopf-21110.php.fhstp.cc/wp-content/uploads/2021/02/bilder-im-web.pdf" class="wp-block-file__button" download>Herunterladen</a></div>



<h2 class="wp-block-heading">1 Einleitung</h2>



<p class="wp-block-paragraph">Zwar ist Bandbreite in Zeiten von 5G längst nicht mehr solch ein großes Problem wie dies noch vor einigen Jahren der Fall war, jedoch kann das Vernachlässigen der Optimierung einer Website nicht zuletzt für NutzerInnen mobiler Geräte nach wie vor zu einer schlechten User-Experience führen. So kamen in der jüngeren Vergangenheit beispielsweise neue Bild-Dateiformate für das Web auf, welche eine effizientere Codierung der Bilddaten als dies bei den bereits seit Jahrzehnten etablierten Standards der Fall ist, zum Ziel haben [1], [2]. Auch wurden Standards geschaffen, um mehrere für unterschiedliche Bildschirmgrößen geeignete Bild-Dateien gleichzeitig anzugeben und zur Verfügung zu stellen, sodass der Browser eigenständig die passende Version lädt [3]. Dies ist spätestens seit dem Erscheinen von Retina-Displays mit höherer Auflösung relevant, welche nun mit den herkömmlichen Displays koexistieren.</p>



<p class="wp-block-paragraph">In diesem Artikel soll ein Überblick über moderne Ansätze zur Optimierung von Bilddateien im Web gegeben und darauf eingegangen werden wie diese möglichst effizient vom Client angefordert werden können. Es werden mehrere prominente Konzepte aus diesem Themenfeld vorgestellt.</p>



<h2 class="wp-block-heading">2 Moderne Dateiformate</h2>



<p class="wp-block-paragraph">Noch bevor ein Bild vom Client angefordert wird, erscheint es relevant, die Bild-Datei an sich effizient zu kodieren, um auf diese Weise die Dateigröße zu verringern. In diesem Kontext sind die Formate WebP, JPEG 2000, JPEG XR und seit kurzem auch AVIF zu nennen, deren Browser-Unterstützung unterschiedlich ausfällt, wodurch eine einander ergänzende Einsatz-Strategie vorstellbar ist [2].</p>



<p class="wp-block-paragraph">Um bestehendes Bildmaterial zu konvertieren, können beispielsweise Web-Apps, wie etwa <em>Squoosh</em>, genutzt werden. Diese bietet die Möglichkeit, die Qualität zu vergleichen und zeigt die prozentuelle Reduzierung der Dateigröße. Es werden jedoch nicht alle Formate unterstützt [4].</p>



<h3 class="wp-block-heading">2.1 WebP</h3>



<p class="wp-block-paragraph">Das von Google im Jahr 2010 ins Leben gerufene Format WebP unterstützt sowohl verlustfreie als auch verlustbehaftete Datenkompression. Nach eigenen Angaben sind verlustfreie WebP-Dateien etwa um 26% kleiner als vergleichbare PNG-Dateien. Für die verlustbehaftete Variante ist sogar von von bis zu 34% Ersparnis im Vergleich zu gewöhnlichem JPEG die Rede [1], [5]. Von den hier behandelten Formaten erfährt WebP zurzeit die umfassendste Unterstützung durch gängige Web-Browser und kann durchaus als etabliert betrachtet werden [6].</p>



<h3 class="wp-block-heading">2.2 AVIF</h3>



<p class="wp-block-paragraph">Ein neuer Standard ist AVIF, welcher auf der AV1-Intra-Frame-Codierung basiert. Dieser wurde in [7] bereits evaluiert und erzielt in zahlreichen die Qualität bzw. Effizienz betreffenden Parametern bessere Ergebnisse als WebP und JPEG. Der Test umfasste drei Datensätze bestehend aus natürlichen (fotografischen), synthetischen sowie Gaming-Bildern.</p>



<p class="wp-block-paragraph">Das Format wird bereits standardmäßig von Google Chrome unterstützt [8] und auch in Mozilla Firefox kann dieses Feature bereits genutzt werden, wenngleich auch erst in einem experimentellen Stadium [9]. Es zeichnet sich gegenwärtig ein deutlicher Trend hin zur Annahme dieses Formats ab. Einen Überblick diesbezüglich bietet [10].</p>



<h3 class="wp-block-heading">2.3 JPEG 2000 und JPEG XR</h3>



<p class="wp-block-paragraph">Zur Vollständigkeit seien hier auch JPEG 2000 und JPEG XR erwähnt. Die Browser-Unterstützung für diese Formate ist sehr rudimentär, weswegen sie sich vor allem als Fallback-Optionen für wenige spezifische Clients eignen [11], [12]. Neben der geringeren Dateigröße gegenüber herkömmlichem JPEG besteht bei JPEG 2000 auch die Möglichkeit, aus demselben Bit-Stream verschiedene Auflösungen und Bildausschnitte zu extrahieren. Durch eine solche progressive Übertragung ist es dem Browser möglich, die für den Anwendungsfall nützlichen Daten zu selektieren [13]. Der später entwickelte JPEG-XR-Standard sollte eine Alternative zu JPEG 2000 mit geringem Rechenaufwand beim Kodieren und Dekodieren bieten, Bilder mit hohem Dynamikumfang (HDR) unterstützen sowie Möglichkeiten zur Interaktion mit dem Bild im Web-Browser schaffen [14].</p>



<h2 class="wp-block-heading">3 Die Attribute „srcset“ und<br>„sizes“</h2>



<p class="wp-block-paragraph">Die auf <code>&lt;img&gt;</code>-Elemente anwendbaren HTML-Attribute <code>srcset</code> und <code>sizes</code> bieten dem Client die Möglichkeit, aus mehreren verschiedenen Bildquellen (URLs) die gewünschte Version auszuwählen. Während <code>srcset</code> der Angabe einer URL-Liste und der originalen Bildgröße (oder der Pixel-Dichte, für die eine Quelle vorgesehen ist) dient, enthält <code>sizes</code> die nötige Information über die letztendliche Darstellungsgröße am Bildschirm und etwaige diesbezügliche Unterschiede zwischen verschiedenen Bildschirmgrößen. So kann beim Ändern der Fenstergröße bei Bedarf dynamisch eine weitere Version aus der Liste geladen werden. Wird <code>sizes</code> weggelassen, so geht der Browser von einer Darstellung über die gesamte Bildschirmbreite aus [15].</p>



<p class="wp-block-paragraph">Ein Bild, welches stets die gesamte Breite des Bildschirms belegt, aber für Ausgabegeräte mit einfacher und doppelter Pixel-Dichte optimiert ist, könnte also wie in Code-Beispiel 1 in das HTML-Dokument eingebunden werden.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
&amp;lt;img
  srcset=&quot;einfach.jpg 1x, doppelt.jpg 2x&quot;
  src=&quot;einfach.jpg&quot;
  alt=&quot;Ein Beispiel&quot;
/&gt;
</pre></div>


<p class="wp-block-paragraph" style="font-size:12px"><em><span class="has-inline-color has-black-color"><strong>Code-Beispiel 1:</strong> Auszeichnung mehrerer alternativer<br>Bild-Versionen</span></em></p>



<p class="wp-block-paragraph">Zu beachten ist, dass das Attribut <code>src</code> auch hier verpflichtend anzuführen ist [3]. Es stellt die Kompatibilität mit älteren Browsern sicher, welche <code>srcset</code> nicht unterstützen. In Code-Beispiel 1 dient diesen die URL zur Version mit einfacher Pixel-Dichte als Fallback.</p>



<p class="wp-block-paragraph">Nun wird ein <code>sizes</code>-Attribut hinzugefügt, welches im konkreten Fall die dargestellte Breite des Bilds für Viewport-Breiten von maximal 800 Pixel mit der vollen, andernfalls mit der halben Breite beziffert. Gemeint sind hier nicht etwa Hardware-Pixel, sondern das in CSS-Media-Querys verwendete Maß. Geräte mit höherer Pixel-Dichte rechnen die für sie gültige Entsprechung dieses Werts automatisch in Hardware-Pixel um. Ferner kann die originale Breite des Bilds in Pixel mit <code>500w</code> bzw. <code>1000w</code> angegeben werden. Dadurch kann der Browser schließlich – wiederum unter Berücksichtigung der Pixel-Dichte des Geräts auf welchem er läuft – berechnen, welche Quelle angefordert werden soll. In diesem Fall könnte das &lt;<code>img&gt;</code>-Element im Dokument wie in Code-Beispiel 2 angeführt werden.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
&amp;lt;img
  sizes=&quot;(max-width: 800px) 100vw, 50vw&quot;
  srcset=&quot;einfach.jpg 500w, doppelt.jpg 1000w&quot;
  src=&quot;einfach.jpg&quot;
  alt=&quot;Ein Beispiel&quot;
/&gt;
</pre></div>


<p class="wp-block-paragraph" style="font-size:12px"><em><span class="has-inline-color has-black-color"><strong>Code-Beispiel 2:</strong> Beispiel mit Angabe der Darstellungsgröße eines Bilds in Abhängigkeit von der Bildschirmgröße</span></em></p>



<h2 class="wp-block-heading">4 Das Picture-Tag</h2>



<p class="wp-block-paragraph">Die in Code-Beispiel 1 und Code-Beispiel 2 veranschaulichte Strategie stößt an ihre Grenzen, sobald die einzelnen aufgelisteten URLs nicht nur auf verschiedene Versionen desselben Bilds mit unterschiedlicher Auflösung verweisen, sondern darüber hinaus auch abhängig von der Bildschirmgröße unterschiedlicher Bildinhalt gezeigt werden soll. Dies ist beispielsweise in einem Szenario denkbar, wenn ein sehr breites Bild in der Darstellung auf Mobiltelefonen speziell zugeschnitten werden muss, um das zentrale Bildelement in einer vorteilhaften Position zu behalten. Würde man dies in Code-Beispiel 2 so handhaben, würden Geräte mit unterschiedlicher Pixel-Dichte bei gleicher Bildschirmgröße womöglich unterschiedliche Bilder bzw. voneinander abweichende Bildkompositionen zeigen.</p>



<p class="wp-block-paragraph">Um dem entgegenzuwirken, steht das <code>&lt;picture&gt;</code>-Element zur Verfügung, welches wiederum eine beliebige Anzahl an <code>&lt;source&gt;</code>-Elementen (und genau ein verpflichtendes <code>&lt;img&gt;</code>-Element als Fallback) enthält. Jedes &lt;source&gt;-Element erhält nun, analog zu den Beispielen im vorherigen Abschnitt, ein <code>srcset</code>&#8211; bzw. wo nötig auch ein <code>sizes</code>-Attribut. Optional kann durch das <code>media</code>-Attribut ein Überspringen des gesamten <code>&lt;source&gt;</code>-Elements erwirkt werden, wenn sich das darin spezifizierte Media-Query als unzutreffend erweist. Ebenso wird ein solches Element außer Acht gelassen, wenn ein <code>type</code>-Attribut einen vom Browser nicht unterstützten Typ (Internet Media Type) enthält [3]. Code-Beispiel 2 umgesetzt mittels <code>&lt;picture&gt;</code> und Dateien im WebP-Format könnte also lauten wie in Code-Beispiel 3.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
&amp;lt;picture&gt;
  &amp;lt;source
    type=&quot;image/webp&quot;
    media=&quot;(max-width: 800px)&quot;
    sizes=&quot;100vw&quot;
    srcset=&quot;mobile-einfach.webp 500w, mobile-doppelt.webp 1000w&quot;
  /&gt;
  &amp;lt;source
    type=&quot;image/webp&quot;
    sizes=&quot;50vw&quot;
    srcset=&quot;desktop-einfach.webp 1000w, desktop-doppelt.webp 2000w&quot;
  /&gt;
  &amp;lt;img
    src=&quot;einfach.jpg&quot;
    alt=&quot;Ein Beispiel&quot;
  /&gt;
&amp;lt;/picture&gt;
</pre></div>


<p class="wp-block-paragraph" style="font-size:12px"><em><span class="has-inline-color has-black-color"><strong>Code-Beispiel 3:</strong> Ein Beispiel-Anwendungsfall für das<br>Picture-Tag</span></em></p>



<p class="wp-block-paragraph">Unterstützt der Browser den Internet-Media-Type <code>image/webp</code> nicht, so werden beide <code>&lt;source&gt;</code>-Elemente ignoriert. Beträgt die Breite des Viewports maximal 800 Pixel, so kommt das erste <code>&lt;source&gt;</code>-Element in Betracht und entsprechend der Pixel-Dichte wird die passende Quelle aus dem <code>srcset</code>-Attribut geladen. Bei einer größeren Viewport-Breite fällt die Wahl hingegen auf das zweite <code>&lt;source&gt;</code>-Element.</p>



<h2 class="wp-block-heading">5 Fazit</h2>



<p class="wp-block-paragraph">Im Zuge der Recherche zum vorliegenden Artikel wurde der Autor auf mehrere ihm bis dahin noch nicht geläufige Bild-Formate aufmerksam. Dies führt vor Augen, wie groß der Fortschritt hinsichtlich immer effizienterer Algorithmen für Bild-Kodierung ist. Diese können dazu beitragen, die User-Experience in modernen Web-Applikationen stetig zu verbessern und die benötigte Datenmenge gleichzeitig zu reduzieren. Der Autor ermutigt daher dazu, sich mit den damit einhergehenden Möglichkeiten vertraut zu machen und von den in diesem Artikel vorgestellten Konzepten Gebrauch zu machen. Gleichzeitig scheinen ebendiese Methoden zur Optimierung auch dazu zu verleiten, hohen Aufwand für kaum merkbare Performance-Verbesserungen zu betreiben. Geht man schließlich weiter ins Detail, so findet man immerhin auch bei den hier angeführten Beispielen noch deutliches Verbesserungspotential. Dieser Aspekt sollte stets bedacht werden, um nicht andere relevante Bereiche außen vor zu lassen.</p>



<p class="wp-block-paragraph">Zukünftige Arbeiten könnten sich mit der Messung der Performance der genannten Bild-Dateiformate befassen und einen objektiven Vergleich schaffen. Dies ist keineswegs trivial, muss doch die Dateigröße der subjektiv wahrgenommenen Bildqualität gegenübergestellt werden. Immerhin bieten viele Formate mehr als nur eine Qualitätsstufe an, was zusätzliche Komplexität in einen Vergleich bringt. In der vorliegenden Arbeit hätte eine solche detaillierte Untersuchung den Rahmen gesprengt.</p>



<h2 class="wp-block-heading">Literatur</h2>



<p class="wp-block-paragraph">
[1] „A new image format for the web“, Google Developers, [Online]. Adresse: <a href="https://developers.google.com/speed/webp" target="_blank" rel="noreferrer noopener">https://developers.google.com/speed/webp</a> (besucht am 02.01.2021).<br><br>

[2] „Serve images in next-gen formats“, web.dev, [Online]. Adresse: <a href="https://web.dev/uses-webp-images/" target="_blank" rel="noreferrer noopener">https://web.dev/uses-webp-images/</a> (besucht am 03.01.2021).<br><br>

[3] „HTML standard: Embedded content“, Web Hypertext Application Technology Working Group (WHATWG), [Online]. Adresse: <a href="https://html.spec.whatwg.org/multipage/embedded-content.html" target="_blank" rel="noreferrer noopener">https://html.spec.whatwg.org/multipage/embedded-content.html</a> (besucht am 03.01.2021).<br><br>

[4] „Squoosh“, Squoosh, [Online]. Adresse:
<a href="https://squoosh.app" target="_blank" rel="noreferrer noopener">https://squoosh.app</a> (besucht am 17.02.2021).<br><br>

[5] J. Hu, S. Song und Y. Gong, „Comparative performance analysis of web image compression“, in <em>2017 10th International Congress on Image and Signal Processing</em>, <em>BioMedical Engineering and Informatics (CISP-BMEI)</em>, IEEE, 2017, S. 15.<br><br>

[6] „WebP image format“, caniuse.com, [Online]. Adresse: <a href="https://caniuse.com/webp" target="_blank" rel="noreferrer noopener">https://caniuse.com/webp</a> (besucht am 03.01.2021).<br><br>

[7] N. Barman und M. G. Martini, „An evaluation of the next-generation image coding standard AVIF“, in <em>2020 Twelfth International Conference on Quality of Multimedia Experience (QoMEX)</em>, IEEE, 2020, S. 14. [Online]. Adresse: <a href="https://ieeexplore.ieee.org/document/9123131/" target="_blank" rel="noreferrer noopener">https://ieeexplore.ieee.org/document/9123131/</a> (besucht am 03.01.2021).<br><br>

[8] „Feature: AVIF image decode“, Chrome Platform Status, [Online]. Adresse: <a href="https://www.chromestatus.com/feature/4905307790639104" target="_blank" rel="noreferrer noopener">https://www.chromestatus.com/feature/4905307790639104</a> (besucht am 03.01.2021).<br><br>

[9] „Experimental features in Firefox“, MDN Web Docs, [Online]. Adresse: <a href="https://developer.mozilla.org/en-US/docs/Mozilla/Firefox/Experimental_features#AVIF_AV1_Image_File_format_support" target="_blank" rel="noreferrer noopener">https://developer.mozilla.org/en-US/docs/Mozilla/Firefox/Experimental_features#AVIF_AV1_Image_File_format_support</a> (besucht am 03.01.2021).<br><br>

[10] „AVIF image format“, caniuse.com, [Online]. Adresse: <a href="https://caniuse.com/avif" target="_blank" rel="noreferrer noopener">https://caniuse.com/avif</a> (besucht am 17.02.2021).<br><br>

[11] „JPEG XR image format“, caniuse.com, [Online]. Adresse: <a href="https://caniuse.com/jpegxr" target="_blank" rel="noreferrer noopener">https://caniuse.com/jpegxr</a> (besucht am 03.01.2021).<br><br>

[12] „JPEG 2000 image format“, caniuse.com, [Online]. Adresse: <a href="https://caniuse.com/jpeg2000" target="_blank" rel="noreferrer noopener">https://caniuse.com/jpeg2000</a> (besucht am 03.01.2021).<br><br>

[13] M. W. Marcellin, M. J. Gormish, A. Bilgin und M. P. Boliek, „An overview of JPEG2000“, in <em>Proceedings DCC 2000. Data Compression Conference</em>, IEEE, 2000, S. 523–541. [Online]. Adresse: <a href="http://ieeexplore.ieee.org/document/838192/" target="_blank" rel="noreferrer noopener">http://ieeexplore.ieee.org/document/838192/</a> (besucht am 03.01.2021).<br><br>

[14] F. Dufaux, G. J. Sullivan und T. Ebrahimi, „The JPEG XR image coding standard [standards in a nutshell]“, <em>IEEE Signal Processing Magazine</em>, Jg. 26, Nr. 6, S. 195–204, 2009. [Online]. Adresse: <a href="http://ieeexplore.ieee.org/document/5230820/" target="_blank" rel="noreferrer noopener">http://ieeexplore.ieee.org/document/5230820/</a> (besucht am 03.01.2021).<br><br>

[15] „HTML standard: Images“, Web Hypertext Application Technology Working Group (WHATWG), [Online]. Adresse:<br><a href="https://html.spec.whatwg.org/multipage/images.html" target="_blank" rel="noreferrer noopener">https://html.spec.whatwg.org/multipage/images.html</a> (besucht am 03.01.2021).</p>
<p>The post <a href="https://mobile.fhstp.ac.at/allgemein/moeglichkeiten-zur-optimierung-von-bildern-im-web-im-hinblick-auf-performance/">Möglichkeiten zur Optimierung von Bildern im Web im Hinblick auf Performance</a> appeared first on <a href="https://mobile.fhstp.ac.at">Mobile USTP MKL</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Yet Another COVID-19 Guest List</title>
		<link>https://mobile.fhstp.ac.at/studium/studium-projekte/yet-another-covid-19-guest-list/</link>
		
		<dc:creator><![CDATA[Alexander Schuster]]></dc:creator>
		<pubDate>Wed, 28 Oct 2020 00:11:28 +0000</pubDate>
				<category><![CDATA[Projekte]]></category>
		<category><![CDATA[Initialprojekt]]></category>
		<category><![CDATA[QR-Code]]></category>
		<guid isPermaLink="false">https://akirchknopf-21110.php.fhstp.cc/?p=8573</guid>

					<description><![CDATA[<p>Während der COVID-19-Krise bedarf es Tools, welche das Contact-Tracing, also das Nachverfolgen von Kontaktpersonen, vereinfachen. Mancherorts ist das Erfassen von Kontaktdaten sogar verpflichtend, wie etwa in der Wiener Gastronomie. Dabei ist das Konzept, durch das Bereitstellen von QR-Codes, welche auf ein entsprechendes Formular verlinken, einen mit der Zeit immer größer werdenden Stapel an ausgefüllten Papierbögen <a class="read-more" href="https://mobile.fhstp.ac.at/studium/studium-projekte/yet-another-covid-19-guest-list/">[...]</a></p>
<p>The post <a href="https://mobile.fhstp.ac.at/studium/studium-projekte/yet-another-covid-19-guest-list/">Yet Another COVID-19 Guest List</a> appeared first on <a href="https://mobile.fhstp.ac.at">Mobile USTP MKL</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Während der COVID-19-Krise bedarf es Tools, welche das Contact-Tracing, also das Nachverfolgen von Kontaktpersonen, vereinfachen. Mancherorts ist das Erfassen von Kontaktdaten sogar verpflichtend, wie etwa in der Wiener Gastronomie. Dabei ist das Konzept, durch das Bereitstellen von QR-Codes, welche auf ein entsprechendes Formular verlinken, einen mit der Zeit immer größer werdenden Stapel an ausgefüllten Papierbögen zu verhindern, nicht mehr ganz neu. Dennoch soll in diesem Projekt (Initialprojekt in der Masterklasse &#8220;Mobile&#8221;) ein neuer Anlauf genommen werden, um auf die Problematik der möglchen Falschangaben zu reagieren. Kurz gesagt wird hier ein per SMS gesendeter Bestätigungscode abgefragt, welcher zwar keine unumgehbare Hürde darstellt, aber wenigstens eine Rufnummer einer Anmeldung zuordnet. Zu erwähnen sei an dieser Stelle, dass das Projekt zurzeit noch fehleranfällig ist, jedoch soll hier noch laufend nachgebessert werden, um das Tool praxistauglicher zu machen. FH-intern kann das zugehörige Git-Repository <a href="https://git.nwt.fhstp.ac.at/it201516/covid-guest-list" target="_blank" rel="noreferrer noopener nofollow">hier</a> aufgerufen werden.</p>



<figure class="wp-block-image size-large"><img fetchpriority="high" decoding="async" width="470" height="571" src="https://akirchknopf-21110.php.fhstp.cc/wp-content/uploads/2020/10/form.jpg" alt="" class="wp-image-8574"/><figcaption>Das Online-Formular für einen &#8220;Raum&#8221;</figcaption></figure>



<p class="wp-block-paragraph">Prinzipiell können mit dem Tool sogenannte &#8220;Räume&#8221; erstellt werden, welche von AdministratorInnen verwaltet werden. Gäste rufen dann einfach ein Formular wie das obige auf und bestätigen dann ihre angegebene Rufnummer mit einem per SMS empfangenen Code.</p>



<figure class="wp-block-image size-large"><img decoding="async" width="720" height="450" src="https://akirchknopf-21110.php.fhstp.cc/wp-content/uploads/2020/10/code.jpg" alt="" class="wp-image-8575"/><figcaption>Eine Beispiel-SMS-Nachricht mit Bestätigungscode</figcaption></figure>



<p class="wp-block-paragraph">Im Administrationsbereich kann schließlich im Bedarfsfall eine Gästeliste im JSON-Format heruntergeladen werden. Hier könnten künftig noch Filteroptionen und andere Formate implementiert werden. Der angezeigte QR-Code dient zum Aushang beim Eingang zu einem Lokal und wird in der gegenwärtigen Version von einer Google-API generiert und hier ausgegeben.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="636" height="800" src="https://akirchknopf-21110.php.fhstp.cc/wp-content/uploads/2020/10/admin-636x800.jpg" alt="" class="wp-image-8576"/><figcaption>Beispiel-Ancsicht im Administrationsbereich (Bemerkung: QR-Code verweist hier nur auf den Localhost, da der Screenshot am Localhost aufgenommen wurde)</figcaption></figure>



<h2 class="wp-block-heading">Verwendete Technologien</h2>



<p class="wp-block-paragraph">Das Projekt wurde mit <a href="https://www.php.net/" target="_blank" rel="noreferrer noopener">PHP</a> (mit <a href="https://getcomposer.org/" target="_blank" rel="noreferrer noopener">Composer</a> als Package-Manager) und <a href="https://www.mysql.com/" target="_blank" rel="noreferrer noopener">MySQL</a> umgesetzt. Die Formulare werden mit <a href="https://getbootstrap.com/" target="_blank" rel="noreferrer noopener">Bootstrap</a> optisch verschönert. Als SMS-API kommt <a href="https://www.twilio.com/" target="_blank" rel="noreferrer noopener">Twilio</a> zum Einsatz.</p>
<p>The post <a href="https://mobile.fhstp.ac.at/studium/studium-projekte/yet-another-covid-19-guest-list/">Yet Another COVID-19 Guest List</a> appeared first on <a href="https://mobile.fhstp.ac.at">Mobile USTP MKL</a>.</p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
