In diesem Artikel wird eine moderne Website-Designmethode vorgestellt und erläutert, wie mithilfe von HTML5 und Browser-Rendering-Mechanismen von flach bis tief eine leistungsstarke Website erstellt wird.
Dieser Artikel beinhaltet viele Prinzipien der Browser-Neuzeichnung und Leistungsoptimierung. Er ist auch eine Erweiterung und Fortsetzung von „Web Scrolling Performance Optimization Practice“. Bitte lesen Sie diesen Artikel, bevor Sie ihn lesen .
Einleitung
Parallax-Seiten liegen in letzter Zeit voll im Trend, schauen Sie sich einfach diese Seiten an:
Old Pulteney Row to the Pole
Adidas Snowboarding
BBC News – James Bond: Autos, Schlagworte und Küsse
Falls Sie sie noch nicht kennen: Es handelt sich tatsächlich um Websites, bei denen sich die visuelle Struktur der Seite beim Scrollen ändert. Unter normalen Umständen werden Elemente auf der Seite skaliert, gedreht oder an die Scroll-Position verschoben.
Demoseite unseres Parallax-Effekts
Es ist eine Sache, ob Sie Parallax-Websites mögen, aber wir können bestätigen, dass es sich definitiv um ein schwarzes Leistungsloch handelt . Der Grund dafür ist, dass der Browser beim Scrollen versucht, Leistungsoptimierungen daran vorzunehmen, wo neue Inhalte angezeigt werden (basierend auf der Scrollrichtung). Generell gilt: Je weniger optisch aktualisiert der Browser ist, desto besser. Dies ist bei Parallaxen-Websites selten, da sich große visuelle Elemente auf der Seite mehrmals ändern, was dazu führt, dass der Browser die gesamte Seite neu zeichnen muss (warum es sich um ein schwarzes Leistungsloch handelt, erfahren Sie in meinem Artikel „Praxis zur Optimierung der Web-Scroll-Leistung“) ").
Es ist sinnvoll, Parallax-Websites wie folgt zusammenzufassen:
1. Wenn Sie auf der Seite nach oben oder unten scrollen, ändert das Hintergrundelement seine Position, dreht oder skaliert.
2. Seiteninhalte wie Text oder kleine Bilder scrollen in einer speziellen Weise von oben nach unten.
Wir haben bereits die Scrollleistung vorgestellt und erklärt, wie Sie sie optimieren können, um die Reaktionsfähigkeit Ihrer App zu verbessern. Dieser Artikel baut darauf auf, daher müssen Sie zuerst den obigen Artikel lesen.
Die Frage ist nun also: Wenn Sie eine Parallax-Scrolling-Website erstellen, müssen Sie dann teure Neulackierungen vornehmen, oder gibt es andere Methoden, die Sie anwenden können, um die Leistung zu maximieren? Werfen wir einen Blick auf die Optionen.
Methode 1: Verwendung von DOM-Elementen und absoluter Positionierung
Dies ist wahrscheinlich die Methode, die die meisten Menschen wählen. Es gibt viele Elemente auf der Seite, und wenn Scroll-Ereignisse ausgelöst werden, werden viele visuelle Aktualisierungen an diesen Elementen vorgenommen. Hier zeige ich eine Demoseite.
Wenn Sie den Rahmenmodus in der Zeitleiste der Entwicklertools aktivieren und nach oben oder unten scrollen, werden Sie kostspielige Zeichenvorgänge im Vollbildmodus bemerken. Wenn Sie mehrmals scrollen, sehen Sie möglicherweise mehrere Scroll-Ereignisse in einem einzelnen Frame, die jeweils Layoutarbeiten auslösen.
Die Entwicklertools zeigen eine große Anzahl von Zeichenvorgängen und mehrere ereignisgesteuerte Layouts in einem Frame an
Um dies zu erreichen, ist es wichtig, sich daran zu erinnern Bei 60 fps (entspricht einer typischen Monitor-Bildwiederholfrequenz von 60 Hz) müssen wir alles in fast 16 ms erledigen. In dieser ersten Version müssen wir jedes Mal, wenn wir ein Scroll-Ereignis erhalten, ein visuelles Update durchführen, aber wie wir in den vorherigen Artikeln besprochen haben – „Verwenden von requestAnimationFrame zum Implementieren einfacherer Animationen“ und „Praxis zur Optimierung der Web-Scroll-Leistung“ Dies ist nicht konsistent mit den Aktualisierungsrhythmus des Browsers. Entweder verpassen wir Frames oder wir erledigen zu viel Arbeit in einem Frame. Dies kann leicht dazu führen, dass Ihre Website unbequem und unnatürlich aussieht, was zu Frustration bei den Benutzern führt.
Verschieben wir den visuellen Aktualisierungscode vom Scroll-Ereignis in den Rückruf requestAnimationFrame und rufen wir einfach den Scroll-Wert im Rückruf des Scroll-Ereignisses ab. Wir demonstrieren diese Änderung in unserer zweiten Demo.
Wenn Sie den Rolltest wiederholen, stellen Sie möglicherweise eine leichte Verbesserung fest, wenn auch nicht viel. Der Grund dafür ist, dass durch Scrollen ausgelöste Layout-Vorgänge teuer sind und wir Layout-Vorgänge jetzt nur einmal pro Frame ausführen.
Die Entwicklertools zeigen eine große Anzahl von Zeichenvorgängen und mehrere ereignisgesteuerte Layouts in einem Frame
Wir können es jetzt in jedem Frame verarbeiten. Ein oder Hunderte von Scroll-Ereignissen, aber am wichtigsten ist, dass wir nur den neuesten Scroll-Wert speichern, um ihn zu verwenden, wenn der requestAnimationFrame-Rückruf ausgelöst wird, und visuelle Aktualisierungen durchzuführen. Der Schlüssel liegt darin, dass wir von der Optimierung visueller Aktualisierungen bei jedem Empfang eines Scroll-Ereignisses zu einer Optimierung im richtigen Moment übergegangen sind, der uns vom Browser vorgegeben wird. Glaubst du, das ist ziemlich mächtig?
Das Hauptproblem bei dieser Methode besteht darin, dass wir unabhängig davon, ob wir requestAnimationFrame verwenden oder nicht, grundsätzlich eine Ebene der gesamten Seite generieren, was beim Verschieben dieser visuellen Elemente viel und teure Arbeit erfordert Elemente Neu zeichnen . Normalerweise ist das Neuzeichnen ein blockierender Vorgang (obwohl dies optimiert wird), was bedeutet, dass der Browser nicht gleichzeitig andere Arbeiten ausführen kann, und wir überschreiten häufig das Frame-Verarbeitungszeitlimit des Browsers von 16 ms, was zu Leistungsverzögerungen führt. Dayton-Situation.
Methode 2: Verwendung von DOM-Elementen und 3D-Transformation
Zusätzlich zur absoluten Positionierung können wir als weitere Methode die 3D-Transformation (Transformation) verwenden. In diesem Fall können wir sehen, dass jedes mit der 3D-Transformation verarbeitete Element zu einer neuen Ebene führt. Im Gegensatz dazu müssen wir bei Methode 1 einen großen Teil der Seite neu zeichnen, wenn sich etwas ändert.
Das bedeutet, dass die Dinge bei dieser Methode ganz anders sind: Wir könnten eine Ebene für jedes Element haben, auf das eine 3D-Transformation angewendet wird. Wenn wir dies tun, indem wir mehr Elemente transformieren, müssen wir keine Ebenen neu zeichnen und die GPU ist in der Lage, Elemente zu verschieben und die gesamte Seite zusammenzustellen. Vielleicht fragen Sie sich, warum die 3D-Transformation anstelle der 3D-Transformation verwendet wird. Der Grund dafür ist, dass die 2D-Transformation nicht garantiert, dass eine neue Ebene entsteht, während die 3D transform macht .
Dies ist eine weitere Demo mit 3D-Transformation. Beim Scrollen können Sie sehen, dass sich die Leistung erheblich verbessert hat.
Viele Leute verwenden die Technik -webkit-transform:translateZ(0) und können wunderbare Leistungsverbesserungen feststellen (Yujie-Hinweis: Bei dieser Methode wird tatsächlich 3D-Konvertierung verwendet, um Browser-Hardware zu aktivieren Beschleunigung ist eine Art Hack, der in inländischen Informationen selten erwähnt wird, aber es gibt viele Artikel über die Leistungsoptimierung bei der Entwicklung mobiler Apps in China und „Verbesserung der Leistung von HTML5-Webseiten“ im Ausland „Steigerung der Leistung von HTML und JavaScript auf Mobilgeräten“). . Diese Methode kann jetzt normal funktionieren, bringt jedoch einige Probleme mit sich:
1. Sie ist nicht browserkompatibel
2. Sie zwingt den Browser, eine neue Ebene zu erstellen. Eine große Anzahl von Schichten kann zu weiteren Leistungsengpässen führen und muss daher sparsam eingesetzt werden.
3. Es ist auf einigen Webkit-Versionen von Ports deaktiviert.
Sie müssen also sehr vorsichtig sein, wenn Sie diese Methode anwenden, da es sich um eine vorübergehende Lösung des Problems handelt. In einer perfekten Welt würden wir nicht einmal darüber nachdenken, und wenn die Browser jeden Tag besser werden, wer weiß, vielleicht brauchen wir es eines Tages nicht mehr.
Methode 3: Verwenden Sie eine Leinwand mit fester Position oder WebGL
Die letzte Methode, die wir in Betracht ziehen müssen, besteht darin, eine Leinwand mit fester Position auf der Seite zu verwenden und das transformierte Bild einzufügen ist oben aufgetragen. Auf den ersten Blick ist dies vielleicht nicht die effizienteste Lösung, hat aber mehrere Vorteile:
Wir brauchen nicht mehr viel Compositing-Arbeit, Weil die Seite nur ein Element hat – Canvas; Für uns ist es die Art der durchzuführenden Transformationen, was bedeutet, dass Entwicklung und Wartung einfacher zu handhaben sind.
Durch die Verwendung des Canvas-Elements erhalten wir eine neue Ebene, die jedoch nur eine Ebene hat, während wir bei Methode 2 eine neue Ebene für jedes Element erstellen, auf das die 3D-Transformation angewendet wird, sodass zusätzliche Arbeit erforderlich ist. Diese Ebenen werden zusammengesetzt zusammen.
Wenn Sie sich die Demonstration dieser Methode ansehen und sie in den Entwicklertools beobachten, werden Sie feststellen, dass ihre Leistung noch besser ist. Bei dieser Methode müssen wir nur die API drawImage auf Canvas aufrufen, das Hintergrundbild festlegen und jeden Farbblock an der richtigen Position auf dem Bildschirm zeichnen.
/** * Updates and draws in the underlying visual elements to the canvas. */ function updateElements () { var relativeY = lastScrollY / h; // Fill the canvas up context.fillStyle = "#1e2124"; context.fillRect(0, 0, canvas.width, canvas.height); // Draw the background context.drawImage(bg, 0, pos(0, -3600, relativeY, 0)); // Draw each of the blobs in turn context.drawImage(blob1, 484, pos(254, -4400, relativeY, 0)); context.drawImage(blob2, 84, pos(954, -5400, relativeY, 0)); context.drawImage(blob3, 584, pos(1054, -3900, relativeY, 0)); context.drawImage(blob4, 44, pos(1400, -6900, relativeY, 0)); context.drawImage(blob5, -40, pos(1730, -5900, relativeY, 0)); context.drawImage(blob6, 325, pos(2860, -7900, relativeY, 0)); context.drawImage(blob7, 725, pos(2550, -4900, relativeY, 0)); context.drawImage(blob8, 570, pos(2300, -3700, relativeY, 0)); context.drawImage(blob9, 640, pos(3700, -9000, relativeY, 0)); // Allow another rAF call to be scheduled ticking = false; } /** * Calculates a relative disposition given the page’s scroll * range normalized from 0 to 1 * @param {number} base The starting value. * @param {number} range The amount of pixels it can move. * @param {number} relY The normalized scroll value. * @param {number} offset A base normalized value from which to start the scroll behavior. * @returns {number} The updated position value. */ function pos(base, range, relY, offset) { return base + limit(0, 1, relY - offset) * range; } /** * Clamps a number to a range. * @param {number} min The minimum value. * @param {number} max The maximum value. * @param {number} value The value to limit. * @returns {number} The clamped value. */ function limit(min, max, value) { return Math.max(min, Math.min(max, value)); }
Dieser Ansatz ist wirklich nützlich für den Umgang mit großen Bildern (oder anderen Elementen, die sich leicht auf eine Leinwand schreiben lassen) oder Große Textblöcke können sicherlich eine Herausforderung sein. Aber auf Ihrer Website könnte es sich als die am besten geeignete Lösung erweisen. Wenn Sie Text auf Canvas verarbeiten müssen, möchten Sie vielleicht die fillText-API verwenden, aber sie hat Zugriffskosten (Sie haben den Text gerade in eine Bitmap konvertiert!) und Sie müssen sich um den Textumbruch kümmern andere Probleme. Sie müssen versuchen, dies zu vermeiden.
Nachdem wir so viel besprochen haben, haben wir keinen Grund anzunehmen, dass das Canvas-Element verwendet werden muss, um mit Parallaxe zu arbeiten. Wir können WebGL verwenden, wenn der Browser es unterstützt. Der Schlüssel hier ist, dass WebGL der direkteste Weg von allen APIs zur Grafikkarte ist und wenn die Effekte Ihrer Website komplex sind, wird die Leistung höchstwahrscheinlich 60 fps erreichen.
Ihre unmittelbarste Reaktion könnte sein, dass die Verwendung von WebGL übertrieben ist oder nicht allgemein unterstützt wird. Wenn Sie jedoch eine Bibliothek ähnlich wie Three.js verwenden, können Sie jederzeit auf die Verwendung des Canvas-Elements zurückgreifen Gleichzeitig kann Ihr Code auf konsistente und benutzerfreundliche Weise abstrahiert werden. Wir müssen lediglich Modernizr verwenden, um die Unterstützung der entsprechenden API zu erkennen:
// check for WebGL support, otherwise switch to canvas if (Modernizr.webgl) { renderer = new THREE.WebGLRenderer(); } else if (Modernizr.canvas) { renderer = new THREE.CanvasRenderer(); }
Dann verwenden Sie Three.js API, und anstatt den Kontext selbst zu verwalten. Hier ist eine Demo, die beide Rendering-Methoden unterstützt.
Das letzte Problem bei diesem Ansatz besteht darin, dass Sie, wenn Sie nicht besonders gerne zusätzliche Elemente zur Seite hinzufügen, Canvas jederzeit als Hintergrundelement in Firefox- und Webkit-Browsern verwenden können. Offensichtlich ist dies nicht universell anwendbar, daher sollten Sie diesbezüglich vorsichtig sein.
Allmähliche Verschlechterung
Der Hauptgrund, warum Entwickler standardmäßig absolut positionierte Elemente anstelle anderer Methoden verwenden, könnte einfach eine Frage der Browserunterstützung sein. Dieser Ansatz ist in gewisser Weise falsch, da er für ältere Browser nur ein sehr schlechtes Rendering-Erlebnis bieten kann. Selbst in modernen Browsern führt die Verwendung der absoluten Positionierung nicht unbedingt zu einer guten Leistung.
Eine bessere Lösung besteht darin, Parallaxeneffekte nicht in älteren Browsern auszuprobieren und nur die besten Browser zu verwenden, um sicherzustellen, dass die richtige API zum Rendern des Site-Effekts verwendet werden kann. Wenn Sie Three.js verwenden, sollten Sie natürlich je nach benötigter Unterstützung problemlos zwischen Renderern wechseln können.
Fazit
Wir haben verschiedene Möglichkeiten zum Umgang mit stark neu gezeichneten Bereichen bewertet, von absolut positionierten Elementen bis hin zur Verwendung fest positionierter Leinwände. Natürlich hängt der von Ihnen gewählte Ansatz davon ab, was Sie erreichen möchten und von Ihrem spezifischen Design, aber es ist gut zu wissen, dass es Optionen gibt. Im Beispiel dieses Artikels ist es uns gelungen, von einem relativ verzögerten Effekt mit unter 30 Bildern pro Sekunde auf einen gleichmäßigen Effekt mit 60 Bildern pro Sekunde zu optimieren.
Das obige ist der detaillierte Inhalt vonAusführliche Erläuterung des Grafik- und Textcodes zum Aufbau einer leistungsstarken Parallaxen-Website mit HTML5. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!