Budujesz aplikację w .NET i zastanawiasz się, czy wybrać klasyczne Razor Pages, widoki MVC, czy Blazora? Porównanie Blazor vs Razor szybko pokazuje, że nie są to technologie tego samego rodzaju. Wyjaśniam, czym naprawdę się różnią, jak działa renderowanie, kiedy lepiej postawić na prostotę Razor Pages, a kiedy na interaktywne komponenty Blazora.
Najważniejsze różnice widać w sposobie renderowania aplikacji
- Razor jest składnią łączącą HTML z C#, a nie osobnym frameworkiem.
- Razor Pages i widoki MVC generują HTML na serwerze po żądaniu przeglądarki.
- Blazor buduje aplikację z komponentów, które mogą działać interaktywnie na serwerze lub w przeglądarce.
- Razor Pages zwykle wygrywa przy prostych formularzach, stronach contentowych i aplikacjach opartych na żądaniach HTTP.
- Blazor lepiej pasuje do rozbudowanych paneli, dashboardów i interfejsów przypominających aplikacje desktopowe.
- Blazor Web App pozwala łączyć statyczne renderowanie z interaktywnością tylko tam, gdzie jest potrzebna.
Blazor i Razor rozwiązują różne problemy
Największe nieporozumienie polega na traktowaniu Razor jako konkurenta dla Blazora. Razor to składnia, która pozwala umieszczać kod C# w znacznikach HTML. Korzystają z niej między innymi widoki MVC, Razor Pages oraz komponenty Blazora.
Gdy widzę pytanie o różnicę między tymi technologiami, najpierw rozdzielam trzy pojęcia. Razor może oznaczać samą składnię, Razor Pages jako model budowania stron albo widoki MVC zapisane w plikach .cshtml. Blazor jest natomiast modelem komponentowym dla aplikacji webowych, zwykle opartym na plikach .razor.
Razor Pages i widoki MVC
W Razor Pages strona składa się zazwyczaj z pliku .cshtml oraz powiązanego pliku .cshtml.cs, czyli klasy PageModel. Kod serwerowy przygotowuje dane, a Razor generuje z nich HTML. Po wysłaniu odpowiedzi instancja strony nie musi zachowywać swojego stanu między żądaniami.
To podejście dobrze pasuje do witryn firmowych, blogów, paneli administracyjnych i formularzy. Każda akcja może być zwykłym żądaniem HTTP, co upraszcza obsługę, testowanie i wdrażanie aplikacji.
Blazor jako framework komponentów
Blazor dzieli interfejs na komponenty. Komponent może być stroną, formularzem, tabelą, modalem albo niewielkim fragmentem interfejsu wielokrotnie używanym w różnych miejscach. Może też przechowywać stan i reagować na zdarzenia użytkownika bez przeładowywania całej strony.
@code {
private int count;
private void Increase()
{
count++;
}
}W tym przykładzie nie wysyłamy formularza do serwera po każdym kliknięciu. Zmienia się stan komponentu, a Blazor aktualizuje potrzebny fragment interfejsu. To właśnie interaktywność, a nie sama obecność składni Razor, jest najważniejszą cechą tej technologii.
Największa różnica dotyczy sposobu renderowania
Razor Pages i klasyczne widoki MVC generują stronę na serwerze. Przeglądarka wysyła żądanie, serwer pobiera dane, wykonuje kod Razor i zwraca gotowy HTML. Przy kolejnej akcji, na przykład wysłaniu formularza, proces może rozpocząć się ponownie.
W Blazorze sytuacja zależy od wybranego modelu renderowania. W aktualnym Blazor Web App można użyć statycznego SSR, interaktywnego Blazor Server, WebAssembly albo trybu automatycznego. Dzięki temu nie trzeba wybierać jednego sposobu dla całej aplikacji.
| Kryterium | Razor Pages lub MVC | Blazor |
|---|---|---|
| Podstawowa jednostka | Strona lub widok | Komponent |
| Typowy plik | .cshtml |
.razor |
| Renderowanie | HTML generowany na serwerze | SSR, Server, WebAssembly lub tryb mieszany |
| Obsługa kliknięcia | Najczęściej nowe żądanie HTTP | Zdarzenie obsługiwane przez komponent |
| Stan interfejsu | Zwykle odtwarzany przy kolejnym żądaniu | Może być utrzymywany w komponencie |
| JavaScript | Często używany do interakcji w przeglądarce | Może być ograniczony, ale nadal dostępny przez JS interop |
W Razor Pages każda linia kodu ostatecznie emituje tekst HTML. W Blazorze komponent tworzy strukturę renderowania, a framework może obliczyć różnicę między poprzednim i nowym stanem interfejsu. Nie każda zmiana wymaga odświeżenia całego dokumentu, co robi dużą różnicę w złożonych widokach.
Trzeba jednak uważać na uproszczenie, że Blazor zawsze działa jak aplikacja SPA. Współczesny Blazor potrafi rozpocząć od statycznego HTML, a interaktywność włączyć tylko dla wybranych komponentów. To często rozsądniejszy kompromis niż budowanie całej aplikacji jako jednego klienta WebAssembly.
Kiedy lepiej wybrać Razor Pages lub MVC
Razor Pages wybrałbym wtedy, gdy aplikacja jest przede wszystkim zbiorem stron i formularzy, a interakcje nie wymagają rozbudowanego lokalnego stanu. Dla wielu paneli administracyjnych, serwisów informacyjnych i aplikacji biznesowych to nadal najprostsza droga do działającego rozwiązania.
- Strony marketingowe i serwisy z dużą ilością treści.
- Blogi, dokumentacje i portale, w których ważne są szybkie odpowiedzi HTML.
- Formularze rejestracji, edycji danych i obsługi procesów biznesowych.
- Proste panele administracyjne z niewielką liczbą elementów interaktywnych.
- Aplikacje, w których zespół dobrze zna MVC i nie chce wprowadzać kolejnego modelu komponentów.
Razor Pages ma też praktyczną zaletę po stronie infrastruktury. Nie trzeba utrzymywać stałego obwodu interaktywnego dla każdego użytkownika, a obsługa żądań jest dobrze znana z klasycznego ASP.NET Core. Przy dużej liczbie krótkich wizyt może to ułatwić skalowanie.
Nie oznacza to, że Razor Pages jest zawsze szybsze. Jeśli strona wykonuje wiele pełnych przeładowań i użytkownik często przechodzi między formularzami, odczuwalna płynność może być gorsza niż w aplikacji komponentowej. W prostym projekcie ten koszt bywa jednak mniejszy niż koszt dodatkowej złożoności Blazora.
Kiedy Blazor daje wyraźną przewagę
Blazor ma sens, gdy interfejs zachowuje się bardziej jak aplikacja niż dokument. Mam na myśli dashboardy, konfiguratory, systemy obsługi zgłoszeń, edytory danych i ekrany, na których wiele elementów reaguje na siebie nawzajem.
Interfejs z dużą liczbą zdarzeń
Jeżeli użytkownik filtruje tabelę, wybiera kilka opcji, otwiera modal i od razu widzi przeliczoną wartość, model komponentowy jest naturalny. Stan znajduje się bliżej interfejsu, a logika reakcji nie musi być rozrzucona między kontrolerem, formularzem, JavaScriptem i osobnymi endpointami.
Współdzielenie komponentów
W Blazorze można budować własne komponenty z parametrami, zdarzeniami i cyklem życia. Raz przygotowana tabela, walidator czy selektor może być używana w wielu ekranach. To szczególnie dobrze działa w systemach wewnętrznych, gdzie wygląd i zachowanie interfejsu muszą być spójne.
Wspólny kod C#
Jeżeli zespół pracuje głównie w C#, Blazor pozwala ograniczyć ilość kodu JavaScript potrzebnego do typowych interakcji. Nie usuwa to JavaScriptu całkowicie, bo biblioteki przeglądarkowe nadal mogą być przydatne, ale logika aplikacji może pozostać w jednym ekosystemie.
Blazor nie jest jednak magicznym sposobem na zamianę każdej strony w szybszą aplikację. Duży komponent z nieprzemyślanym stanem może być trudniejszy w utrzymaniu niż kilka prostych stron Razor Pages. Ja zwracam szczególną uwagę na granice komponentów, bo to one często decydują o jakości całego projektu.
Wydajność, SEO i koszty utrzymania mają różne profile
Nie istnieje jedna uniwersalna odpowiedź na pytanie, które rozwiązanie jest szybsze. Wynik zależy od rozmiaru aplikacji, sposobu renderowania, zapytań do bazy, sieci i liczby równoczesnych użytkowników. Można jednak wskazać typowe kompromisy.
Razor Pages i szybki pierwszy widok
W Razor Pages serwer zwraca gotowy HTML, więc przeglądarka może szybko pokazać zawartość bez pobierania pełnego runtime aplikacji. To korzystne dla stron publicznych, SEO i urządzeń o słabszych parametrach. Pierwsze renderowanie jest zwykle łatwe do przewidzenia.
Blazor Server i połączenie z serwerem
W trybie interaktywnym Server kod komponentu działa na serwerze, a zdarzenia i aktualizacje interfejsu przechodzą przez połączenie SignalR. Każda aktywna sesja ma utrzymywany stan po stronie serwera, dlatego trzeba planować pamięć, limity połączeń i zachowanie aplikacji po utracie sieci.
To rozwiązanie może dawać bardzo szybki start, ale opóźnienie sieci wpływa na reakcję interfejsu. Dobrze działa w aplikacjach używanych przez pracowników w stabilnej sieci, natomiast w aplikacji publicznej z użytkownikami mobilnymi trzeba dokładnie przetestować zachowanie przy słabym połączeniu.
Blazor WebAssembly i zasoby klienta
W WebAssembly część aplikacji działa w przeglądarce. Użytkownik musi pobrać runtime, biblioteki i kod aplikacji, więc pierwszy start może być cięższy niż w Razor Pages. Później wiele operacji może odbywać się lokalnie, bez stałej komunikacji z serwerem.
Nie podaję jednej liczby jako typowego rozmiaru aplikacji WebAssembly, bo zależy on od wersji .NET, bibliotek, kompresji i trimming’u. Rozsądna decyzja powinna wynikać z pomiaru konkretnego projektu, a nie z porównania przypadkowych przykładów.
Przeczytaj również: Jak sprawdzać, czy plik istnieje w Node.js?
SEO i bezpieczeństwo
Razor Pages od początku dostarcza wyszukiwarkom gotową treść HTML. Blazor Web App z renderowaniem po stronie serwera może osiągnąć podobny efekt, ale aplikacja oparta wyłącznie na kliencie WebAssembly wymaga większej ostrożności przy indeksowaniu i pierwszym renderowaniu.
W Blazor WebAssembly kod klienta należy traktować jako publiczny. Sekrety, klucze i reguły autoryzacji nie mogą trafić do przeglądarki. Niezależnie od wybranego modelu wrażliwa logika powinna pozostać na serwerze.
Najrozsądniejsza decyzja często łączy oba podejścia
W nowych projektach nie zakładałbym automatycznie, że trzeba wybrać wyłącznie Blazora albo wyłącznie Razor Pages. Blazor Web App pozwala renderować część aplikacji statycznie, a interaktywność włączać tylko dla tych komponentów, które naprawdę jej potrzebują.
Przykładowo strona produktu może zostać wyrenderowana jako SSR, formularz konfiguracji może działać w trybie interaktywnym Server, a rozbudowany edytor może korzystać z WebAssembly. Tryb renderowania warto dobierać per komponent, a nie traktować go jak decyzję podejmowaną raz dla całej aplikacji.
Przy migracji z Razor Pages dobrze zacząć od jednego ekranu o wysokiej interaktywności. Jeżeli komponent poprawia czytelność kodu i doświadczenie użytkownika, można przenosić kolejne fragmenty. Migracja wszystkiego naraz zwykle utrudnia ocenę, czy zysk rzeczywiście rekompensuje dodatkową złożoność.
- Spisz ekrany, które wymagają częstych aktualizacji bez przeładowania strony.
- Zostaw proste strony i formularze w Razor Pages, jeśli działają dobrze.
- Wydziel komponenty Blazora tam, gdzie występuje dużo lokalnego stanu.
- Wybierz Server, WebAssembly lub SSR na podstawie sieci, SEO i obciążenia.
- Zmierz czas pierwszego renderowania, opóźnienia interakcji i zużycie pamięci.
Takie podejście ogranicza ryzyko architektoniczne. Zespół nie musi prowadzić wojny technologicznej, bo oba modele mogą współpracować w jednej aplikacji ASP.NET Core.
Moja praktyczna reguła wyboru między Blazorem a Razor
Gdy tworzę stronę opartą głównie na treści, formularzach i klasycznym przepływie żądań, zaczynam od Razor Pages. Daje prosty model mentalny, dobrze współpracuje z SEO i nie wymaga utrzymywania interaktywnego stanu dla każdego otwartego ekranu.
Gdy interfejs ma zachowywać się jak rozbudowane narzędzie, wybieram Blazora. Szczególnie dobrze sprawdza się tam, gdzie użytkownik stale filtruje dane, zmienia ustawienia, pracuje na wielu kontrolkach i oczekuje płynnej reakcji bez pełnych przeładowań.
Najważniejsze jest to, by nie mylić składni z architekturą. Razor może być wspólnym językiem obu podejść, ale Razor Pages i Blazor organizują aplikację w zupełnie inny sposób. Jeśli zaczniesz decyzję od potrzeb interfejsu, modelu ruchu i warunków wdrożenia, wybór stanie się znacznie prostszy.
