Web Assets - Tipps für eine bessere Organisation und Leistung

Erinnern Sie sich noch an die Zeit, als wir viel Zeit darauf verwenden mussten, die Ressourcen unseres Projekts (Bilder, CSS usw.) zu optimieren? Heute haben Benutzer eine viel schnellere Internetverbindung und es scheint, dass wir es uns leisten können, größere Bilder oder größere Flash-Dateien mit vielen Videos und Bildern zu verwenden. Mit dem Aufstieg der mobilen Entwicklung sind wir jedoch wieder in derselben Situation. Es ist äußerst wichtig, gut optimierte Websites zu erstellen, damit wir schnellere Anwendungen haben, die weniger Inhalte herunterladen und sofort reagieren.


Bilder

Dienen Sie die richtige Größe

Oft verwenden wir dieselben Bilder für verschiedene Bereiche unserer Websites. In einem Online-Shop haben beispielsweise alle Produkte ein Übersichtsbild. Angenommen, wir haben drei Seiten, auf denen wir diese Bilder zeigen müssen - eine Seite zum Auflisten der Produkte, eine weitere Seite mit Details zum Produkt und eine dritte Seite, die nur das Bild in Originalgröße zeigt.

Wir benötigen also drei verschiedene Bildgrößen, und wenn wir dieselbe Datei für alle drei verschiedenen Orte verwenden, lädt der Browser das Bild in voller Größe selbst für die Auflistungsseite herunter, wo wir möglicherweise nur ein 200x200-Bild benötigen. Wenn die Originaldatei etwa 1 MB groß ist und wir zehn Produkte pro Seite haben, würde der Benutzer 10 MB herunterladen. Das ist keine sehr gute Idee. Wenn Sie können, versuchen Sie, verschiedene Bilder für die verschiedenen Teile Ihrer Website zu generieren. Dadurch sparen Sie eine Menge KB für Ihre Benutzer. Es ist eine gute Idee, die aktuelle Bildschirmauflösung im Auge zu behalten. Wenn zum Beispiel jemand Ihre Site auf seinem iPhone öffnet, müssen Sie das riesige Header-Image nicht bedienen, das Sie normalerweise verwenden. Durch die Verwendung von CSS-Medienabfragen können Sie ein Bild mit einer kleineren Größe senden:

@media only screen und (min-device-width: 320px) und (max-device-width: 480px) .header background-image: url (… /images/background_400x200.jpg); 

Kompression

Ein Bild nur mit den richtigen Abmessungen zu senden reicht nicht immer aus. Einige Dateiformate können stark komprimiert werden, ohne dass ihre Qualität beeinträchtigt wird. Es gibt viele Programme, die Ihnen helfen können. Zum Beispiel bietet Photoshop eine nette Funktion namens Speichern Sie für Web und Geräte:


Es gibt viele Optionen in diesem Dialog, aber eine der wichtigsten ist Qualität. Wenn Sie den Wert auf etwa 80% einstellen, kann sich die Dateigröße erheblich verringern.

Natürlich können Sie Code zum Komprimieren der Dateien verwenden, aber ich persönlich bevorzuge Photoshop und verwende es, wann immer es möglich ist. Hier ist ein einfaches Beispiel in PHP geschrieben:

Funktion compressImage ($ source, $ destination, $ quality) $ info = getimagesize ($ source); switch ($ info ['mime']) case "image / jpeg": $ image = imagecreatefromjpeg ($ source); imagejpeg ($ image, $ destination, $ quality); brechen; Fall "image / gif": $ image = imagecreatefromgif ($ source); Imagegif ($ image, $ destination, $ quality); brechen; Fall "image / png": $ image = imagecreatefrompng ($ source); imagepng ($ image, $ destination, $ quality); brechen;  compressImage ('source.png', 'destination.png', 85);

Sprites

Sie können die Leistung Ihrer Anwendung steigern, indem Sie die Anzahl der Anforderungen an den Server reduzieren. Jedes neue Bild bedeutet also eine neue Anfrage. Es ist eine gute Idee, Ihre Bilder zu einem zu kombinieren. Das resultierende Bild heißt a Sprite und mit dem Ändern der Hintergrundposition Im CSS-Stil können Sie nur den Teil des Bildes anzeigen, den Sie benötigen. Beispielsweise verwendet Twitter Bootstrap Sprites für seine internen Symbole:


Im CSS können Sie so etwas tun, um zu zeigen, welchen Teil des Sprites Sie möchten:

.icon-edit Hintergrundbild: URL ("… /img/glyphicons-halflings-white.png"); Hintergrundposition: -96px -72px; 

Caching

Der Cache-Mechanismus des Browsers ist Ihr Freund. Ja, manchmal kann es während der Entwicklung zu sehrem Ergebnis kommen lustig Situationen, aber es hilft wirklich, die Leistung Ihrer Website zu verbessern. Jeder Browser speichert Inhalte wie Bilder, JavaScript oder CSS. Es gibt mehrere Möglichkeiten, die Zwischenspeicherung zu steuern, und ich empfehle Ihnen, diesen großartigen Artikel für eine detaillierte Überprüfung zu lesen. Im Allgemeinen können Sie den Prozess durch Setzen von Kopfzeilen wie folgt steuern:

$ expire = 60 * 60 * 24 * 1; // Sekunden, Minuten, Stunden, Tage-Header ('Cache-Control: maxage = ". $ expire); Header (' Expires: '.gmdate (' D, d MYH: i: s ', time () + $ verfallen).' GMT '); header ('Last-Modified:' .gmdate ('D, dMYH: i: s'). 'GMT');

Vorabruf

HTML5 schreitet jeden Tag voran. Es gibt eine nette Funktion namens Vorabruf Dem Browser wird mitgeteilt, dass Sie in naher Zukunft eine Ressource benötigen werden, die jetzt heruntergeladen werden muss. Zum Beispiel:

Daten-URI-Schema / Inline-Bilder

Vor ein paar Jahren musste ich eine einfache Webseite entwickeln, die nur eine HTML-Datei sein sollte. Natürlich gab es mehrere Bilder, die ich hinzufügen musste. Daten-URI-Schemas halfen mir, das Problem zu lösen. Die Idee ist, Ihre Bilder in eine Base64-kodierte Zeichenfolge umzuwandeln und sie in der src Attribut des img Etikett. Zum Beispiel:

roter Punkt

Wenn Sie diesen Ansatz verwenden, befindet sich Ihr Bild tatsächlich im HTML-Format, und Sie speichern eine HTTP-Anforderung. Wenn Sie ein großes Image haben, wird die Zeichenfolge natürlich sehr lang sein. Hier ist ein einfaches PHP-Skript, das Bilder in base64-Strings konvertiert:

$ picture = fread ($ fp, Dateigröße ($ file)); fclose ($ fp); // base64 codiert die Binärdaten und zerlegt sie dann // in Abschnitte gemäß der RFC 2045-Semantik. $ base64 = base64_encode ($ picture); $ tag = ''; $ css = 'url (data: image / jpg; base64,'. str_replace ("\ n", "", $ base64). '); ';

In manchen Fällen kann dies hilfreich sein, bedenken Sie jedoch, dass es im IE nicht sehr gut funktioniert.


CSS

Ich denke gerne, dass das Schreiben von CSS dem Schreiben von Code ähnelt. Sie müssen Ihre Stile noch organisieren, um verschiedene Blöcke und die Beziehung zwischen ihnen zu definieren. Deshalb finde ich CSS-Management sehr wichtig. Jeder Teil der Anwendung sollte einen eigenen Stil haben und gut voneinander getrennt sein. Wenn Sie alles in verschiedenen Dateien aufbewahren, ist dies eine gute Organisation, bringt aber auch eigene Probleme mit sich.

Wir alle wissen, dass die Verwendung der @einführen Aussage ist keine sehr gute Idee. Das liegt daran, dass alles neu ist @einführen bedeutet eine neue Anfrage an den Server. Und wenn Sie zum Beispiel 20 verschiedene haben .css Dateien bedeutet, dass der Browser 20 Anfragen stellt. Und der Browser rendert / zeigt die Seite nicht vor dem Herunterladen aller Stile. Wenn einige von Ihnen .css Da Dateien fehlen oder sehr groß sind, erhalten Sie eine große Verzögerung, bevor Sie etwas auf dem Bildschirm sehen.

Verwenden Sie CSS-Preprozessoren

CSS-Präprozessoren lösen alle oben genannten Probleme. Sie teilen Ihre Stile immer noch in verschiedene Dateien auf, aber am Ende kompiliert der Präprozessor alles zu einer einzigen .css Datei. Sie bieten eine Reihe cooler Features wie Variablen, verschachtelte Blöcke, Mixins und Vererbung. Der Code sieht immer noch wie CSS aus, ist aber gut formatiert / strukturiert. Es gibt wenige beliebte Präprozessor, die es wert sind, überprüft zu werden - Sass, LESS und Stylus. Hier ist ein einfaches in LESS geschriebenes Beispiel:

.position (@top: 0, @left: 0) position: absolut; Top Top; links Links; Text ausrichten: links; Schriftgröße: 24px;  .header .position (20px, 30px); .tips .position (10px, -20px);  .logo .position (10px, 20px); 

wird herstellen

.Kopfzeile Position: absolut; oben: 20px; links: 30px; Text ausrichten: links; Schriftgröße: 24px;  .header .tips position: absolut; oben: 10px; links: -20px; Text ausrichten: links; Schriftgröße: 24px;  .header .logo position: absolut; oben: 10px; links: 20px; Text ausrichten: links; Schriftgröße: 24px; 

Wenn Sie beispielsweise eine Schaltfläche mit einem Styling versehen haben und nur dieselbe Schaltfläche mit einer anderen Farbe für den Text erzeugen möchten, können Sie Folgendes tun:

.button border: fest 1px # 000; Polsterung: 10px; Hintergrund: # 9f0; Farbe: # 0029FF;  .active-button .button (); Farbe: #FFF; 

Effizientes CSS

Normalerweise denken die meisten Entwickler nicht an effizientes CSS. Die Effizienz des CSS spiegelt sich im Rendern der Seite wider. Wenn Ihre Stile ineffizient sind, wird Ihre Anwendung von Browsern langsam gerendert. Eine interessante Tatsache ist, dass Browser die CSS-Selektoren von rechts nach links parsen. Was bedeutet, dass der folgende Code:

Körper ul li a color: # F000; Textdekoration: keine; 

… Ist überhaupt nicht effizient. Das liegt daran, dass der Motor alles bekommt Tags und müssen jedes übergeordnete Element auswerten, um den erforderlichen Stil zu erfassen. Sie sollten auch wissen, dass die Selektoren hinsichtlich ihrer Effizienz in der folgenden Reihenfolge angeordnet sind: ID, Klasse, Tag und Universal. Dies bedeutet, dass ein Element mit einem Ich würde set wird schneller gerendert als ein Element mit nur einem Tag-Selektor. Natürlich macht es keinen Sinn, IDs für alle Elemente in der DOM-Baumstruktur hinzuzufügen, aber Sie sollten Ihren Code auf jeden Fall überprüfen und wo möglich verbessern. Zum Beispiel, wenn Sie so etwas haben:

ul #navigation li background: # ff0232; 

Sie sollten das entfernen ul Teil, weil Sie nur einen haben #Navigation Element auf der Seite. Oder in der folgenden Auswahl:

body .content p font-size: 20px; 

Es ist klar, dass die .Inhalt Element ist ein Kind der Karosserie Etikett. Alle Elemente sind eigentlich Kinder dieses Elements.

Hier sind zwei hilfreiche Links zu diesem Thema: Developers.google.com und css-tricks.com

Dateigröße

Wie bereits erwähnt, ist es gut, so wenig Code wie möglich zu haben, da der Browser die Seite vor dem Herunterladen des CSS nicht rendert. Hier sind einige Tipps zum Verringern der Dateigröße.

Kombinieren Sie ähnliche Stile:

.Header Schriftgröße: 24px;  .content font-size: 24px; 

… Verwandelt sich in:

.Header, .content Schriftgröße: 24px; 

Verwenden Sie Abkürzungen. Anstatt:

.Kopfzeile Hintergrundfarbe: # 999999; Hintergrundbild: URL (… /images/header.jpg); Hintergrundposition: oben rechts; 

Schreibe es auf diese Weise:

.Header Hintergrund: # 999 URL (… /images/header.jpg) oben rechts; 

Reduzieren Sie Ihren CSS-Code. Sie können dies tun, indem Sie ein Werkzeug verwenden, das im Allgemeinen alle Leerzeichen und neuen Zeilen entfernt. Zum Beispiel CSSOptimiser oder Minifycss. Es ist üblich, solche Instrumente auf der Serverseite der Anwendung zu verwenden, d. H. Etwas, das in der Sprache des Back-End geschrieben ist. Normalerweise minimieren diese Komponenten Ihren Code und stellen ihn dem Benutzer zur Verfügung.

Setzen Sie Ihre CSS-Dateien in das Etikett

Es ist eine gute Praxis, Ihre .css Dateien in der Kopf Tag, so lädt es der Browser zuerst herunter.


JavaScript

Reduzieren Sie die Anzahl der HTTP-Anforderungen

Genau wie bei Ihrem CSS - es ist gut, die Anzahl der Anfragen, die an den Server gesendet werden, zu reduzieren. In den meisten Fällen wird das Rendern der Seite durch das Laden der JavaScript-Dateien nicht angehalten, einige Teile der Seite werden jedoch nicht mehr funktionsfähig.

Minimieren Sie Ihren Code

Es gibt eine Reihe von Bibliotheken, die JavaScript-Minifizierung durchführen. Es ist etwas, das die Größe der Dateien verringert, aber bedenken Sie, dass es in einer Entwicklungsumgebung gut ist, Ihren Code sauber zu halten. Die meisten dieser Tools ändern den Namen Ihrer Variablen und konvertieren alles in eine einzeilige Zeichenfolge, wodurch der Debugging-Prozess fast unmöglich wird.

CommonJS, AMD, RequireJS - Probieren Sie es aus

JavaScript verfügt nativ über keinen Mechanismus zum Verwalten von Modulen. All diese Dinge wurden erfunden, um dieses Problem zu lösen. Sie bieten eine API, mit der Sie Module definieren und verwenden können. Hier ein Beispiel aus http://requirejs.org/:

   Mein Beispielprojekt     

Mein Beispielprojekt

Innen main.js, Sie können verwenden benötigen() um andere Skripte zu laden, die Sie benötigen:

required (["helper / util"], function (util) // Diese Funktion wird aufgerufen, wenn scripts / helper / util.js geladen wird. // Wenn util.js define () aufruft, wird diese Funktion erst ausgelöst // die Abhängigkeiten von util wurden geladen, und das Argument util hält den Modulwert für "helper / util".);

Verwenden Sie Namensräume

Wenn wir über die Code-Organisation sprechen, können wir den Teil über Namespaces nicht überspringen. Natürlich gibt es keine solche Funktion in JavaScript, aber Sie können dasselbe mit etwas Code erreichen. Wenn Sie beispielsweise ein eigenes MVC-Framework erstellen möchten, verfügen Sie wahrscheinlich über die folgenden Klassen:

var model = function () …; var view = function () …; var controller = function () …;

Wenn Sie die Dinge im obigen Code belassen, werden sie öffentlich, und es besteht eine größere Chance, Konflikte mit anderen Bibliotheken in Ihrem Projekt zu verursachen. Wenn Sie sie in einem unabhängigen Objekt (Namespace) gruppieren, wird das Framework geschützt:

var MyAwesomeFramework = Modell: Funktion () …, Ansicht: Funktion () …, Controller: Funktion () …

Folgen Sie den Entwurfsmustern

Das Rad muss nicht neu erfunden werden. JavasScript wurde sehr populär und es gibt eine Menge guter Praktiken. Entwurfsmuster sind wiederverwendbare Lösungen für allgemeine Probleme bei der Programmierung. Wenn Sie einige davon befolgen, können Sie eine gute Anwendung erstellen. Wenn ich jedoch versuche, alle hier zu behandeln, müsste ich ein Buch schreiben. Hier sind nur einige davon:

Konstruktionsmuster

Verwenden Sie dieses Muster, um eine Instanz eines bestimmten Objekttyps zu erstellen. Hier ist ein Beispiel:

var Klasse = Funktion (param1, param2) this.var1 = param1; this.var2 = param2;  Class.prototype = method: function () alert (this.var1 + "/" + this.var2); ;

Oder du kannst es versuchen:

Funktionsklasse (param1, param2) this.var1 = param1; this.var2 = param2; this.method = function () alert (param1 + "/" + param2); ; ; var Instanz = neue Klasse ("value1", "value2");

Modulmuster

Das Modulmuster gibt uns die Möglichkeit, private und öffentliche Methoden zu erstellen. Im folgenden Code beispielsweise die Variable _Index und die Methode privateMethod sind privat. Zuwachs und getIndex sind öffentlich.

var Modul = (function () var _index = 0; var privateMethod = function () return _index * 10; return increment: function () _index + = 1;, getIndex: function () return _index; ;) ();

Beobachtermuster

Wo immer Sie Abonnements oder das Versenden von Ereignissen sehen, werden Sie dieses Muster wahrscheinlich sehen. Es gibt Beobachter, die sich für etwas interessieren, das sich auf ein bestimmtes Objekt bezieht. Sobald die Aktion ausgeführt wird, benachrichtigt das Objekt die Beobachter. Das folgende Beispiel zeigt, wie wir einen Beobachter hinzufügen können Benutzer Objekt:

var Users = list: [], listeners: , add: function (name) this.list.push (name: name); this.dispatch ("Vom Benutzer hinzugefügt"); , on: function (eventName, Listener) if (! this.listeners [eventName]) this.listeners [eventName] = []; this.listeners [eventName] .push (Listener); , dispatch: function (eventName) if (this.listeners [eventName])) für (var i = 0; i 

Funktionsverkettungsmuster

Dieses Muster ist eine gute Möglichkeit, die öffentliche Schnittstelle Ihres Moduls zu organisieren. Das spart Zeit und verbessert die Lesbarkeit:

var User = Profil: , Name: Funktion (Wert) this.profile.name = Wert; kehre das zurück; , job: function (value) this.profile.job = value; kehre das zurück; , getProfile: function () return this.profile; ; var profile = User.name ("Krasimir Tsonev"). job ("Webentwickler"). getProfile (); console.log (Profil);

Ich empfehle Ihnen dringend, dieses Buch von Addy Osmani zu lesen. Dies ist eine der besten Ressourcen, die Sie über Designmuster in JavaScript finden können.


Assets-Pack

Jetzt, da wir uns dem Ende dieses Artikels nähern, möchte ich ein paar Gedanken zum CSS- und JavaScript-Code-Management auf dem Server teilen. Es ist eine sehr gebräuchliche Technik, das Zusammenführen, Minifizieren und Kompilieren in die Logik der Anwendung einzufügen. Oft gibt es einen Zwischenspeicherungsmechanismus, aber alle Vorgänge passieren zur Laufzeit. Sie haben also wahrscheinlich eine Codelogik, die die Anfrage bearbeitet .js oder .css Dateien und liefert den richtigen Inhalt. Hinter diesem Prozess steht die Zusammenstellung, Minifizierung oder was auch immer Sie zum Packen Ihrer Assets verwenden.

In meinen neuesten Projekten habe ich ein Werkzeug namens verwendet Assets-Pack. Es ist wirklich hilfreich und ich erkläre im Detail, was genau es tut, aber der interessantere Teil ist, wie ich es verwendet habe. Diese Bibliothek sollte nur im Entwicklungsmodus verwendet werden. Sie verbleibt nicht in Ihrer Codebase und sollte nicht auf Ihrem Produktionsserver bereitgestellt werden.

Die Idee ist, den Packer nur zu verwenden, wenn Sie an den Assets (CSS, JS) arbeiten. Es überwacht tatsächlich Änderungen in bestimmten Verzeichnissen und kompiliert / packt den Code in einer einzigen Datei. Bei diesem Ansatz müssen Sie nicht über die Minifizierung oder Zusammenstellung nachdenken. Sie müssen lediglich die kompilierte statische Datei an den Benutzer senden. Dies erhöht die Leistung Ihrer Anwendung, da sie nur statische Dateien bereitstellt und natürlich die Sache vereinfacht. Sie müssen auf Ihrem Server nichts einstellen oder unnötige Logik implementieren.

So können Sie einrichten und verwenden Assets-Pack.

Installation

Dieses Tool ist ein Nodejs-Modul. Daher sollten Sie bereits Node installiert haben. Falls nicht, gehen Sie einfach zu nodejs.org/download und holen Sie sich das Paket für Ihr Betriebssystem. Nachdem:

npm install -g assetspack

Verwendungszweck

Das Modul arbeitet mit der JSON-Konfiguration. Wenn es über die Befehlszeile verwendet wird, sollten Sie Ihre Einstellungen in a einfügen .Json Datei.

Über die Befehlszeile

Erstelle ein assets.json Datei und führen Sie den folgenden Befehl im selben Verzeichnis aus:

Assetspack

Wenn Ihre Konfigurationsdatei einen anderen Namen verwendet oder sich in einem anderen Verzeichnis befindet, verwenden Sie Folgendes:

assetspack --config [Pfad zur Json-Datei]

In Code

var AssetsPack = required ("assetspack"); var config = [type: "css", watch: ["css / src"], Ausgabe: "tests / package / styles.css", minify: true, ausschließen: ["custom.css"]]; var pack = new AssetsPack (config, function () console.log ("AssetsPack überwacht");); pack.onPack (function () console.log ("AssetsPack hat den Job gemacht"););

Aufbau

Die Konfiguration sollte eine gültige JSON-Datei / ein gültiges Objekt sein. Es ist nur ein Array von Objekten:

[(Objektobjekt), (Objektobjekt), (Objektobjekt),…]

Asset-Objekt

Die Grundstruktur des Asset-Objekts sieht folgendermaßen aus:

Typ: (Dateityp / Zeichenfolge, könnte zum Beispiel css, js oder weniger sein), watch: (Verzeichnis oder Verzeichnisse für die Überwachung von / Zeichenfolge oder Array von Zeichenfolgen /), pack: (Verzeichnis oder Verzeichnisse für Packen / Zeichenfolge oder Array von strings /.), Ausgabe: (Pfad zur Ausgabedatei / string /), minify: / boolean /, exclude: (Array der Dateinamen)

Das Pack Eigenschaft ist nicht obligatorisch. Wenn Sie es vermissen, ist sein Wert gleich sehen. abbauen ist standardmäßig falsch.

Hier einige Beispiele:

CSS verpacken

Typ: "css", watch: ["tests / data / css", "tests / data / css2"], pack: ["tests / data / css", "tests / data / css2"], ausgabe: " tests / package / styles.css ", minify: true, ausschließen: [" header.css "]

JavaScript verpacken

Typ: "js", watch: "tests / data / js", pack: ["tests / data / js"], Ausgabe: "tests / package / scripts.js", minify: true, ausschließen: ["A .js "]

Verpackung .Weniger Dateien

Die Verpackung von .Weniger Dateien ist ein bisschen anders. Das Pack Eigenschaft ist obligatorisch und es ist im Grunde Ihr Einstiegspunkt. Sie sollten alle anderen importieren .Weniger Dateien dort. Das ausschließen Eigenschaft ist hier nicht verfügbar.

Typ: "less", watch: ["tests / data / less"], pack: "tests / data / less / index.less", Ausgabe: "tests / package / styles-less.css", minify: true 

Bei Problemen überprüfen Sie bitte die Tests / Pack-Less.spec.js des Repository in GitHub.

Andere Dateiformate packen

Assets-Pack funktioniert mit jedem Dateiformat. Beispielsweise können wir HTML-Vorlagen in einer einzigen Datei kombinieren, indem Sie Folgendes tun:

Typ: "html", watch: ["tests / data / tpl"], Ausgabe: "tests / package / template.html", ausschließen: ["admin.html"]

Das einzige, was Sie hier wissen sollten, ist, dass es keine Minifizierung gibt.


Fazit

Als Front-End-Webentwickler sollten wir versuchen, die bestmögliche Leistung für unsere Benutzer bereitzustellen. Die obigen Tipps sollen nicht alle Aspekte der Asset-Organisation und -Leistung abdecken, aber ich habe sie in meiner täglichen Arbeit persönlich behandelt. Bitte teilen Sie einige Ihrer Tipps in den Kommentaren mit.