sztuczne-rosliny.pl, sklep z najwyższej jakości roślinami sztucznymi
Rośliny sztuczne to produkt, który klient wybiera oczami, a kupuje na podstawie danych. Wygląda jak zakup estetyczny, a decyduje o nim wysokość, materiał, rodzaj podstawy i to, czy sztuka nadaje się do przestrzeni, w której stanie. Dlatego katalog takiego sklepu musi obsłużyć dwa zupełnie różne sposoby szukania: przeglądanie dla inspiracji i dobieranie po parametrach. To jest punkt, w którym zapadają wszystkie ważne decyzje techniczne.
sztuczne-rosliny.pl to sklep firmy zajmującej się importem i dystrybucją roślin sztucznych, działającej także jako hurtownia i dostawca aranżacji zieleni do przestrzeni komercyjnych, z ofertą obejmującą drzewa, trawy, bluszcze i donice oraz z wersją anglojęzyczną sklepu (źródło: sztuczne-rosliny.pl). Marka stawia na jakość produktu, a cena jest kryterium wtórnym. Partnerami są producenci i dostawcy z Azji oraz Europy. Wdrożenie ruszyło w 2019 roku i zajęło około sześciu tygodni. Warstwa techniczna to WordPress z rozbudowanym modelem produktu, Redis jako cache obiektowy, HTML5, CSS3 i SASS po stronie interfejsu, AJAX w wyszukiwaniu oraz CDN przed plikami graficznymi. Układ i rozmieszczenie elementów dostarczył klient.
Katalog, czyli dane produktowe zamiast opisów
Podstawą jest model produktu zbudowany na własnych typach treści i polach niestandardowych, a nie na opisie wpisanym do edytora. Wysokość, materiał, kolor, producent i rodzaj wykończenia są wartościami w bazie, a nie zdaniami w akapicie.
Różnica ujawnia się przy filtrach. Jeśli wysokość rośliny jest zapisana w opisie, filtr “od 120 do 180 cm” nie powstanie nigdy, bo nie ma czego porównywać. Można to obejść tagami w rodzaju “wysokie”, ale wtedy granica jest umowna, każdy redaktor rozumie ją inaczej, a klient dowiaduje się o rzeczywistym rozmiarze dopiero z karty produktu. W sklepie, w którym rośliny kupuje się do konkretnej przestrzeni, to jest różnica między wyborem trwającym minutę a wyborem, który kończy się zwrotem towaru.
Cena tego rozwiązania jest realna i warto ją nazwać. Wprowadzenie produktu zajmuje więcej czasu, bo formularz ma kilkanaście pól zamiast jednego okna edytora. Zbiór parametrów trzeba przemyśleć wcześniej, a jego późniejsza zmiana jest migracją danych, a nie poprawką w tekście. Ta inwestycja zwraca się przy każdej kolejnej setce produktów i przy każdej przebudowie wyglądu, bo dane w polach można wyświetlić w nowym układzie jednym szablonem, a dane w treści trzeba przepisywać ręcznie.
Osobnym tematem są zdjęcia. W tej branży fotografia jest opisem produktu, a nie ilustracją: klient ocenia po niej odcień liścia i sposób osadzenia w donicy. Dlatego galerie są rozbudowane, pliki duże i cały ciężar strony leży właśnie tutaj. Nie da się tego naprawić przez usunięcie zdjęć, więc trzeba to obsłużyć w warstwie dostarczania.
Wyszukiwanie i filtrowanie, czyli najdroższe zapytania w sklepie
Wyszukiwanie i filtrowanie działa asynchronicznie, więc zawężanie listy nie przeładowuje całej strony, a klient widzi skutek zmiany parametru od razu. To jest wygodne dla kupującego i kosztowne dla bazy danych, bo każde przesunięcie suwaka z wysokością jest osobnym zapytaniem.
Filtrowanie po wielu atrybutach naraz jest w WordPressie najdroższą operacją na liście produktów. Zapytanie łączy tabele relacji taksonomii i pól dodatkowych, a przy kilku aktywnych warunkach liczba łączeń rośnie szybciej niż liczba filtrów. Dlatego w takim sklepie wąskim gardłem nie jest strona główna, którą wszyscy testują, tylko widok kategorii z trzema zaznaczonymi filtrami, którego nie testuje nikt.
Praktyczne wnioski z tego wdrożenia są trzy. Po pierwsze, wynik filtrowania trzeba cache’ować osobno, bo ta sama kombinacja parametrów wraca częściej, niż się wydaje. Po drugie, liczniki przy filtrach, czyli informacja, ile produktów kryje się pod każdą opcją, są najdroższą częścią widoku i warto świadomie zdecydować, czy są potrzebne. Po trzecie, testy mają sens wyłącznie na kopii produkcji z pełnym katalogiem. Na pustej instalacji z dwudziestoma produktami każde zapytanie jest szybkie, bo baza mieści się w pamięci i nic nie musi być zoptymalizowane.
Dane od dostawców z dwóch rynków
Asortyment pochodzi od producentów z Azji i z Europy, a to oznacza, że dane produktowe przychodzą w różnych formatach, z różną częstotliwością i w różnej jakości. Jeden dostawca przysyła arkusz z pełną specyfikacją, inny plik, w którym wysokość bywa podana raz w centymetrach, raz w calach, a nazwa koloru istnieje w trzech wariantach zapisu.
Zadaniem warstwy synchronizacji jest sprowadzenie tego do jednego słownika, zanim dane trafią do katalogu. To jest nudna praca, która decyduje o wszystkim, co dzieje się dalej: filtr po materiale działa tylko wtedy, kiedy dziesięć wariantów zapisu tego samego tworzywa zostało wcześniej sprowadzonych do jednej wartości.
Druga rzecz to rozstrzygnięcie, kto jest właścicielem pola. Stany magazynowe i ceny pochodzą od dostawcy i mogą być nadpisywane przy każdej synchronizacji. Opis, zdjęcia i przypisanie do kategorii są pracą sklepu i nadpisane być nie mogą, bo import wykasowałby wtedy dorobek redakcji. Brak tej decyzji jest najczęstszą przyczyną awarii przy integracjach produktowych i objawia się zawsze tak samo: po nocnym imporcie połowa katalogu ma znowu opisy dostawcy.
Trzecia rzecz dotyczy produktów, które znikają z oferty dostawcy. Usunięcie ich z bazy zabija adres, który był w wynikach wyszukiwarki i w zakładkach klientów. Sensowniejsze jest oznaczenie jako niedostępne, pokazanie zamienników i utrzymanie strony przy życiu, bo w tej branży dobór alternatywy jest normalną częścią sprzedaży, a firma i tak sprowadza konkretne rośliny na zamówienie.
Płatności, zamówienia i to, czego nie wolno cache’ować
Sklep jest zintegrowany z bramkami płatności i obsługą zamówień. To jest ta część systemu, w której optymalizacja wydajności musi się zatrzymać, i warto rozumieć dlaczego.
Koszyk, podsumowanie zamówienia i strona po płatności są z definicji różne dla każdego użytkownika. Wrzucenie ich do pełnego cache strony kończy się najgorszą możliwą awarią w e-commerce, czyli pokazaniem jednemu klientowi koszyka innego. Dlatego te ścieżki są z cache wyłączone, a przyspieszenie osiąga się gdzie indziej: cache obiektowy w Redis skraca czas składania strony także tam, gdzie gotowej odpowiedzi nie da się zapisać.
Powrót z bramki płatności to osobny przypadek brzegowy, który trzeba przetestować na kopii produkcji. Klient może zamknąć przeglądarkę przed powrotem, wrócić dwa razy, albo trafić na powiadomienie serwera płatności szybsze niż jego własne przekierowanie. Status zamówienia musi wynikać z powiadomienia od operatora, a nie z tego, czy przeglądarka wróciła pod właściwy adres.
Wydajność, obrazy i ruch sezonowy
Warstwa wydajnościowa opiera się na cache obiektowym w Redis i na CDN przed plikami graficznymi, uzupełnionych o optymalizację obrazów i ograniczenie rozmiaru arkuszy stylów i skryptów. Podział pracy jest tu prosty: CDN zdejmuje z serwera transfer, którego ten nie powinien obsługiwać, a Redis skraca pracę potrzebną do złożenia strony, której nie da się oddać z gotowego cache.
Ruch w takim sklepie nie rozkłada się równo. Rośnie przed świętami i w okresach, w których firmy urządzają biura i lokale, a pojedyncze dni potrafią przynieść wielokrotność zwykłego obciążenia. Strojenie pod średnią miesięczną jest więc mało warte. Liczy się zachowanie serwisu w godzinie szczytu, a w tej godzinie decyduje nie szybkość kodu, tylko to, ile żądań w ogóle dociera do aplikacji.
Bezpieczeństwo w sklepie sprowadza się do rzeczy nudnych i konsekwentnych: aktualizacje rdzenia, motywu i wtyczek, przeglądanie logów, kontrola dostępów i testowanie zmian na kopii, zanim trafią na produkcję. W sklepie, w którym przez formularz płatności przechodzą prawdziwe transakcje, aktualizacja wykonana od razu na produkcji jest ryzykiem operacyjnym, a nie oszczędnością czasu.
Nasze działania
Po naszej stronie było wdrożenie sklepu na podstawie układu dostarczonego przez klienta: model produktu z polami parametrycznymi, widoki katalogu i karty produktu, wyszukiwanie z filtrowaniem, spięcie płatności i obsługi zamówień, warstwa cache oraz przygotowanie katalogu pod indeksowanie. Najważniejsze było to, żeby osoba zarządzająca ofertą mogła dodać nową roślinę bez pomocy programisty, a klient trafiał do właściwego produktu w kilku ruchach.
Warstwa wyszukiwarkowa w sklepie z parametrami ma jedną szczególną cechę. Strony kategorii i wyniki filtrowania potrafią wygenerować bardzo wiele adresów różniących się wyłącznie kolejnością parametrów, a to jest klasyczny sposób na rozmycie widoczności katalogu. Dlatego trzeba z góry ustalić, które kombinacje mają być stronami indeksowanymi, a które mają zostać narzędziem nawigacyjnym bez własnego adresu w wyszukiwarce. Nie mam pomiarów efektu tej pracy, którymi mógłbym się tu posłużyć, więc żadnych nie podaję.
Podsumowanie
sztuczne-rosliny.pl jest projektem, w którym o jakości sklepu zdecydował model danych, a nie warstwa graficzna. Parametry produktu zapisane jako pola, a nie jako zdania, dały filtrowanie, na którym oparta jest cała ścieżka zakupowa. Rozstrzygnięcie, które pola należą do dostawcy, a które do sklepu, pozwoliło synchronizować ofertę bez kasowania pracy redakcji. Wyłączenie ścieżki zakupowej z pełnego cache i przyspieszenie jej cache’em obiektowym pozwoliło pogodzić wydajność z poprawnością zamówień.
Na kolejne wdrożenie przenosi się warstwa techniczna i sposób pracy: WordPress z własnym modelem produktu, Redis, CDN, testowanie filtrów i płatności na kopii produkcji. Nie przenosi się słownik parametrów tego sklepu ani jego integracje z dostawcami, bo powstały pod konkretny asortyment i konkretne formaty danych. Kolejny projekt zaczyna się od analizy zakresu, a wycena idzie po niej.
Często zadawane pytania
Najważniejsze odpowiedzi, które pomagają wdrożyć temat w praktyce.
Jakiego zakresu dotyczył projekt sztuczne-rosliny.pl?
#Jak wyglądał przebieg prac przy sztuczne-rosliny.pl?
#Co było najtrudniejsze technicznie w sztuczne-rosliny.pl?
#Co z projektu sztuczne-rosliny.pl da się wykorzystać przy kolejnym wdrożeniu?
#Potrzebujesz FAQ dopasowanego do branży i rynku? Przygotujemy wersję pod Twoje cele biznesowe.
Porozmawiajmy