Bilder mit der Anweisung für gewinkelte Bilder optimieren

Kara Erickson
Kara Erickson
Leena Sohoni
Leena Sohoni

Im Mai 2022 kündigten die Aurora- und Angular-Teams an, gemeinsam an einer Bildrichtlinie für Angular zu arbeiten. Die Direktive wurde vor Kurzem als Teil von Angular v14.2 in der Entwicklervorschau veröffentlicht. In diesem Beitrag erfahren Sie, wie die neue Bilddirektive NgOptimizedImage die Bildoptimierung in Angular unterstützt.

Hintergrund

Bilder sind eine gängige und wichtige Komponente der Nutzerfreundlichkeit im Web.99, 9% der Webseiten generieren Anfragen für ein oder mehrere Bilder. Bilder tragen auch am stärksten zum Seitengewicht bei und machen im Median 982 KiB pro Seite aus.

Aufgrund ihrer zunehmenden Anzahl und Größe können Bilder die Leistung von Webseiten beeinträchtigen und sich auf die Core Web Vitals auswirken. Bei 79, 4% der Desktopseiten war 2021 ein Bild das Largest Contentful Paint-Element (LCP). Die Suche nach optimierten Bildern ist für viele von uns zu einer ständigen Herausforderung geworden.

Das Aurora-Team setzt auf die Vorteile von Frameworks, um integrierte Lösungen für häufige Entwicklerherausforderungen bereitzustellen. Der erste Schritt in die Bildoptimierung war die Next.js-Bildkomponente. Diese Komponente sollte als Testgrundlage dienen, um herauszufinden, ob die Verbesserung der Entwicklerfreundlichkeit bei der Bildoptimierung zu Leistungssteigerungen bei mehr Apps mit Frameworks führen könnte.

Die ersten Ergebnisse des Next.js-Nutzers Leboncoin waren ermutigend. Leboncoin konnte den LCP nach der Einführung von next/image deutlich verbessern (von 2,4 Sekunden auf 1,7 Sekunden). Die anschließende Einführung von next/image in der Community hat dazu beigetragen, dass mehr Next.js-Quellen die LCP-Grenzwerte einhalten. Bald gab es Anfragen nach ähnlichen Funktionen in anderen Frameworks, darunter Angular.

Daher hat Aurora sich an Angular und Nuxt gewandt, um Bildkomponenten für diese Frameworks zu entwickeln. Die Nuxt-Bildkomponente wurde letztes Jahr veröffentlicht. Jetzt wurde die Angular-Bilddirektive (NgOptimizedImage) veröffentlicht, um Standardeinstellungen für die Bildoptimierung in Angular zu ermöglichen.

Empfehlung

Angular ist eines der führenden JavaScript-Frameworks, das von Entwicklern verwendet wird. Es wird von mehr als 50.000 Quellen verwendet, die von HTTPArchive auf Mobilgeräten gecrawlt werden, und verzeichnet fast 3 Millionen Downloads pro Woche auf NPM.

LCP für Angular-Websites im letzten Jahr

Bei den Core Web Vitals-Werten ist der Prozentsatz der Angular-Quellen, die die LCP-Grenzwerte für „Gut“ einhalten, noch verbesserungswürdig. Im Juni 2022 hatten nur 18,74% der Angular-Websites eine gute LCP auf Mobilgeräten. Da Bilder bei mehr als 70% der Webseiten auf Mobilgeräten und Computern das LCP-Element sind, können nicht optimierte LCP-Bilder eine der Hauptursachen für einen schlechteren LCP auf Angular-Websites sein.

Die Angular-Bilddirektive wurde entwickelt, um diese Zahlen zu verbessern.

MVP für die Direktive „NgOptimizedImage“

Das MVP der Angular-Bilddirektive baut auf den Erkenntnissen aus den bisher von Aurora entwickelten Bildkomponenten auf und passt das Design an das clientseitige Rendering von Angular an. Viele der Standardprobleme bei der Bildoptimierung wurden durch folgende Maßnahmen behoben:

  • Starke Standardeinstellungen bereitstellen
  • Fehler oder Warnungen ausgeben, um die Einhaltung der Best Practices zu gewährleisten.

Die Highlights des Designs sind:

  1. Intelligentes Lazy Loading

    Bilder, die beim Laden der Seite für den Nutzer nicht sichtbar sind (z. B. Bilder unterhalb des sichtbaren Bereichs oder ausgeblendete Karussellbilder), sollten idealerweise lazy-loaded werden. Durch das Lazy Loading werden Browserressourcen freigesetzt, um andere wichtige Texte, Medien oder Scripts zu laden. Die meisten Bilder sind nicht kritisch und sollten mit Lazy Loading geladen werden.2021 wurde jedoch nur auf 7, 8% der Seiten natives Lazy Loading verwendet.

    Die Angular-Bildanweisung lädt nicht kritische Bilder standardmäßig verzögert und nur Bilder, die speziell als priority gekennzeichnet sind, sofort. So wird sichergestellt, dass die meisten Bilder optimal geladen werden.

  2. Priorisierung wichtiger Bilder

    Ressourcenhinweise hinzufügen (z.B. preload oder preconnect), um das Laden wichtiger Bilder zu priorisieren, ist eine empfohlene Best Practice. Die meisten Apps nutzen sie jedoch nicht. Laut dem Web Almanac 2021 werden nur 12,7% der mobilen Seiten mit Vorverbindungshinweise und nur 22,1% der mobilen Seiten mit Vorabladehinweisen erstellt.

    Die Bildanweisung wirkt sich auf zwei Ebenen aus, wenn Bilder als „wichtig“ gekennzeichnet sind.

    • Die fetchpriority des Bildes wird auf "high" festgelegt, damit der Browser weiß, dass das Bild mit hoher Priorität heruntergeladen werden soll.
    • Im Entwicklungsmodus wird bei einer Laufzeitprüfung bestätigt, dass ein preconnect-Ressourcenhinweis für die Herkunft des Bildes enthalten ist.

    Im Entwicklungsmodus wird mit der Richtlinie auch die PerformanceObserver API verwendet, um zu prüfen, ob das LCP-Bild wie erwartet mit priority gekennzeichnet wurde. Wenn das nicht der Fall ist, wird ein Fehler ausgegeben, in dem der Entwickler aufgefordert wird, dem LCP-Bild das Attribut priority hinzuzufügen.priority

    Diese Kombination aus Automatisierung und Konformität sorgt dafür, dass das LCP-Bild einen preconnect-Hinweis, einen fetchpriority-Attributwert von high und kein Lazy Loading hat.

  3. Optimierte Konfiguration für gängige Bildtools

    Für Angular-Anwendungen wird empfohlen, Bild-CDNs zu verwenden, die häufig standardmäßig Optimierungsdienste bereitstellen.

    Die Richtlinie fördert die Verwendung von Bild-CDNs, indem sie eine besonders ansprechende Entwicklererfahrung (DX) zur Konfiguration in der App bietet. Sie unterstützt eine Loader API, mit der Sie den CDN-Anbieter und Ihre Basis-URL in Ihrer Konfiguration definieren können. Nach der Konfiguration müssen Sie nur noch den Asset-Namen im Markup definieren. Beispiel:

    // in module providers:
    provideImgixLoader('https://mysite.net/assets/')
    
    // in markup
    <img ngSrc="image.png" >
    <img ngSrc="image2.png" >
    

    Das entspricht dem Einfügen der folgenden Bild-Tags und reduziert das Markup, das Entwickler für jedes Bild einfügen müssen.

    <img src="https://mysite.net/assets/image.png">
    <img src="https://mysite.net/assets/image2.png">
    

    Die Bilddirektive bietet integrierte Loader mit einer optimalen Konfiguration für die gängigsten Bild-CDNs. Diese Loader formatieren Bild-URLs automatisch, damit für jedes CDN das empfohlene Bildformat und die empfohlenen Komprimierungseinstellungen verwendet werden.

  4. Integrierte Fehler und Warnungen

    Zusätzlich zu den oben genannten integrierten Optimierungen enthält die Richtlinie auch integrierte Prüfungen, um sicherzustellen, dass Entwickler die empfohlenen Best Practices im Bild-Markup befolgt haben. Die image-Direktive führt die folgenden Prüfungen durch.

    1. Ohne Größe:Die Bildanweisung gibt einen Fehler aus, wenn im Bild-Markup keine explizite Breite und Höhe definiert ist. Bilder ohne Größe können zu Layoutverschiebungen führen, die sich auf den Messwert „Cumulative Layout Shift“ (CLS) der Seite auswirken. Um dies zu vermeiden, sollten für Bilder die Attribute width und height angegeben werden.

    2. Seitenverhältnis:Die Bildanweisung gibt einen Fehler aus, um Entwickler darauf hinzuweisen, dass das Seitenverhältnis von width:height, das in der HTML-Datei definiert ist, nicht dem tatsächlichen Seitenverhältnis des gerenderten Bilds entspricht. Das kann dazu führen, dass das Bild auf dem Bildschirm verzerrt erscheint. Das kann in folgenden Fällen passieren:

      1. Sie haben versehentlich die falschen Abmessungen (Breite oder Höhe) definiert oder
      2. Wenn Sie eine Dimension in Ihrem CSS als Prozentsatz definiert haben, die andere aber nicht (z. B. width: 100% benötigt height: auto, damit das Bild in beiden Dimensionen wächst).
    3. Zu große Bilder:Wenn für das Bild kein srcset definiert ist und das ursprüngliche Bild deutlich größer als das gerenderte Bild ist, wird in der Anweisung eine Warnung angezeigt, in der die Verwendung der Attribute srcset und sizes empfohlen wird.

    4. Bilddichte:Die Direktive gibt einen Fehler zurück, wenn Sie versuchen, ein Bild in die srcset mit einer Pixeldichte von mehr als 3x einzufügen. Deskriptoren mit einer höheren Auflösung als 2x werden im Allgemeinen nicht empfohlen, da Mobilgeräte mit hoher Auflösung dadurch gezwungen werden, riesige Bilder herunterzuladen. Außerdem kann das menschliche Auge über 2-fach kaum einen Unterschied erkennen.

Herausforderungen

Eine der Hauptherausforderungen beim Entwerfen von NgOptimizedImage bestand darin, Strategien zur Bildoptimierung an ein clientseitiges Framework anzupassen. Das standardmäßige Rendering in Next.js ist das serverseitige Rendering (SSR) oder die statische Websitegenerierung (SSG), während in Angular das clientseitige Rendering (CSR) verwendet wird. Obwohl Angular eine SSR-Bibliothek unterstützt (angular/universal), verwenden die meisten Angular-Apps (ca. 60%) CSR.

Die image-Direktive wurde vollständig für CSR entwickelt, um dem typischen Anwendungsfall in Angular-Apps zu entsprechen. Das stellte zusätzliche Einschränkungen dar und das Team musste neu überlegen, wie es spezielle Optimierungen für CSR-Apps entwickeln konnte.

Einige der Herausforderungen sind:

  1. Unterstützende Ressourcenhinweise

    Wenn Sie wichtige Assets vorab laden, kann der Browser sie früher erkennen. Das Einfügen von Ressourcenhinweisen in Angular-Apps ist jedoch kompliziert, weil:

    Manuelle Hinzufügung: Es ist schwierig für Entwickler, den preload-Ressourcenhinweis manuell hinzuzufügen. In Angular wird eine gemeinsame index.html-Datei für das gesamte Projekt oder für alle Routen auf der Website verwendet. Daher ist die <head> des Dokuments für jede Route gleich (zumindest zum Zeitpunkt der Auslieferung). Wenn Sie der <head> einen preload-Hinweis hinzufügen, wird die Ressource für alle Routen vorab geladen, auch wenn sie nicht erforderlich ist. Daher wird das manuelle Hinzufügen von preload-Hinweisen nicht empfohlen.

    Automatische Hinzufügung während des Renderings:Es hilft nicht, dem Header des Dokuments während des Renderings in einer CSR-App mithilfe des Frameworks Hinweise zum Vorladen hinzuzufügen. Da das Rendering erst nach dem Herunterladen und Ausführen von JavaScript erfolgt, wird <head> zu spät gerendert, um einen Wert zu haben.

    In der ersten Version der Direktive wird anstelle einer preload eine Kombination aus preconnect- und fetchpriority-Hinweisen verwendet, um das Bild zu priorisieren. Aurora arbeitet jedoch derzeit mit dem Angular CLI-Team zusammen, um die automatische Einschleusung von Ressourcenhinweisen zur Buildzeit zu ermöglichen. Mehr dazu demnächst!

  2. Bildgröße und ‑format auf dem Server optimieren

    Da Angular-Apps in der Regel clientseitig gerendert werden, können Bilder im Dateisystem nicht zum Zeitpunkt der Anfrage komprimiert werden und werden unverändert bereitgestellt. Aus diesem Grund wird die Verwendung von Bild-CDNs empfohlen, um Bilder zu komprimieren und bei Bedarf in moderne Formate wie WebP oder AVIF umzuwandeln.

    Die Richtlinie erzwingt zwar nicht die Verwendung von Bild-CDNs, wir empfehlen sie jedoch dringend. Die integrierten Loader sorgen dafür, dass die richtigen Konfigurationsoptionen verwendet werden.

Auswirkungen

In der folgenden Demo wird der Unterschied veranschaulicht, den die Angular-Bilddirektive bei der Bildleistung bewirken kann. Dabei werden zwei Websites verglichen:

Website 1:Verwendet native <img>-Elemente mit Bildern, die über das Imgix-CDN bereitgestellt werden (mit Standardkonfigurationsoptionen).

Website 2:Verwenden Sie die Bildanweisung für alle Bilder. Außerdem enthält sie die Optimierungen, die direkt durch Warnungen oder Fehler empfohlen werden, die von der Richtlinie ausgegeben werden.

Filmstreifenvergleich: Website 1 mit nativen Bild-Tags und Website 2 mit der Angular-Bildrichtlinie

Das Team hat mit Partnern zusammengearbeitet, um die Auswirkungen der Bildrichtlinie auf die Leistung echter Angular-Anwendungen in Unternehmen zu überprüfen.

Einer dieser Partner war Land's End. Es wurde erwartet, dass die Website ein guter Testfall für Ergebnisse sein würde, die in realen Anwendungen auftreten könnten.

Vor und nach der Verwendung der Bildrichtlinie wurden Lighthouse-Lab-Tests in der QA-Umgebung durchgeführt. Auf dem Computer sank der mediane LCP von 12,0 Sekunden auf 3,0 Sekunden, was einer Verbesserung des LCP um 75% entspricht. Auf Mobilgeräten sank der mediane LCP von 20,2 Sekunden auf 12,0 Sekunden (40,6% Verbesserung).

Roadmap für die Zukunft

Dies ist nur die erste Version des Designs für die Angular-Bildrichtlinie. Für zukünftige Versionen sind viele weitere Funktionen geplant, darunter:

  • Bessere Unterstützung für responsive Bilder:

    NgOptimizedImage unterstützt derzeit die Verwendung von srcset. Die Attribute srcset und sizes müssen jedoch für jedes Bild manuell angegeben werden. Künftig könnten die Attribute srcset und sizes automatisch über die Direktive generiert werden.

  • Automatische Einfügung von Ressourcenhinweisen

    Es ist möglicherweise möglich, die Angular-Befehlszeile zu integrieren, um Preconnect- und Preloading-Tags für kritische LCP-Bilder zu generieren.

  • Unterstützung für SSR (Angular)

    Die MVP-Version wurde unter Berücksichtigung der Angular-CSR-Einschränkungen entwickelt. Es ist jedoch auch wichtig, Lösungen zur Bildoptimierung für Angular-SSR (Angular/Universal) zu untersuchen.

  • Verbesserungen für Entwickler

    Für NgOptimizedImage müssen die Attribute width und height für jedes Bild angegeben werden. Für einige Entwickler kann es jedoch mühsam sein, diese für jedes Bild anzugeben. In der nächsten Iteration können wir die Entwicklerfreundlichkeit hier so verbessern:

    1. Unterstützung eines zusätzlichen Modus (ähnlich der Bildlayoutoption „fill“ in Next.js), für den keine explizite Breite/Höhe definiert werden muss.
    2. Mit der CLI-Integration können Sie die Breite und Höhe für lokale Bilder automatisch festlegen, indem Sie die tatsächlichen Abmessungen des Bildes ermitteln.

Fazit

Die Angular-Bildanweisung wird für Entwickler schrittweise eingeführt, beginnend mit der Entwicklervorschauversion in Version 14.2.0. Probieren Sie NgOptimizedImage aus und geben Sie uns Feedback.

Ein besonderer Dank geht an Katie Hempenius und Alex Castle für ihren Beitrag.