co robi -webkit-transform: translate3d (0,0,0); dokładnie zrobić? Zastosuj do ciała?

89

co -webkit-transform: translate3d(0,0,0); dokładnie robi? Czy ma jakieś problemy z wydajnością? Czy powinienem po prostu nałożyć go na ciało lub poszczególne elementy? Wydaje się, że drastycznie poprawia to przewijanie.

Dzięki za lekcję!

WIWIWWIISpitFire
źródło
4
Czego brakuje odpowiedzi: W rzeczywistości tłumaczy element o 0 pikseli na osi x, y i z. ;)
insertusernamehere
Ma również wpływ na renderowanie czcionek, szczególnie widoczne na dużych czcionkach. W przeciwnym razie gładkie krawędzie ponownie pojawią się aliasowane. Może to być specyficzne dla przeglądarki lub systemu operacyjnego, zaobserwowano to w Chrome 33 w systemie Windows 7.
patrickj
1
@patrickj Zacząłem też zauważać nieco inne zachowanie translate3d(0,0,0)w Chrome 33 (33.0.1750.117m) w Windows 7. Sprawiło to, że jeden z moich elementów stał się niewidoczny, więc usunąłem go.
David Sherret
2
Na przyszłość: will-changeoddzieli również element HTML na własną warstwę. developer.mozilla.org/en-US/docs/Web/CSS/will-change . will-changezastąpi -webkit-transform:translate3d(0,0,0)włamanie.
Jason Lydon
nie używaj go z * css selector wszystkie moje linki stały się nieaktywne :)
stefan

Odpowiedzi:

112

-webkit-transform: translate3d(0,0,0); sprawia, że ​​niektóre urządzenia uruchamiają akcelerację sprzętową.

Dobra lektura znajduje się tutaj

Aplikacje natywne mogą uzyskiwać dostęp do graficznej jednostki przetwarzania (GPU) urządzenia, aby piksele latały. Z drugiej strony aplikacje internetowe działają w kontekście przeglądarki, co pozwala oprogramowaniu wykonać większość (jeśli nie całość) renderowania, co skutkuje mniejszą mocą na przejścia. Jednak internet nadrabia zaległości i większość producentów przeglądarek zapewnia teraz graficzne przyspieszanie sprzętowe za pomocą określonych reguł CSS.

Użycie -webkit-transform: translate3d(0,0,0);spowoduje, że GPU zacznie działać przy przejściach CSS, czyniąc je płynniejszymi (wyższy FPS).

Uwaga: translate3d(0,0,0) nic nie robi pod względem tego, co widzisz. przesuwa obiekt o 0px na osi x, y i z. To tylko technika wymuszenia przyspieszenia sprzętowego.


Alternatywą jest -webkit-transform: translateZ(0). A jeśli w Chrome i Safari pojawia się migotanie z powodu transformacji, spróbuj -webkit-backface-visibility: hiddeni -webkit-perspective: 1000. Więcej informacji znajdziesz w tym artykule .

Yotam Omer
źródło
Nie jestem pewien, czy zastosowanie transformacji macierzy do tekstury w pamięci podręcznej naprawdę poprawiłoby korzyści. Gdy zawartość jest przenoszona z tekstury przechowywanej w pamięci podręcznej do bufora ramki, transformacja zwiększyłaby wydajność złożonych operacji, ale nie przyniosłaby korzyści w przypadku normalnych zdarzeń malowania. Nie zaszkodzi ani nie przyniesie żadnych korzyści. Popraw mnie, jeśli się mylę?
Mathew Kurian
Myślę, że nawet zwykłe farby zostaną przyspieszone. Jednym z kryteriów tworzenia warstw jest „3D lub transformacja perspektywiczna właściwości CSS”.
Yotam Omer
Na przykład karuzela bootstrapa używa tego, podczas przesuwania wyświetlanego obrazu z prawej strony na lewą.
Ethan
@YotamOmer Czy możemy alternatywnie użyć translateZ (0) lub scale3d (1,1,1), aby włączyć akcelerator H / W?
Ethan
1
@Ethan Tak, zgodnie z tym oba powinny działać. Wiedziałem tylko o transformacji 3D, ale najwyraźniej translateZteż załatwi sprawę w większości przeglądarek.
Yotam Omer
12

Nie widziałem tutaj odpowiedzi, która to wyjaśnia. Można wykonać wiele przekształceń, obliczając każdą z opcji divi jej opcji przy użyciu skomplikowanego zestawu walidacji. Jeśli jednak korzystasz z funkcji 3D, każdy z elementów 2D, które masz, jest traktowany jako elementy 3D i możemy wykonać transformację macierzową tych elementów w locie. Jednak większość elementów jest już „technicznie” akcelerowana sprzętowo, ponieważ wszystkie korzystają z GPU. Ale transformacje 3D działają bezpośrednio na buforowanych wersjach każdego z tych renderów 2D (lub buforowanych wersji div) i bezpośrednio używają na nich transformacji macierzowej (które są wektoryzowane i równoległe do matematyki FP).

Ważne jest, aby pamiętać, że transformacje 3D powodują TYLKO zmiany w funkcjach w buforowanym elemencie div 2D (innymi słowy, element div jest już renderowanym obrazem). Tak więc rzeczy takie jak zmiana szerokości i koloru obramowania nie są już „3D”, mówiąc niejasno. Jeśli się nad tym zastanowić, zmiana szerokości obramowania wymaga ponownego wyrejestrowania argumentu „ divponieważ” i ponownego jego zbrojenia, aby można było zastosować transformacje 3D.

Mam nadzieję, że to ma sens i daj mi znać, jeśli masz więcej pytań.

Odpowiadając na twoje pytanie, translate3d: 0x 0y 0znic by nie zrobiło, ponieważ transformacje działają bezpośrednio na teksturze utworzonej przez uruchomienie wierzchołków divw module cieniującym GPU. Ten zasób modułu cieniującego jest teraz buforowany, a podczas rysowania do bufora ramki zostanie zastosowana macierz. Więc zasadniczo nie ma z tego żadnej korzyści.

W ten sposób przeglądarka działa wewnętrznie.

Krok 1: Analiza danych wejściowych

<div style = "position:absolute;left:0;right:0;bottom:0;top:0;"></div>

Krok 2: Opracuj warstwę kompozytową

CompositeLayer compLayer = new CompositeLayer();
compLayer.setPosition(0, 0, 0, 0);
compLayer.setPositioning(ABSOLUTE); // Note. this is psuedocode. The actual code
Pipeline.add(compLayer, zIndex); // would be significantly more complex.

Krok 3: Renderuj warstwę kompozytową

for (CompositeLayer compLayer : allCompositeLayers){

     // Create and set cacheTexture as active target
     Texture2D cacheTexture = new Texture2D();
     cacheTexture.setActive();

     // Draw to cachedTexture
     Pipeline.renderVertices(compLayer.getVertices());
     Pipeline.setTexture(compLayer.getBackground());
     Pipeline.drawIndexed(compLayer.getVertexCount());

     // Set the framebuffer as active target
     frameBuffer.setActive();

     // Render to framebuffer from texture and **applying transformMatrix**
     Pipeline.renderFromCache(cacheTexture, transformMatrix);
}
Mathew Kurian
źródło
6

Występuje błąd z przewijaniem w MobileSafary (iOS 5), który prowadzi do pojawiania się artefaktów jako kopii elementów wejściowych w kontenerze przewijania.

Użycie translate3d dla każdego elementu podrzędnego może naprawić ten dziwny błąd. Oto przykład CSS, który uratował mi dzień.

.scrolling-container {
    overflow: auto;
    -webkit-overflow-scrolling: touch;
}

.scrolling-container .child-element {
    position: relative;
    -webkit-transform: translate3d(0,0,0);
}
Serge Seletskyy
źródło
5

Translate3D wymusza przyspieszenie sprzętowe. Animacje CSS, transformacje i przejścia nie są automatycznie przyspieszane przez GPU , a zamiast tego są wykonywane z wolniejszego silnika renderującego w przeglądarce. Aby korzystać z GPU, używamy translate3d

Obecnie przeglądarki takie jak Chrome, FireFox, Safari, IE9 + i najnowsza wersja Opery są wyposażone w akcelerację sprzętową, używają jej tylko wtedy, gdy istnieją wskazania, że ​​element DOM mógłby na tym skorzystać.

Prasanna Aarthi
źródło
3

Należy pamiętać, że tworzy kontekst stosu (plus co druga odpowiedzi powiedziane), więc to ma potencjalnie mieć wpływ na to, co widzisz, np zrobienie czegoś pojawiają się nad nakładkę, gdy nie ma.

Jason Young
źródło