Używamy cookies, żeby zwiększyć Twoje doświadczenia na stronie
CodeWorlds
Powrót do kolekcji
Przewodnik12 min czytania

Spline, sceny 3D na stronę internetową

Spline pozwala zbudować scenę 3D w przeglądarce i osadzić ją na stronie. Eksport do Reacta, realny koszt wydajnościowy, plany i kiedy to się opłaca.

Spline, czyli scena 3D bez pisania kodu graficznego

Umieszczenie trójwymiarowej sceny na stronie wymagało dotąd znajomości bibliotek graficznych, pojęć z grafiki komputerowej i sporo cierpliwości. Spline zamienia to w pracę w edytorze działającym w przeglądarce, przypominającą narzędzia do projektowania interfejsów.

Budujesz scenę wizualnie, dodajesz materiały, światła i interakcje, a potem eksportujesz ją do osadzenia na stronie. Wynik działa w przeglądarce, reaguje na kursor i przewijanie, i nie wymaga od Ciebie napisania ani jednej linii kodu graficznego.

To narzędzie ma jednak koszt, którego materiały o nim mówią mniej wyraźnie, niż powinny, i jest to koszt wydajnościowy. Poświęcam mu osobną sekcję, bo od niego zależy, czy warto po nie sięgać.

Jak wygląda praca

Edytor przypomina narzędzia do projektowania interfejsów, z osią czasu i panelem właściwości, więc osoba znająca Figmę odnajduje się w nim szybciej, niż w klasycznym programie do grafiki trójwymiarowej.

Scenę składasz z brył podstawowych, kształtów rysowanych na płaszczyźnie i wyciąganych w przestrzeń oraz modeli wczytanych z zewnątrz. Materiały ustawia się suwakami, a oświetlenie przez dodanie źródeł i ustawienie ich siły.

Interakcje są tu najciekawszą częścią i zarazem powodem, dla którego ludzie po to sięgają. Zdarzenie takie jak najechanie kursorem, kliknięcie albo przewinięcie strony uruchamia przejście do innego stanu sceny, opisanego wizualnie. Bez tego mechanizmu trójwymiarowa scena jest ozdobą, a z nim staje się elementem interfejsu.

Warto od początku pilnować liczby obiektów i rozmiaru tekstur. Scena, która w edytorze działa płynnie na mocnym komputerze, potrafi zatrzymać przewijanie na telefonie sprzed trzech lat, a różnicy nie widać, dopóki sam tego nie sprawdzisz na takim urządzeniu.

Osadzenie na stronie

Najprostsza droga to gotowy komponent wczytujący scenę z adresu. Instalujesz dwie paczki, bo silnik uruchomieniowy jest zależnością równorzędną i nie wciąga się sam w każdym menedżerze pakietów.

Code
Bash
npm install @splinetool/react-spline @splinetool/runtime
Code
TypeScript
import Spline from '@splinetool/react-spline'

export function Sekcja() {
  return <Spline scene="https://prod.spline.design/xxx/scene.splinecode" />
}

To działa i ma dwie konsekwencje, które warto znać. Pierwsza: scena pobierana jest z serwerów producenta, więc czas ładowania zależy od jego infrastruktury, a znikniecie usługi oznacza puste miejsce na Twojej stronie. Drugą jest brak kontroli nad momentem wczytania, o ile sam go nie dołożysz.

Bardziej świadomy układ polega na wczytywaniu sceny dopiero wtedy, gdy jest potrzebna, i pokazaniu czegoś w międzyczasie.

Code
TypeScript
import dynamic from 'next/dynamic'

const Spline = dynamic(() => import('@splinetool/react-spline'), {
  ssr: false,
  loading: () => <div className="h-[500px] bg-slate-100" />,
})

Wbrew rozpowszechnionemu przekonaniu wyłączenie renderowania po stronie serwera nie jest tu warunkiem uniknięcia awarii. Komponent jest oznaczony jako kliencki, a po obiekty przeglądarki sięga dopiero w efekcie uruchamianym po zamontowaniu, więc w Next.js nie psuje budowania. Dynamiczny import z wyłączonym renderowaniem serwerowym służy tu czemu innemu: odsunięciu pobrania paczki i pokazaniu własnego wypełniacza w tym czasie. Biblioteka ma zresztą osobne wejście @splinetool/react-spline/next, które renderuje po stronie serwera rozmyty podgląd wyliczony z samej sceny, więc miejsce nie jest puste w trakcie ładowania.

Dla osób pracujących bezpośrednio z bibliotekami graficznymi dostępny jest wariant wczytujący scenę do własnego drzewa obiektów, co pozwala mieszać elementy zaprojektowane w edytorze z kodem pisanym ręcznie.

Koszt wydajnościowy

To jest sekcja najważniejsza w tym tekście i rzecz, którą warto rozstrzygnąć przed podjęciem decyzji.

Pierwsza pozycja to rozmiar. Scena z kilkoma obiektami, teksturami i modelem wczytanym z zewnątrz waży zwykle kilka megabajtów, czyli tyle, co cała reszta typowej strony razem wzięta. Przy połączeniu mobilnym to są sekundy oczekiwania, zanim cokolwiek się pojawi.

Druga to obciążenie karty graficznej. Scena renderuje się w pętli przez cały czas, gdy jest widoczna, więc zużywa procesor graficzny nieprzerwanie. Na telefonie przekłada się to wprost na zużycie baterii i na płynność przewijania reszty strony.

Rozwiązaniem jest zatrzymanie renderowania, gdy scena wyjedzie poza ekran.

Code
TypeScript
const kontener = useRef<HTMLDivElement>(null)
const [widoczna, ustawWidoczna] = useState(false)

useEffect(() => {
  const obserwator = new IntersectionObserver(
    ([wpis]) => ustawWidoczna(wpis.isIntersecting),
    { rootMargin: '200px' }
  )
  if (kontener.current) obserwator.observe(kontener.current)
  return () => obserwator.disconnect()
}, [])

<div ref={kontener} className="h-[500px]">
  {widoczna && <Spline scene={ADRES} />}
</div>

Zapas dwustu pikseli w ustawieniach obserwatora sprawia, że scena zaczyna się wczytywać tuż przed wjechaniem w kadr, więc użytkownik nie widzi pustego miejsca, a poza kadrem nic się nie renderuje.

Trzecia to miary jakości strony. Duży zasób ładowany na początku pogarsza czas do wyświetlenia głównej treści, a element pojawiający się po wczytaniu przesuwa układ, jeśli nie zarezerwowałeś na niego miejsca.

Cztery rzeczy ograniczają ten koszt i warto zastosować wszystkie. Zarezerwuj wymiary elementu z góry, żeby układ się nie przesuwał. Wczytuj scenę dopiero, gdy zbliża się do widoku, zamiast przy wejściu na stronę. Zatrzymuj renderowanie, gdy scena wyjdzie poza widok albo gdy karta przestanie być aktywna. I przygotuj wariant zastępczy: statyczny obraz dla urządzeń słabszych albo dla osób, które w ustawieniach systemu ograniczyły animacje.

To ostatnie warto potraktować poważnie. Scena reagująca na ruch kursora u części osób wywołuje realny dyskomfort, a sprawdzenie odpowiedniego ustawienia to trzy linie kodu.

Warto też zmierzyć skutek, zamiast go szacować. Otwórz stronę w narzędziach deweloperskich z ograniczoną przepustowością sieci i spowolnionym procesorem, ustawionymi tak, żeby odpowiadały średniemu telefonowi. Liczba, którą zobaczysz, mówi więcej niż jakiekolwiek zalecenie ogólne, bo dotyczy Twojej sceny na Twojej stronie, a nie przykładu z dokumentacji. Ten test zajmuje pięć minut i regularnie kończy dyskusję o tym, czy scena zostaje na ekranie powitalnym.

Kiedy to ma sens

Warto rozdzielić zastosowania, w których narzędzie wygrywa, od tych, w których jest kosztowną ozdobą.

Wygrywa na stronie głównej produktu, gdzie użytkownik przychodzi raz, na krótko, a pierwsze wrażenie faktycznie decyduje. Trójwymiarowy model produktu obracany kursorem mówi więcej niż trzy zdjęcia i jest tym, co ludzie zapamiętują.

Wygrywa przy prezentacji rzeczy fizycznych. Mebel, urządzenie, opakowanie, element ubioru: obejrzenie ze wszystkich stron zastępuje galerię i zmniejsza liczbę pytań przed zakupem.

Wygrywa też przy stronach wydarzeń, portfolio i kampaniach, gdzie efekt jest częścią przekazu, a czas życia strony liczy się w tygodniach.

Przegrywa wszędzie tam, gdzie liczy się szybkie dostarczenie informacji. Dokumentacja, panel administracyjny, sklep z setką produktów, aplikacja używana codziennie przez tych samych ludzi. W tych miejscach kilkusekundowe ładowanie i stałe obciążenie karty graficznej są kosztem bez żadnego zwrotu.

Przegrywa również przy treści, która ma się indeksować. Scena trójwymiarowa nie niesie tekstu, więc dla wyszukiwarki jest pustym prostokątem, i to warto uwzględnić, planując, co znajdzie się na ekranie powitalnym.

Jest jeszcze jeden przypadek, w którym warto się wstrzymać: strona, na której użytkownik ma coś wypełnić albo kupić. Efekt przyciągający uwagę konkuruje wtedy z formularzem o tę samą uwagę, a przy zakupie każde rozproszenie działa przeciw Tobie. Trójwymiarowy model produktu obok formularza zamówienia bywa sensowny, ale trójwymiarowa animacja tła nad nim raczej nie.

Jak zmniejszyć scenę

Skoro rozmiar jest głównym kosztem, warto wiedzieć, co go napędza, bo intuicja myli się tu regularnie.

Największą pozycją są zwykle tekstury, a nie liczba obiektów. Obraz o rozdzielczości dwóch tysięcy pikselów użyty jako materiał na małym elemencie waży tyle samo co ten sam obraz na całym ekranie, a widać go w ułamku tej wielkości. Zmniejszenie tekstur do rozmiaru, w jakim faktycznie się pojawiają, zbija paczkę najszybciej.

Druga to modele wczytane z zewnątrz. Model pobrany z biblioteki bywa przygotowany pod renderowanie filmowe i ma dziesiątki tysięcy wielokątów, z których na ekranie widać kilka procent. Uproszczenie siatki przed wczytaniem to praca na kwadrans i zwykle kilkukrotna redukcja rozmiaru.

Trzecia to obiekty niewidoczne w kadrze. Scena budowana wizualnie gromadzi elementy, które w finalnym ujęciu są zasłonięte albo poza kadrem, a mimo to trafiają do eksportu.

Czwarta, najmniej oczywista, to liczba materiałów. Każdy odrębny materiał to osobne przetwarzanie przy renderowaniu, więc dziesięć obiektów dzielących jeden materiał kosztuje mniej niż dziesięć obiektów z dziesięcioma różnymi.

Sprawdź rozmiar wyeksportowanej sceny przed osadzeniem jej na stronie.

Code
Bash
curl -sI https://prod.spline.design/xxx/scene.splinecode |
  awk '/[Cc]ontent-[Ll]ength/ { printf "%.1f MB\n", $2/1048576 }'

To jedna liczba, którą warto znać przed decyzją, bo powyżej kilku megabajtów rozmowa przestaje dotyczyć estetyki, a zaczyna dotyczyć tego, czy ktokolwiek zobaczy stronę przed zamknięciem karty.

Praca z zespołem i przekazanie do wdrożenia

Narzędzie stoi na styku projektowania i programowania, więc warto ustalić, kto za co odpowiada, zanim scena trafi na stronę.

Osoba projektująca pracuje w edytorze i publikuje scenę pod adresem, który się nie zmienia. Osoba wdrażająca osadza ten adres raz i nie wraca do tego przy każdej poprawce, bo zmiany w edytorze pojawiają się na stronie po ponownym opublikowaniu.

To wygodne i niesie jedno ryzyko warte nazwania. Zmiana opublikowana bez uzgodnienia trafia od razu na produkcję, bez przeglądu i bez możliwości cofnięcia przez osobę odpowiedzialną za stronę. Przy poważnym wdrożeniu warto rozważyć serwowanie sceny z własnej infrastruktury, co odbiera wygodę natychmiastowej publikacji i daje w zamian kontrolę nad tym, co widzą użytkownicy. Warto tylko wiedzieć, gdzie producent to umieścił: eksport kodu i eksport do samodzielnego hostowania są wymienione dopiero na planie firmowym z wyceną indywidualną, więc na planach z cennika nie masz do tego drogi wprost.

Drugą rzeczą do ustalenia jest, kto sprawdza wydajność. Osoba projektująca widzi scenę w edytorze na mocnym sprzęcie i nie ma powodu podejrzewać problemu, a osoba wdrażająca dostaje gotowy adres i przyjmuje, że wszystko jest w porządku. Test na słabszym telefonie należy do kogoś i warto, żeby ten ktoś był wskazany, a nie domyślny.

Plany i co je dzieli

Cennik producenta rozkłada możliwości na cztery poziomy plus wycenę indywidualną, a stawka zależy od tego, czy płacisz z góry za rok, czy co miesiąc.

PlanRocznie, za miejsceMiesięcznie, za miejsceCo dochodzi
Free0 USD0 USDograniczona liczba plików, eksport na stronę ze znakiem wodnym
Hobby12 USD15 USDznak wodny znika z eksportów na stronę, pliki bez limitu, biblioteka materiałów
Pro20 USD25 USDeksport na Apple i Androida, znak wodny znika także z osadzeń, projekty i foldery bez limitu
Max120 USD150 USD10 000 kredytów miesięcznie, najwyższe limity funkcji AI, wsparcie priorytetowe
Enterprisewycena indywidualnawycena indywidualnaeksport kodu i samodzielne hostowanie, logowanie SSO, historia wersji pliku

Dwie rzeczy w tej tabeli łatwo przeoczyć. Pierwsza to znak wodny rozbity na dwie osobne pozycje: eksport sceny na stronę czyści już Hobby, natomiast osadzenie sceny bez znaku wymaga Pro. Druga to eksport na platformy mobilne, przypisywany zwykle „planom płatnym" w ogóle, a dostępny dopiero od Pro.

Osobną pozycją są kredyty na funkcje sztucznej inteligencji: 2 000 miesięcznie na Hobby, 3 000 na Pro, 10 000 na Max. Pulę podnosi się dokupując kolejne tysiące po 5 USD miesięcznie za tysiąc, i jest to stała pozycja doliczana do abonamentu, a nie jednorazowe doładowanie. Kredyty zużywa wyłącznie generowanie modeli, tekstur i stylów, więc przy scenie składanej ręcznie ta kolumna Cię nie dotyczy.

Spline kontra alternatywy

RozwiązanieMocna stronaSłabośćKiedy wybrać
SplinePraca wizualna, interakcje bez kodu, eksport do ReactaDuży rozmiar, obciążenie karty graficznejStrona produktu, portfolio, prezentacja
Biblioteki graficzne wprostPełna kontrola, optymalizacja rozmiaruWymaga wiedzy z grafiki trójwymiarowejRozbudowana scena albo gra
Wideo z animacjąPrzewidywalny rozmiar, działa wszędzieBrak interaktywnościEfekt bez reakcji na użytkownika
MotionLekkie, animuje istniejące elementyDwa wymiary, nie trójwymiarowa scenaAnimacja interfejsu, nie model

Drugi wiersz warto rozważyć przy scenie, która ma żyć długo. Kod pisany wprost daje kontrolę nad tym, co trafia do paczki, i pozwala zejść z rozmiarem znacznie niżej, kosztem czasu i wiedzy.

Trzeci wiersz bywa pomijany, a rozwiązuje zaskakująco wiele przypadków. Jeśli scena nie reaguje na użytkownika, tylko odtwarza animację, nagranie tej animacji waży mniej, działa na każdym urządzeniu i nie obciąża karty graficznej przez cały czas widoczności.

Typowe błędy

Pierwszy to osadzenie sceny bez zarezerwowania miejsca. Element pojawiający się po wczytaniu przesuwa układ, co pogarsza miary jakości strony i irytuje użytkownika.

Drugi to wczytywanie sceny przy wejściu na stronę zamiast wtedy, gdy zbliża się do widoku. Kilka megabajtów pobieranych od razu opóźnia wszystko inne.

Trzeci to przekonanie, że bez wyłączenia renderowania serwerowego aplikacja się wywali, i budowanie na tym całej konfiguracji. Komponent jest kliencki i po obiekty przeglądarki sięga dopiero po zamontowaniu. Prawdziwym niedopatrzeniem jest co innego: pominięcie wejścia @splinetool/react-spline/next, które daje rozmyty podgląd renderowany po stronie serwera, i niewstawienie w to miejsce własnego wypełniacza.

Czwarty to testowanie wyłącznie na komputerze deweloperskim. Scena płynna na mocnej maszynie potrafi zatrzymać przewijanie na starszym telefonie.

Piąty to pominięcie ustawienia ograniczającego ruch. U części osób animacje wywołują realny dyskomfort, a sprawdzenie tego to trzy linie kodu.

Szósty to umieszczenie sceny tam, gdzie użytkownik przychodzi po informację. Dokumentacja i panel administracyjny tracą na tym jednoznacznie, a koszt ładowania nie zwraca się w żaden sposób.

Siódmy to pozostawienie w scenie obiektów niewidocznych w finalnym kadrze. Trafiają do eksportu razem z resztą i podnoszą rozmiar, mimo że nikt ich nigdy nie zobaczy.

FAQ

Czy Spline jest darmowy?

Plan bezpłatny pozwala tworzyć sceny i eksportować je na stronę, przy czym eksport zawiera znak wodny producenta, a liczba plików jest ograniczona. Znak wodny z eksportów na stronę zdejmuje dopiero Hobby, czyli 12 USD miesięcznie za miejsce przy płatności rocznej albo 15 USD przy miesięcznej. Osadzenie sceny bez znaku oraz eksport na Apple i Androida wchodzą jeszcze wyżej, na Pro za 20 USD rocznie albo 25 USD miesięcznie.

Ile waży taka scena?

Zwykle kilka megabajtów, czyli tyle, co cała reszta typowej strony. To najważniejsza liczba przy tej decyzji, bo przy połączeniu mobilnym przekłada się wprost na sekundy oczekiwania, zanim cokolwiek się pojawi.

Czy działa na telefonach?

Działa, natomiast obciąża kartę graficzną przez cały czas widoczności, co przekłada się na zużycie baterii i płynność przewijania. Przy urządzeniach starszych warto przygotować wariant zastępczy w postaci statycznego obrazu.

Czy scena jest widoczna dla wyszukiwarek?

Nie w sensie treści. Scena nie niesie tekstu, więc dla wyszukiwarki jest pustym obszarem. Jeśli ekran powitalny ma się indeksować, tekst musi znaleźć się obok sceny, a nie w niej.

Kiedy lepiej użyć czegoś innego?

Gdy scena nie reaguje na użytkownika, bo wtedy nagranie tej samej animacji waży mniej i działa wszędzie. Oraz gdy strona służy szybkiemu dostarczeniu informacji, bo tam koszt ładowania i obciążenia nie zwraca się w żaden sposób.

Narzędzie i dokumentacja stoją na stronie projektu, a pakiet do Reacta znajdziesz w rejestrze npm.