Vorheriger Artikel Nächster Artikel

Magento: Aus dem Shopsystem mehr Performance rausholen

Aus dem
t3n Magazin Nr. 24

06/2011 - 08/2011

Wer einen plant, kommt an kaum vorbei. Das Open-Source-System punktet vor allem mit Flexibilität. Doch die geht zu Lasten der Leistung. Vermeintlich, denn auch aus Magento lässt sich jede Menge Performance herausholen.

Bequem vom eigenen Sofa aus zu bestellen, scheint Volkssport geworden zu sein. Doch ob Besucher eines Onlineshops verweilen und schließlich einkaufen oder direkt wieder in den Weiten des Webs verschwinden, hängt von vielen Faktoren ab: Finden sie auf Anhieb, was sie gesucht haben? Erscheint der Shop vertrauenswürdig? Passen Preise für Produkte und Versand?

Hinzu kommt die Reaktionszeit der Seite, die einen großen Anteil am „Wohlfühlfaktor“ des Besuchers hat. Wenn der Nutzer den Eindruck hat, dass die Seite nur behäbig auf die Eingaben reagiert, macht das Surfen durch die Produkte des Shops nur wenig Spaß und der Einkauf wird bei Mitbewerbern fortgesetzt. Google wird deshalb in Zukunft die Ladegeschwindigkeit einer Seite stärker in seine Beurteilung innerhalb der Suche einbeziehen – ein weiterer Grund, ein Auge auf die Performance zu werfen.

Flexibilität als Fluch und Segen

Flexibilität galt bei Magento von Beginn an als Maxime. Über Module und Templates lässt sich das System sowohl funktional als auch optisch an fast alle Anforderungen und Ansprüche der Shopbetreiber anpassen. Nicht zuletzt dieser Flexibilität ist die hohe Beliebtheit Magentos zu verdanken.

Gleichzeitig erweist sich diese Flexibilität aber als größter Feind der Performance. Statt Prozesse, Daten und Layouts strikt festzulegen, bleibt dem Betreiber immer die Möglichkeit, Dinge anzupassen und zu erweitern. Dass das System hierdurch komplexere Routinen durchlaufen muss, ist die logische Konsequenz.

Bestes Beispiel hierfür ist das Entity-Attribute-Value-Pattern (EAV), das Magentos Datenmodelle hochgradig flexibel macht. Über das Backend können Betreiber Produkte frei mit beliebigen Attributen verschiedener Typen ausstatten. Die Besucher können dann Produkte anhand dieser Attribute vergleichen, filtern oder suchen.

Andererseits ist EAV sehr performancelastig. Im Gegensatz zu herkömmlichen Datenbankmodellen, bei denen die Eigenschaften eines Objekts in einzelnen Spalten einer flachen Tabelle gespeichert werden, teilt EAV die Daten in mehrere Tabellen auf: Entitätstypen wie Produkte, Kategorien oder Kunden werden zentral in der Tabelle eav_entity_type definiert. Attribute zu Produkten werden in eav_attribute spezifiziert und den jeweiligen Entitätstypen zugeordnet. Optionen für Auswahl-Attribute werden in eav_attribute_option, deren Labels in eav_attribute_option_value gespeichert. Die eigentlichen Daten der Produkte, Kategorien und sonstigen EAV-Objekte liegen aber in den Wertetabellen. Hierbei handelt es sich um eine Kopftabelle (beispielsweise catalog_product_entity) und bis zu neun datentypspezifische Tabellen für Integer, Texte, Datumswerte und andere.

Ganze fünf Tabellen sind nötig, um das Entity-Attribute-Pattern abzubilden; die Werte selbst, die das EAV komplettieren, fehlen in der Abbildung aus Platzgründen.
Ganze fünf Tabellen sind nötig, um das Entity-Attribute-Pattern abzubilden; die Werte selbst, die das EAV komplettieren, fehlen in der Abbildung aus Platzgründen.

Um nun ein Produkt vollständig aus der Datenbank zu lesen, muss zunächst bestimmt werden, welche Attribute diesem Produkt zugeordnet sind, um anschließend die jeweiligen Werte auslesen zu können. Hierfür sind mehrere Datenbankzugriffe über mehrere Tabellen notwendig, was mehr Zeit und Ressourcen in Anspruch nimmt als der Zugriff auf eine einzelne Tabelle.

Ein weiteres Beispiel sind die Module: Über XML-Konfigurationen lässt sich das Verhalten anderer Module anpassen, indem beispielsweise Klassen dynamisch ausgetauscht werden. Hierdurch wird der Instanzierungsprozess von Klassen jedoch deutlich gebremst. Noch verstärkt wird dieser Effekt durch die vier Codepools „lib“, „core“, „community“ und „local“, durch die die Ordnung und Update-Fähigkeit des Systems gewahrt bleiben soll. Wird eine bestimmte Klasse gesucht, probiert das System die vier Ordner rückwärts durch. Dadurch wird das Laden der Klassen in Magento paradoxerweise schneller, je mehr Klassen in „local“ oder „community“ überschrieben werden.

Caching, Caching, Caching

Um Flexibilität und Performance unter einen Hut zu bringen, beinhaltet Magento diverse Caching-Mechanismen. Hierbei wird ausgenutzt, dass die meisten Konfigurationseinstellungen zu Beginn eines Projekts stark variieren, zur eigentlichen Produktivphase jedoch überwiegend gleich bleiben.

Eine Übersicht über die Zustände der Caches findet man im Backend bei System, Cache Management. Während es für die Entwicklungsumgebung durchaus sinnvoll sein kann, die Caches zu deaktivieren, ist dies in der Produktivumgebung keine Option. Innerhalb des Caching-Moduls finden sich folgende Optionen:

  • Konfiguration: Beinhaltet die Grundkonfiguration des Systems sowie die Konfiguration aller aktiven Module.
  • Layouts: Definition der Ausgabeblöcke sowie deren Positionen.
  • Block HTML-Ausgabe: Speichert die HTML-Ausgaben von Blöcken, wenn diese für Caching konfiguriert wurden.
  • Übersetzungen: Dieser Cache speichert die verschiedenen Übersetzungen zentral ab.
  • Kollektionsdaten: Bestimmte Listen werden in Magento immer wieder aufgerufen. Werden diese zwischengespeichert, kann wertvolle Zeit gespart werden.
  • EAV-Typen und -Attribute: Konfiguration der verschiedenen EAV-Elemente, sodass diese nicht permanent aus der Datenbank gelesen werden müssen.
  • Konfiguration der Webdienste: Vorrangig für die SOAP-API interessant; speichert öffentliche Methoden und Zugriffsrechte.

Obschon überall zu Caching geraten wird, finden sich in der Praxis noch zu viele Magento-Shops mit (partiell) deaktiviertem Cache. Das ist zum Teil einer fehlenden Unterstützung durch Templates oder Erweiterungen von Drittanbietern geschuldet: Haben die Entwickler Caching bei der Programmierung nicht vorgesehen, beeinträchtigt dies unter Umständen die komplette Installation.

Cache-Keys

Ob Magento einen Block live generieren muss oder eine valide Version aus dem Cache beziehen kann, wird anhand so genannter Cache-Keys entschieden. Diese geben den aktuellen Zustand der Ausgabe wieder und werden vor der Ausgabe eines Blocks generiert.

Wird der aktuelle Zustand in einem gültigen Eintrag im Speicher gefunden, kann der dort hinterlegte Inhalt direkt ausgegeben werden, ohne weitere Programmlogik ausführen zu müssen. Wird der Block nicht im Speicher gefunden, erzeugt Magento die Blockausgabe und legt diese für die definierte Cache-Lebenszeit statisch ab. Ohne Cache-Informationen im Block kann das System die Blockausgaben nicht zwischenspeichern und erzeugt die Ausgaben bei jedem Zugriff dynamisch.

Die Definition der Cache-Angaben erfolgt in der Regel im Magento-eigenen Platzhalterkonstruktor des Blocks (Template Method Pattern).

Definition der Cache-Header im Block

class T3n_Example_Block_Example extends Mage_Core_Block_Template
{
	protected function _construct()
	{
		$this->addData(array(
			'cache_lifetime'	=> 86400,
			'cache_tags'	=> array(Mage_Catalog_Model_Product::CACHE_TAG)
		));
	}

	public function getCacheKeyInfo() {
		return array(
			'T3N_EXAMPLE',
			(int)Mage::app()->getStore()->isCurrentlySecure(),
			Mage::getDesign()->getPackageName(),
			Mage::getDesign()->getTheme('template')
		);
	}

}

Listing 1

Der angegebene Wert in der Cache-Lifetime definiert den Zeitraum in Sekunden, für den der Cache gültig sein soll. Der Wert sollte mit Bedacht gewählt werden. Fällt er zu niedrig aus, wird der Block zu häufig dynamisch generiert. Ist er zu hoch, kommt es zu keiner Aktualisierung und die Informationen bleiben länger im Speicher als gewünscht. Im Beispiel wird eine Cache-Lebenszeit von einem Tag (in Sekunden; 60 x 60 x 24 = 86400) definiert.

Die Cache-Tags unterteilen die Informationen im Cache in verschiedene Kategorien. Diese Kategorien werden etwa verwendet, um bestimmte Bestandteile gezielt zu aktivieren, zu deaktivieren oder zu verwerfen. Genau das passiert auch beim Löschen eines Caches über das Magento-Backend.

Im Backend lassen sich die einzelnen Caches überwachen und steuern.
Im Backend lassen sich die einzelnen Caches überwachen und steuern.

Dritter Bestandteil des Listings ist die Definition des Keys in der Methode getCacheKeyInfo. Der Cache-Key ist der eindeutige Bezeichner für eine im Cache hinterlegte Information. Die Werte des Cache-Keys sollten alle verschiedenen Zustände eines Blocks wiedergeben, die einzeln gespeichert werden. Erlaubt ein Block verschiedene Zustände, so darf es genauso viele unterschiedliche Cache-Keys für den aktuellen Block geben. Um Cache-Kollisionen mit anderen Blöcken zu vermeiden, wird als erster Teil meist der Identifikator des aktuellen Blocks verwendet. Weitere Komponenten sind häufig das Package und Theme sowie die Sprache.

Cache-Backends

Wie die Caching-Daten gespeichert werden, entscheidet die Wahl der Cache-Backends, welche in der Konfigurationsdatei app/etc/local.xml eingestellt werden.

Beispiel einer Cache-Backend-Konfiguration

<config>
	<cache>
		<backend>memcached</backend>
		<slow_backend>database</slow_backend>
		<fast_backend>memcached</fast_backend>
		<memcached>
			<servers>
				<server>
					<host>192.168.0.1</host>
					<port>11211</port>
					<persistent>0</persistent>
				</server>
			</servers>
		</memcached>
	</cache>
	[...]
</config>

Listing 2

In <backend> wird das Cache-Backend eingetragen, welches mit der Zwischenspeicherung beauftragt werden soll. Mögliche Werte sind memcached, apc, xcache, eaccelerator, sqlite, database und file. Wird kein Wert übergeben, nutzt Magento standardmäßig den dateibasierten Cache.

Die vier erstgenannten Cache-Backends sind arbeits­speicher­basiert und dementsprechend schnell; allerdings sind sie nicht persistent und unterstützen keine Cache-Tags. Sie werden deshalb im Rahmen des Two-Level-Cache-Backends mit einem langsameren, aber persistenten Speicher kombiniert. Dies geschieht über die Konfigurations-Tags <slow_backend> und <fast_backend>. Darüber hinaus werden dem memcached-Backend im Beispiel noch notwendige Serverinformationen übergeben.

Zur Verbesserung der Two-Level-Cache-Performance existiert ein Cache-Modul [1], welches verhindert, dass Magento bei jedem Lesezugriff den schnellen Cache neu schreibt. Über das Modul kann zusätzlich das Cache-Backend Libmemcached aktiviert werden, welches in den Benchmarks deutlich besser abschneidet als Memcached [2].

Empfohlen wird für einzelne Webserver übrigens APC mit File-Cache. Werden mehrere Webserver verwendet, sollte das Libmemcached- mit dem Datenbank-Backend kombiniert werden.

Caching von ganzen Seiten

Innerhalb von Magento gibt es eine Vielzahl von Seiten, die (fast) vollständig aus dem Cache bezogen werden können. Gute Beispiele sind die Kategorie- und Produktdetailseiten, die bis auf wenige Elemente bei jedem Aufruf und jedem Benutzer gleich sind. Einzig (Staffel-)Preise können kunden­gruppen­spezifisch abweichen. Liegt die Seite also für eine bestimmte Zeit (beispielsweise 24 Stunden) im Cache, so wird die Auslieferung für alle weiteren Besucher für diesen Zeitraum deutlich beschleunigt, ohne dass ihnen Informationen verloren gehen.

Die Enterprise Edition bringt für solche Fälle den Full-Page-Cache (FPC) mit. Dieser speichert alle statischen Bestandteile der Seite im Cache und markiert alle Positionen für dynamische Inhalte, sodass bei einem Aufruf einer Seite nur noch die dynamischen Elemente erzeugt werden müssen. Damit hiervon wirklich profitiert werden kann, wird für die dynamischen Ausgaben kein vollständiger Magento-Stack geladen, sondern nur noch ein Teil der Ausgabelogik. Beispiele für die dafür notwendigen Block-Container finden sich im Enterprise_PageCache-Modul.

Für Professional oder Community Editions ist außerdem das CatalogCache-Modul von Netresearch [3] zu empfehlen, welches die Cache-Keys für Kategorie- und Produktansichten nachpflegt. Das sorgt zwar nicht für das Cachen der gesamten Seite, aber mit den Produktinformationen wird ein Großteil der Ausgabelogik eines hoch frequentierten Bereichs des Onlineshops eingespart.

Opcode-Caching und Magento-Compiler

Magento basiert auf PHP, einer interpretierten Sprache, d.h. der Webserver liest die Quelltexte zur Laufzeit aus den PHP-Dateien, um sie in maschinenlesbaren Operation Code (Opcode) umzuwandeln und schließlich auszuführen. Da sich der Quelltext und damit auch der Opcode zur Laufzeit selten ändern, ist es sinnvoll, den Opcode selbst zwischenzuspeichern und damit den Aufwand für die Umwandlung zu sparen. Um noch einen Schritt weiterzugehen, kann die Prüfung auf Änderung abgeschaltet werden (apc.stat = 0, eaccelerator.check_mtime = 0); das spart einen weiteren Festplattenzugriff pro Datei und Request. Dann muss allerdings der Cache bei Änderungen am PHP-Code manuell zurückgesetzt werden.

Verschiedene Opcode-Caches stehen als Open-Source-Software frei zur Verfügung und bringen deutliche Performance-Steigerungen mit sich. Für Magento bieten sich vorzugsweise eAccelerator oder APC an.

Ähnliche Verbesserungen lassen sich erzielen, indem der include_path keine ungenutzten Verzeichnisse enthält und die bereits angesprochenen Code-Pools zur Laufzeit deaktiviert werden. Mit dem Magento-Compiler können sämtliche Magento-PHP-Dateien aus einem Verzeichnis bezogen werden. Im Magento-Backend unter System, Tools, Compiler kann der Compiler aktiviert werden; die gesammelten Dateien legt Magento anschließend im Ordner includes/src/ ab.

Die Indizes pflegen

Magento nutzt für verschiedene Aspekte des Shops nicht die normalisierten Datentabellen, sondern Index-Tabellen. Dies betrifft die Produktattribute und -preise, Produktsuche, die Zuordnung von Produkten zu Kategorien, die Layered-Navigation, den Lagerbestand sowie Produkt- und Kategorie-URLs.

Für das Frontend ist wichtig, dass die Indizes aktuell gehalten werden. Daher aktualisiert Magento standardmäßig die betroffenen Indizes, wenn ein Objekt gespeichert wird. Sollen jedoch viele Informationen aktualisiert werden, ist es sinnvoll, das automatische Update zu deaktivieren und den Index anschließend komplett neu generieren zu lassen.

Besonders wichtig für die Performance sind die beiden „Flat Data“-Indizes für Kategorien und Produkte. In diesen Flat Tables werden alle Informationen gespeichert, die für die Darstellung der Kategorie- und Produktübersichten benötigt werden. Auf diesen Seiten kommt es vorrangig auf das schnelle Auslesen einiger weniger Informationen relativ vieler Objekte an, was mit Flat Tables deutlich schneller geht als mit EAV-Tabellen.

Um die Flat Tables zu aktivieren, müssen die beiden Indizes zunächst unter System, Index-Verwaltung generiert werden. Magento erstellt automatisch eine Flat Table pro Store View, also inklusive aller Lokalisierungsinformationen. Anschließend muss der Katalog so konfiguriert werden, dass er die Tabellen auch nutzt. Dies geschieht unter System, Konfiguration im Abschnitt Shop unter Katalog. Die beiden Optionen „Flat Catalog Category verwenden“ sowie „Flat Catalog Product verwenden“ sollten spätestens im Produktivbetrieb aktiviert werden.

Keine Objekte in Listen laden

Nichts mit Performance-Optimierung zu tun hat der load-Befehl vieler Datenmodelle. In der Praxis stößt man aber allzu oft auf das Problem, dass bestimmte Informationen in Produktlisten nicht zur Verfügung stehen. Sollen etwa in der Kategorie-Übersicht bereits die Kurzbeschreibungen der Produkte angezeigt werden, scheitert dies, da jene Informationen im Standard-Datenbestand der Produkte in den Produktlisten nicht aufgeführt werden. Unerfahrene Entwickler lösen dieses Problem gerne mit dem Aufruf von load(). Dies führt dazu, dass Magento alle notwendigen Informationen zu Produkten ausliest und alle internen Prozesse anstößt, die eigentlich nur auf der Detailseite notwendig wären. Die Auswirkungen auf die Performance der Listen sind fatal.

Durch zusammengefasste JavaScript- und CSS-Dateien können die Anzahl der HTTP-Requests (im Bild veranschaulicht mit Firebug) gesenkt und damit die Geschwindigkeit der Seite erhöht werden.
Durch zusammengefasste JavaScript- und CSS-Dateien können die Anzahl der HTTP-Requests (im Bild veranschaulicht mit ) gesenkt und damit die Geschwindigkeit der Seite erhöht werden.

Die schnellere Lösung findet sich im Backend von Magento. Innerhalb der Attribut-Eigenschaften gibt es die Option „In Produkt-Listing verwenden“. Steht diese auf „Ja“, wird der Wert in die Flat Tables übernommen und damit in der Produktliste verfügbar gemacht; load() wird nicht mehr benötigt.

Frontend-Optimierung

Wie für alle Webapplikationen zählt die Optimierung von HTML und eingebundenen Ressourcen auch zu wichtigen Stellschrauben der Magento-Performance. Die von Sounders und Oram vorgeschlagenen 14 Schritte zu schnelleren Webseiten [4] sind dementsprechend für Magento-Projekte genauso empfehlenswert.

Eine einfache Reduzierung der HTTP-Requests ermöglicht die Option, JavaScript & CSS zusammenzusetzen und jeweils in einer einzelnen Datei auszuliefern. Diese Option findet sich im Backend unter System, Konfiguration im Tab Entwickleroptionen. Mitunter kommt es nach Aktivierung der Option zu fehlerhafter Darstellung, weil statt korrekter URLs absolute Server-Pfade in den HTML-Quelltext geschrieben werden. Meist liegt dann entweder ein Rechteproblem vor oder eine der im Layout definierten Dateien konnte nicht eingelesen werden.

Ein Optimizer-Modul, als Open-Source-Projekt bei Github verfügbar, versucht außerdem, die HTML- und JavaScript-Ausgabe weiter zu verbessern [5]. Die aktuelle Version des Moduls soll in den kommenden Wochen weiter ausgebaut werden. In der jetzigen Version wird etwa der Translator-Code in die externen JavaScript-Dateien verschoben sowie Whitespaces aus dem HTML herausgefiltert, um die Dateigröße zu reduzieren.

Um die Browser-Begrenzung für gleichzeitige Downloads pro Domain zu umgehen, kann es sinnvoll sein, für Skin- und Media-Ressourcen eigene Subdomains zu definieren. Die entsprechenden Einstellungen finden sich in der Konfiguration im Tab Web im Abschnitt Ungesichert. Gesicherte Verbindungen sollten diese Optimierung nicht durchführen, wenn nicht für die Subdomains ebenfalls SSL-Zertifikate vorliegen.

Etwas kontrovers wird die Verwendung von „Content Delivery Networks“ diskutiert. Ist der Shop global oder zumindest international aufgestellt, kann es sinnvoll sein, Bilder über Module [6] direkt in CDNs zu laden und von dort einzubinden. Für nationale oder auf Europa begrenzte Shops ist das Geld meist besser in einen potenten Server und eine gute Konfiguration investiert.

Server-Konfiguration

Alle bisher aufgezählten Maßnahmen laufen ins Leere, wenn die Server-Konfiguration nicht optimiert wird. Die perfekte Einstellung für alle möglichen Anwendungsfälle gibt es nicht, vielmehr ist es ein Abwägen und Ausprobieren, welche der Punkte der eigenen Installation hilfreich sind.

Der Webserver sollte nur für den Magento-Betrieb benötigte Module aktivieren, um die Prozesse schlank zu halten. Alle Einstellungen können direkt in der zentralen Webserver-Konfiguration durchgeführt werden; auf Einstellungen in .htaccess-Dateien sollte verzichtet werden (AllowOverride None), da ansonsten jedes Verzeichnis auf die Existenz einer solchen Datei hin überprüft werden muss. Alle Ressourcen sollten mit Cache-Headern versehen werden, sodass diese im Browser vorgehalten werden und nicht bei jedem Request neu übertragen werden müssen. Außerdem ist die komprimierte Kommunikation zwischen Client und Server Pflicht.

Ein weiterer Ansatz besteht darin, die Auslieferungen von statischen Dateien wie Bildern durch einen leichtgewichtigen HTTP-Server wie nginx durchführen zu lassen. Diese benötigen in der Regel meist nur einen Bruchteil des Speichers pro Request; PHP-Funktionalität ist hierbei nicht gefragt. Werden Load Balancer eingesetzt, sollte über die direkte Auslieferung von diesem oder über den Einsatz als Reverse-Proxy nachgedacht werden.

MySQL benötigt ausreichend Speicher, um zumindest einen Teil der Datenbank im Arbeitsspeicher halten zu können. Da Magento großflächig Gebrauch von InnoDB macht, sollte der InnoDB Buffer Pool ebenfalls ausreichend groß gewählt sein. Magento schlägt hierbei vor, den Buffer Pool auf 50 bis 85 Prozent des gesamten Arbeitsspeichers des Servers festzulegen, je nachdem, ob der Server die Seiten und die Datenbank oder ausschließlich MySQL beherbergt. Außerdem sollte die Anzahl der konkurrierenden InnoDB-Threads (~ 2 x CPU Cores), der Query Cache (~ 64 MB) sowie das Query Cache Limit (~ 2 MB) festgelegt werden.

Fazit

Nicht nur neue, sondern auch bestehende Shops können von den genannten Maßnahmen profitieren. Die schnelleren Ladezeiten führen neben einer optimierten Ausnutzung der Server auch zu einer guten User Experience, einer besseren Bewertung durch Google und einer höheren Conversion-Rate.

Schnell und einfach umzusetzen sind insbesondere die Überprüfung der Cache-Einstellungen im Backend, das Setzen der Cache-Header in der Apache-Konfiguration sowie das Anpassen der InnoDB-Konfiguration für den MySQL-Server. Nur wenig komplizierter bei großer Wirkung sind die Installation des Opcode-Caches sowie das Setup der Subdomains. Die Maßnahmen beeinflussen die Magento-Instanzen nachhaltig positiv, indem die Skalierbarkeit der Applikation deutlich gesteigert wird. Ignoriert man diese Punkte, lassen sich Leistungs- und damit Umsatzsteigerungen meist nur begrenzt über mehr Hardware realisieren.

Abonniere jetzt t3n-News über WhatsApp und bleib mobil auf dem Laufenden!
t3n-News via WhatsApp!
Vorheriger Artikel Zurück zur Startseite Nächster Artikel
Eine Antwort
  1. von Philipp W. am 05.01.2012 (00:07 Uhr)

    Erwähnenswert ist noch das Magento Modul Full Page Cache von mgt-commerce..sehr einfach einzurichten und den Performanceunterschied ist enorm. In Kombination mit dem Hetzner EX 4 Server gehört es zu meinem Standardsetup. Statt dem normalen MySQL Server setze ich Percona 5.5 ein (verwendet eine andere Storage Engine aber sonst bleibt alles beim alten)..kein großer Aufwand und gibt auch einen guten Boost.

    Antworten Teilen
Deine Meinung

Bitte melde dich an!

Du musst angemeldet sein, um einen Kommentar schreiben zu können.

Jetzt anmelden

Aktuelles aus dem Bereich Magento
Online-Shop-Betreiber aufgepasst: Diese Software erkennt an der Mausbewegung die Stimmung eurer Besucher
Online-Shop-Betreiber aufgepasst: Diese Software erkennt an der Mausbewegung die Stimmung eurer Besucher

Ein Forscherteam hat eine Software entwickelt, die an der Mausbewegung erkennt, ob sich ein Nutzer gerade wohlfühlt oder sich womöglich ärgert. Online-Shop-Betreiber könnten mit einer solchen … » weiterlesen

Wird ja auch Zeit! C64 bekommt WLAN-Modul
Wird ja auch Zeit! C64 bekommt WLAN-Modul

C64-Besitzer können ihren geliebten „Brotkasten“ jetzt sogar mit einem WLAN-Modul ausstatten. 150 US-Dollar will der Entwickler dafür haben. » weiterlesen

E-Commerce leicht gemacht: 10 Tipps für ungeduldige Einsteiger
E-Commerce leicht gemacht: 10 Tipps für ungeduldige Einsteiger

Der erste Onlineshop steht kurz bevor und es gibt unheimlich viel zu tun? Keine Panik, die wichtigsten Tipps zum Einstieg in die Welt des E-Commerce haben wir hier für dich gesammelt. » weiterlesen

Alle Hefte Jetzt abonnieren – für nur 35 €

Kennst Du schon unser t3n Magazin?