Witam, po krótkiej przerwie spowodowanej przedłużonym weekendem oraz oglądaniem mundialu w Brazylii :) Na szczęście dziś wieczorem gra najmniej ciekawa grupa, postanowiłem więc wykorzystać to “okienko” na napisanie nowego wpisu. Nie mogę Was przecież za bardzo zaniedbywać… Ostatnimi czasy zauważyłem sporo wpisów w blogosferze (przynajmniej w tej, którą sam subskrybuję) na temat Velocity.js… Szczerze mówiąc nie znałem wcześniej tego pluginu jQuery. Jednak po bliższym zapoznaniu okazuje się, że to bardzo przydatna wtyczka, która znacznie usprawnia (od strony wydajnościowej) animacje UI. Zobaczmy więc o co ten cały szum!

Krótkie wprowadzenie

Jak już wspomniałem, Velocity to wtyczka, której autor ograniczył się “tylko” do napisania od nowa, dostępnej standardowo w jQuery, funkcji $.animate(). W wersji dostępnej w Velocity, nosi ona nazwę $.velocity() i ma taką samą składnię jak oryginał. Dzięki temu, mając już gotowy kod aplikacji wykorzystujący animacje UI**dostępnych w jQuery, wystarczy tylko pobrać Velocity, dodać skrypt do kodu strony i zamienić wszystkie wystąpienia $.animate() na $.velocity(). I voila, od tego momentu powinniśmy zauważyć znacznywzrost wydajności animacji UI**.

Napisałem przed chwilą, że Velocity ma dokładnie taką samą składnię jak animate… Nie jest to do końca prawda, w tym sensie, że autor wtyczki “doposażył” ją w kilka dodatkowych usprawnień. W ten sposób większość operacji można zrobić tak jak w starej wersji (wsteczna kompatybilność) lub zamiast tego skorzystać z dodatkowych usprawnień (jeśli na przykład od razu tworzymy aplikację wykorzystując Velocity). Za chwilę pokażę na to kilka przykładów. Najpierw jednak, dla porządku zobaczmy jak wygląda standardowe wywołanie funkcji animate oraz jakie parametry możemy do niej przekazać (za oficjalną stroną projektu):

$div.velocity({
    property1: value1,
    property2: value2
}, {
    /* Velocity's default options: */
    duration: 400,
    easing: 'swing',
    queue: '',
    begin: null,
    progress: null,
    complete: null,
    loop: false,
    delay: false,
    display: false,
    mobileHA: true
});

Jak widać, wygląda to podobnie do standardowego podejścia. Funkcję velocity wywołuje się na rzecz uchwytu jQuery do elementu DOM. Podobieństwa na tym się nie kończą. Tak samo jak w przypadku funkcji animate, tak i tutaj możliwe jest przekazywanie do funkcji zarówno parametrów oddzielonych przecinkami jak i jako obiekty parametrów.

1# przykład użycia wtyczki

Skoro wiemy już jaka jest składnia wywoływania funkcji velocity, zobaczmy jak możemy ją wykorzystać w praktyce. W naszym przykładzie zrobimy coś prostego - niech to będzie powolne zmienianie przezroczystości obrazka (chyba najczęściej występujący przykład w internecie). Zobaczmy więc jak to zrobić:

$('img').velocity({
    opacity: 0.8
}, {
    duration: 400,
    completed: function() {
        alert('animation finished');
    }
});

Powyższe pokazuje, że korzystanie z velocity właściwie niczym nie różni się od podejścia stosowanego w jQuery. Jako pierwszy parametr podajemy obiekt zawierający informację do jakich wartości właściwości CSS będziemy docelowo animować element. Drugi obiekt zawiera już ustawienia animacji - w tym przypadku jest to tylko czas trwania animacji oraz funkcja zwrotna wykonywana po zakończeniu animacji. Takie wywołanie jest identyczne z tym, które musielibyśmy zastosować używając funkcji animate z jQuery (dociekliwi, porównując opcje dostępne w Velocity i w jQuery zauważą pewnie, że nieznacznie różnią się one jeśli chodzi o dostępne callbacki jednak i bez nich wtyczka spełnia wszystkie swoje zadania).

2# przykład usprawnienia - wracanie do poprzednich ustawień

Wspomniałem wcześniej, że dzięki Velocity.js mamy możliwość usprawnić trochę kod odpowiedzialny za tworzenie animacji UI. Oto jeden z przykładów na to… W jQuery, chcąc wykonać animację “w tę i z powrotem”, czyli na przykład najpierw zmniejszyć przezroczystość obrazka a zaraz potem z powrotem ją zwiększyć, musimy napisać kod podobny do tego:

$('img')
  .animate({ opacity: 0.6 }, { duration: 400 }})
  .animate({ opacity: 1 }, { duration: 400 });

Niby prosta sprawa, ale żeby to napisać musimy wiedzieć jaki był wyjściowy styl CSS dla tego elementu (w tym przypadku opacity wraca do wartości 1).

W przypadku Velocity.js jest to fajnie usprawnione:

$('img')
  .velocity({ opacity: 0.6 }, { duration: 400 }})
  .velocity('reverse');

I już, nie trzeba się o nic martwić… Velocity.js samo będzie wiedziało jak wrócić do ustawienia wyjściowego.

Oczywiście to jest tylko jeden z najprostszych przykładów usprawnień zaimplementowanych w tej wtyczce. Zachęcam do bliższego zapoznania się z jej możliwościami - dużo informacji na ten temat znajdziecie w tym artykule na CSS Tricks.

Dlaczego animacje UI są lepsze przy użyciu Velocity.js?

Przedstawiłem już główne założenia tego rozwiązania, pora teraz zastanowić się po co to komu i czy warto? Przecież raz, że mamy możliwość wykonywania animacji za pomocą CSS (tranzycje), które zapewne są szybsze skoro są wspierane przez przeglądarkę internetową. Z drugiej strony to chyba animacje UI za pomocą jQuery nie są aż takie złe?

No cóż, jak udowadnia sam autor Velocity.js w swoim artykule, nie do końca tak jest… Otóż, podsumowując informacje z tego artykułu, rozwiązania takie jakVelocity.js są lepsze ponieważ:

  • animacje jQuery (jako najmniej wydajne rozwiązanie) działają wolno ponieważ, po pierwsze wykonują wiele odczytów i zapisów do drzewa elementów DOM co powoduje “zwiechy” layoutu; po drugie duże użycie pamięci przez tę bibliotekę może powodować “zamrażanie” animacji; po trzecie korzystają pod spodem z funkcji setInterval zamiast requestAnimationFrame
  • animacje CSS (na pewno wydajniejsze od jQuery) również nie są idealne ponieważ, po pierwsze nie działają poniżej IE10; po drugie animacje, w których wymuszono akcelerację sprzętową, mogą zbyt obciążać GPU, szczególnie na urządzeniach mobilnych
  • animacje za pomocą Velocity.js rozwiązują powyższe problemy po pierwsze poprzez minimalizację skanowania drzewa DOM podczas animacji (m.in. dzięki cache’owaniu właściwości CSS w łańcuchach wywołań); po drugie poprzez pomijanie aktualizacji stylów elementów jeśli są one niedostrzegalne

Podsumowanie

Jak więc widać Velocity.js przede wszystkim znacznie poprawia animacje UI pod względem wydajności, zarówno na komputerach jak i na smartfonach. Jeśli tworzymy interfejs użytkownika, który jest “responsywny” i pełen wodotrysków, na pewno warto rozważyć użycie tego pluginu.

Co do sposobu jego użycia i dostępnych usprawnień, to pokazałem tylko ułamek dostępnych możliwości - myślę, że to temat na osobny wpis albo nawet ich serię… Tymczasem zachęcam do zapoznania się ze wszystkimi możliwościami na stronie projektu.