Dlaczego zwracanie wygenerowanego HTML zamiast JSON jest złą praktyką? Albo to jest?


301

Ładowanie treści HTML z niestandardowych adresów URL / usług sieciowych jest dość łatwe przy użyciu JQuery lub innej podobnej struktury. Stosowałem to podejście wiele razy i do tej pory uważałem, że wydajność jest zadowalająca.

Ale wszystkie książki, wszyscy eksperci próbują zachęcić mnie do używania JSON zamiast generowanego HTML. Jak to jest znacznie lepsze niż HTML?

Czy to jest znacznie szybsze?
Czy ma znacznie mniejsze obciążenie serwera?

Z drugiej strony mam kilka powodów, dla których warto używać wygenerowanego HTML.

  1. Jest to prosty znacznik i często tak samo kompaktowy, a nawet bardziej kompaktowy niż JSON.
  2. Jest mniej podatny na błędy, ponieważ wszystko, co dostajesz, to znaczniki i brak kodu.
  3. W większości przypadków programowanie będzie szybsze, ponieważ nie będziesz musiał pisać kodu osobno dla klienta.

Po której jesteś stronie i dlaczego?


warto zauważyć, że X w AJAX to XML, a HTML w pewnym momencie miał być XML. Pomysł polegał na tym, że HTML był danymi czytelnymi dla ludzi i maszyn (jak JSON), a CSS przeprowadzałoby prezentację. W tych warunkach wysyłanie kodu HTML w żądaniu AJAX nie naruszałoby „rozdzielenia obaw”
code_monk

Odpowiedzi:


255

Jestem trochę po obu stronach, właściwie:

  • Gdy po stronie javascript potrzebuję danych , korzystam z JSON
  • Kiedy po stronie javascript potrzebuję prezentacji, na której nie będę wykonywać żadnych obliczeń, zazwyczaj używam HTML

Główną zaletą używania HTML jest to, że chcesz zastąpić całą część strony tym, co pochodzi z żądania Ajax:

  • Ponowne zbudowanie części strony w JS jest (dość) trudne
  • Prawdopodobnie masz już silnik szablonów po stronie serwera, który został użyty do wygenerowania strony w pierwszej kolejności ... Dlaczego nie użyć go ponownie?

Zasadniczo nie biorę pod uwagę strony „wydajnościowej”, przynajmniej na serwerze:

  • Na serwerze generowanie części HTML lub JSON prawdopodobnie nie zrobi tak dużej różnicy
  • O wielkości rzeczy, które przechodzą przez sieć: cóż, prawdopodobnie nie używasz setek KB danych / html ... Używanie gzip do wszystkiego, co przesyłasz, robi największą różnicę (nie wybierając między HTML i JSON)
  • Jedną z rzeczy, które można wziąć pod uwagę, są zasoby, których potrzebujesz na kliencie, aby odtworzyć HTML (lub strukturę DOM) z danych JSON ... porównaj to z wypychaniem części HTML na stronę; -)

Wreszcie jedna rzecz, która na pewno się liczy:

  • Jak długo zajmie Ci opracowanie nowego systemu, który będzie wysyłać dane w postaci kodu JSON + JS wymagany do wstrzyknięcia go jako HTML na stronę?
  • Ile czasu zajmie samo zwrócenie HTML? A jak długo można ponownie wykorzystać część istniejącego kodu po stronie serwera?


I aby odpowiedzieć na inną odpowiedź: jeśli musisz zaktualizować więcej niż jedną część strony, nadal istnieje rozwiązanie / włamanie do wysłania wszystkich tych części w jednym dużym ciągu, który grupuje kilka części HTML, i wyodrębnij odpowiednie części w JS.

Na przykład możesz zwrócić ciąg znaków, który wygląda następująco:

<!-- MARKER_BEGIN_PART1 -->
here goes the html
code for part 1
<!-- MARKER_END_PART1 -->
<!-- MARKER_BEGIN_PART2 -->
here goes the html
code for part 2
<!-- MARKER_END_PART2 -->
<!-- MARKER_BEGIN_PART3 -->
here goes the json data
that will be used to build part 3
from the JS code
<!-- MARKER_END_PART3 -->

Nie wygląda to zbyt dobrze, ale jest zdecydowanie przydatne (korzystałem z niego kilka razy, głównie wtedy, gdy dane HTML były zbyt duże, aby można je było zamknąć w JSON) : wysyłasz HTML dla części strony, które potrzebujesz prezentacji, a wysyłasz JSON w sytuacji, w której potrzebujesz danych ...

... I aby je wyodrębnić, metoda JS podciągnie się, jak sądzę ;-)


6
Wszystkie dane są ostatecznie prezentacją.
Cyril Gupta,

47
@Cyril: Huh? Myślę, że próbujesz powiedzieć, że dane, aby były użyteczne, muszą zostać wykorzystane, a zatem przedstawione gdzieś w jakiejś formie, i zgadzam się. Ale stwierdzenie, że dane prezentacją, wydaje się co najmniej błędne.
Vinko Vrsalovic

10
Cześć Vinko, zauważysz „ostatecznie”? Mam na myśli dokładnie to, co masz na myśli. Po prostu próbuję dostać się do księgi cytatów tutaj. Ha ha!
Cyril Gupta,

37
Podstawowe pytanie brzmi: czy jesteś absolutnie, pozytywnie, ostatecznie pewien, że nie będziesz używać tych danych do niczego poza HTML. Ponieważ po spakowaniu do HTML dane będą prawie niemożliwe do odzyskania. Dzięki JSON Twój backend może współpracować z XML, SVG, silnikami baz danych, interfejsem API dla wielu witryn oraz tysiącem innych interfejsów i systemów, które mogą akceptować JSON. Dzięki HTML będziesz mógł używać go tylko w HTML.
SF.

3
@SF: Zwracając HTML z serwera, upewniam się, że kod generujący HTML został podzielony od kodu, który uzyskuje dostęp do bazy danych. W ten sposób mogę również łatwo dodać formularz JSON.
Casebash

114

Zgadzam się głównie z przedstawionymi tutaj opiniami. Chciałem tylko podsumować je jako:

  • Wysyłanie HTML jest złą praktyką, jeśli kończysz parsowanie go po stronie klienta, aby wykonać kilka obliczeń.

  • Wysyłanie JSON jest złą praktyką, jeśli wszystko, co skończysz, to włączenie go do drzewa DOM strony.


3
co jeśli musisz wykonać pewne obliczenia, a także uwzględnić je w DOM strony?
Enrique,

Zastanawiam się, jak długo powyższe stwierdzenie będzie powiązane z prawdomównością. Jeśli dodasz do równania „ okres półtrwania wiedzy ”?
Val

czy jest możliwe zwrócenie HTML, który ma tagi <script>, a następnie wykonuje go po stronie klienta, gdy strona jest ładowana?
nish1013

To. Również jeśli zwracasz dane, które muszą być w jakiś sposób płynne w prezentacji, np. Jeśli masz tabelę HTML z kolumnami, które chciałbyś móc posortować. Niezależnie od tego, czy sprawiłeś, że można je teraz sortować, czy nie, możesz chcieć później, więc w takim przypadku sprawdzenie przyszłości jest warte dodatkowego wysiłku, jakim jest przejście drogą JSON.
trpt4him

Dodałbym również, że jeśli prosisz o przesłanie adresów URL obrazów za pomocą JSON tylko po to, aby spróbować je wyrenderować na stronie, o wiele bardziej wydajne jest umieszczanie ich w HTML od samego początku, aby obrazy mogły rozpocząć ładowanie wcześniej (zanim wróci twoje ajax) .
FailedUnitTest

30

Dobrze,

Jestem jedną z tych rzadkich osób, które lubią rozdzielać rzeczy w ten sposób: - Serwer jest odpowiedzialny za dostarczanie danych (model); - Klient jest odpowiedzialny za wyświetlanie (wyświetlanie) i manipulowanie danymi (model);

Tak więc serwer powinien skupić się na dostarczeniu modelu (w tym przypadku JSON jest lepszy). W ten sposób otrzymujesz elastyczne podejście. Jeśli chcesz zmienić widok swojego modelu, serwer nadal wysyła te same dane i po prostu zmienia klienta, komponenty javascript, które zmieniają te dane w widok. Wyobraź sobie, że masz serwer dostarczający dane do urządzeń mobilnych, a także do aplikacji komputerowych.

Takie podejście zwiększa produktywność, ponieważ kod serwera i klienta można budować w tym samym czasie, nigdy nie tracąc uwagi, co dzieje się, gdy ciągle przechodzisz z js na PHP / JAVA / itp.

Ogólnie myślę, że większość ludzi woli robić tyle, ile to możliwe po stronie serwera, ponieważ nie opanowali js, więc starają się tego unikać w jak największym stopniu.

Zasadniczo mam takie same zdanie jak ci ludzie, którzy pracują nad Angularem. Moim zdaniem taka jest przyszłość aplikacji internetowych.


Tak, całkowicie się z tobą zgadzam. Jednak robiąc tyle samo po stronie serwera, gdy chodzi o wrażliwe informacje, uważam, że najlepiej. Jeśli potrzebujesz, aby klient reagował inaczej w zależności od wyniku, użyłbym json, inaczej użyłbym HTML.
Fi Horan,

9

Mam coś ciekawego, co mogłem dodać. Opracowałem aplikację, która tylko raz załadowała pełny widok. Od tego momentu komunikował się z serwerem tylko z ajaxem. Wystarczyło tylko załadować jedną stronę (mój powód jest tutaj nieistotny). Interesująca część polega na tym, że miałem specjalną potrzebę zwrócenia niektórych danych do obsługi w javascript ORAZ częściowego widoku do wyświetlenia. Mógłbym podzielić to na dwa wezwania na dwie osobne metody działania, ale zdecydowałem się na coś bardziej zabawnego.

Sprawdź to:

public JsonResult MyJsonObject(string someData)
{
     return Json(new { SomeData = someData, PartialView = RenderPartialViewToString("JsonPartialView", null) }, JsonRequestBehavior.AllowGet);
}

Co możesz zapytać o RenderPartialViewToString ()? To właśnie ten mały samorodek chłodu tutaj:

protected string RenderPartialViewToString(string viewName, object model)
{
     ViewData.Model = model;

     using (StringWriter sw = new StringWriter())
     {
          ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(ControllerContext, viewName);
          ViewContext viewContext = new ViewContext(ControllerContext, viewResult.View, ViewData, TempData, sw);
          viewResult.View.Render(viewContext, sw);

          return sw.GetStringBuilder().ToString();
     }
}

Nie przeprowadziłem na tym etapie żadnych testów wydajności, więc nie jestem pewien, czy wiąże się to z większym lub mniejszym obciążeniem, niż wywołanie jednej metody akcji dla JsonResult i jednej dla ParticalViewResult, ale nadal uważałem, że to całkiem fajne. Po prostu serializuje częściowy widok na ciąg i wysyła go wraz z Jsonem jako jeden z jego parametrów. Następnie używam JQuery, aby pobrać ten parametr i uderzyć go w odpowiedni węzeł DOM :)

Daj mi znać, co myślisz o mojej hybrydzie!


1
Wysłanie renderowanego widoku i danych w jednym żądaniu wydaje się trochę zbędne. Żartowałem, gdybyś miał możliwość renderowania widoku po stronie klienta, jeszcze lepiej byłoby wysłać szablon widoku i dane jako osobne żądania. Wymagało to dodatkowego żądania, ale tylko raz, ponieważ żądanie szablonu będzie buforowane dla kolejnych żądań. Najlepiej byłoby użyć kombinacji renderowania widoku klienta i serwera, aby można było budować strony na serwerze i częściowe strony w przeglądarce, ale jeśli wdrożono tylko renderowanie widoku po stronie serwera, nie jest to złe podejście.
Evan Plaice

8

Jeśli odpowiedź nie wymaga dalszego przetwarzania po stronie klienta, HTML jest moim zdaniem w porządku. Wysłanie JSON zmusi cię tylko do przetwarzania po stronie klienta.

Z drugiej strony używam JSON, gdy nie chcę używać wszystkich danych odpowiedzi na raz. Na przykład mam serię trzech łańcuchowych selekcji, w których wybrana wartość jednej określa, które wartości zostaną użyte do zapełnienia drugiej i tak dalej.


7

IMV, chodzi przede wszystkim o oddzielenie danych od prezentacji danych, ale jestem z Pascalem, niekoniecznie wynika z tego, że ta separacja może odbywać się tylko na granicy klient / serwer. Jeśli masz już tę separację (na serwerze) i po prostu chcesz coś pokazać klientowi, to czy odeślesz JSON i przetworzysz go na kliencie, czy po prostu odeślesz HTML, zależy całkowicie od twoich potrzeb. Stwierdzenie, że „nie masz racji” w odesłaniu HTML w ogólnym przypadku, jest po prostu zbyt ogólne, aby oświadczenie IMV.


6

JSON jest bardzo uniwersalnym i lekkim formatem. Odkryłem jego piękno, gdy zacząłem używać go jako danych analizatora składni szablonów po stronie klienta. Pozwól mi wyjaśnić, podczas gdy wcześniej korzystałem ze smarty i widoków po stronie serwera (generując duże obciążenie serwera), teraz używam niestandardowych funkcji jquery i wszystkie dane są renderowane po stronie klienta, używając przeglądarki klienta jako parsera szablonów. oszczędza zasoby serwerowe, a z drugiej strony przeglądarki poprawiają swoje silniki JS każdego dnia. Szybkość parsowania klienta nie jest w tej chwili ważnym problemem, co więcej, obiekty JSON są zwykle bardzo małe, więc nie zużywają dużo zasobów po stronie klienta. Wolę mieć wolną stronę dla niektórych użytkowników z wolną przeglądarką niż wolną stronę dla wszystkich z powodu bardzo obciążonego serwera.

Z drugiej strony, wysyłając czyste dane z serwera, wyodrębniasz je z prezentacji, więc jeśli jutro chcesz je zmienić lub zintegrować z inną usługą, możesz to zrobić o wiele łatwiej.

Tylko moje 2 centy.


A jak zapewnić sobie czytelną stronę, gdy javascript jest wyłączony?
Vinko Vrsalovic

8
jeśli JS jest wyłączony, nie będzie można również ładować HTML. JS jest wyłączone na 2,3% użytkowników zgodnie z moimi statystykami Google Analytics. Najlepszym sposobem zejścia na dół jest zadowolenie wszystkich.
Mike

4
Zgadzam się w 100% z Mikiem. Próba zadowolenia wszystkich jest niemożliwa i tylko cię skrzywdzi. Jeśli użytkownicy wyłączają JS, muszą być przyzwyczajeni do wielu witryn, które do tej pory nie działały.
Chev

1
Jak uzyskać statystyki JavaScript w Analytics, skoro Analytics używa JavaScript do śledzenia danych?
Nick

@Nick Dobre pytanie, ale znalazłem to: stackoverflow.com/questions/15265883/...
Renan Cavalieri

6

Jeśli chcesz mieć czystego oddzielonego klienta, co moim zdaniem jest najlepszą praktyką, warto mieć 100% DOM utworzony przez javascript. Jeśli zbudujesz klienta opartego na MVC, który ma pełną wiedzę na temat tworzenia interfejsu użytkownika, wówczas użytkownicy pobiorą jeden plik javascript za jednym razem i będą buforowani na kliencie. Wszystkie żądania po tym początkowym załadowaniu są oparte na Ajax i zwracają tylko dane. To podejście jest najczystsze, jakie znalazłem, i zapewnia czyste niezależne enkapsulowanie prezentacji.

Strona serwera koncentruje się na dostarczaniu danych.

Więc jutro, gdy produkt poprosi Cię o całkowitą zmianę projektu strony, zmienisz tylko źródłowy JS, który tworzy DOM, ale prawdopodobnie ponownie wykorzystasz już istniejące programy obsługi zdarzeń, a serwer jest nieświadomy, ponieważ jest w 100% oddzielony od prezentacji


1
Zgadzam się, możesz także ponownie użyć JSON dla swojej aplikacji mobilnej.
Alex Shilman

To powinna być zaakceptowana odpowiedź - pierwsze 6-7 słów zwięźle odpowiada na pytanie.
nicholaswmin

Zgodzić się. Zaletą zwracanych danych (JSON) nad prezentacją (html) jest to, że masz teraz „darmowy” internetowy interfejs API, który może być ponownie użyty dla innych klientów, czy to na urządzeniach mobilnych, czy też zupełnie innej aplikacji, która jest zainteresowana niektórymi danymi z tej aplikacji itp. Z mojego doświadczenia wynika, że ​​używanie prostego frameworka po stronie serwera, który zajmuje się wyłącznie danymi, a nie prezentacją, często prowadzi do dobrych i prostych rezultatów. Nowoczesna przeglądarka i procesory są tak szybkie, że tylko w szczególnych przypadkach renderowanie będzie wąskim gardłem. Największym wąskim gardłem jest przede wszystkim sama sieć i wywołanie bazy danych.
beginner_

4

W zależności od interfejsu użytkownika może być konieczne zaktualizowanie dwóch (lub więcej) różnych elementów w DOM. Jeśli Twoja odpowiedź jest w języku HTML, czy zamierzasz to przeanalizować, aby dowiedzieć się, co się dzieje? Lub możesz po prostu użyć skrótu JSON.

Możesz nawet połączyć to, zwrócić JSON z danymi html :)

{ 'dom_ele_1' : '<p>My HTML part 1</p>', 'dome_ele_2' : '<div>Your payment has been received</div>' }

Wysyłanie JSON to zła praktyka, jeśli wszystko, co skończysz, to włączenie go do drzewa DOM strony ... i łącząc JSON z HTML, używasz tej złej
praktyki

2

HTML zawiera wiele zbędnych i nie wyświetlanych danych, tj. Tagi, arkusze stylów itp. Tak więc rozmiar HTML w porównaniu do danych JSON będzie większy, co prowadzi do dłuższego pobierania i renderowania, a także spowoduje, że przeglądarka będzie zajęta renderowaniem nowych danych.


1

Wysyłanie JSON-a odbywa się zwykle, gdy widżet javascript żąda informacji z serwera, takich jak lista lub widok drzewa lub autouzupełnianie. To wtedy wysłałbym JSON, ponieważ to dane będą parsowane i używane na surowo. Jeśli jednak po prostu pokażesz HTML, to jest o wiele mniej pracy, aby wygenerować go po stronie serwera i po prostu pokazać go w przeglądarce. Przeglądarki są zoptymalizowane do wstawiania HTML bezpośrednio do domeny za pomocą innerHTML = "", więc nie możesz się z tym pomylić.


FWIW, innerHTMLjest historycznie znacznie wolniejszy niż fragment dokumentu: coderwall.com/p/o9ws2g/… .
Nate Whittaker

0

Myślę, że to zależy od struktury projektu, po prostu bardziej seksowne jest używanie JSON niż HTML, ale pytanie brzmi, jak sobie z tym poradzić, aby można go było łatwo utrzymać.

Załóżmy na przykład, że mam stronę z listą, która wykorzystuje ten sam styl HTML / styl całej witryny, napisałbym funkcję globalną, aby sformatować te części HTML, a wszystko, co muszę zrobić, to przekazać obiekt JSON do funkcji.


0

Odpowiedź HTML jest wystarczająca w większości przypadków, chyba że musisz wykonać pewne obliczenia po stronie klienta.


0

Zależy od okoliczności.

Czasami konieczne jest unikanie JSON. Gdy na przykład nasi programiści mają problemy z programowaniem w js.

Moje doświadczenie mówi mi, że: lepiej korzystać z usługi ajax niż wbudowanego JSON.

Wcześniej czy później js staje się problemem

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.