¿Por qué es una mala práctica devolver HTML generado en lugar de JSON? ¿O es eso?

301

Es bastante fácil cargar contenido HTML desde sus URL / servicios web personalizados utilizando JQuery o cualquier otro marco similar. He usado este enfoque muchas veces y hasta ahora y he encontrado el rendimiento satisfactorio.

Pero todos los libros, todos los expertos están tratando de hacerme usar JSON en lugar de HTML generado. ¿Cómo es mucho más superior que HTML?

¿Es mucho más rápido?
¿Tiene una carga mucho menor en el servidor?

Por otro lado, tengo algunas razones para usar HTML generado.

  1. Es un marcado simple y, a menudo, tan compacto o realmente más compacto que JSON.
  2. Es menos propenso a errores porque todo lo que obtienes es marcado, y no hay código.
  3. Será más rápido programar en la mayoría de los casos porque no tendrá que escribir código por separado para el cliente final.

¿De qué lado estás y por qué?

Cyril Gupta
fuente
Vale la pena señalar que la X en AJAX es XML, y se suponía que HTML en un momento era XML. La idea era que HTML era información legible por humanos y máquinas (como JSON), y CSS haría la presentación. En esas condiciones, no violaría "separación de intereses" para enviar HTML en una petición AJAX
code_monk

Respuestas:

255

Estoy un poco en ambos lados, en realidad:

  • Cuando lo que necesito en el lado de JavaScript son datos , uso JSON
  • Cuando lo que necesito en el lado de JavaScript es una presentación en la que no haré ningún cálculo, generalmente uso HTML

La principal ventaja de usar HTML es cuando desea reemplazar una parte completa de su página con lo que devuelve la solicitud de Ajax:

  • Reconstruir una parte de la página en JS es (bastante) difícil
  • Probablemente ya tenga un motor de plantillas en el lado del servidor, que se utilizó para generar la página en primer lugar ... ¿Por qué no reutilizarlo?

Por lo general, no tomo en cuenta el lado del "rendimiento" de las cosas, al menos en el servidor:

  • En el servidor, generar una porción de HTML o algo de JSON probablemente no hará una gran diferencia
  • Sobre el tamaño de las cosas que pasan por la red: bueno, probablemente no uses cientos de KB de datos / html ... Usar gzip en lo que sea que estés transfiriendo es lo que hará la mayor diferencia (no elegir entre HTML y JSON)
  • Sin embargo, una cosa que podría tenerse en cuenta es qué recursos necesitará en el cliente para recrear el HTML (o la estructura DOM) a partir de los datos JSON ... compárelo con insertar una parte de HTML en la página; -)

Finalmente, una cosa que definitivamente importa:

  • ¿Cuánto tiempo le llevará desarrollar un nuevo sistema que envíe datos como código JSON + que JS requirió para inyectarlo como HTML en la página?
  • ¿Cuánto tiempo llevará devolver HTML? ¿Y cuánto tiempo si puede reutilizar parte de su código del lado del servidor ya existente?


Y para responder a otra respuesta: si necesita actualizar más de una parte de la página, todavía existe la solución / truco de enviar todas esas partes dentro de una gran cadena que agrupa varias partes HTML y extraer las partes relevantes en JS.

Por ejemplo, podría devolver una cadena que se vea así:

<!-- 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 -->

Eso no se ve realmente bien, pero es definitivamente útil (lo he usado un par de veces, principalmente cuando los datos HTML eran demasiado grandes para encapsularlos en JSON) : está enviando HTML para las partes de la página que necesita presentación, y está enviando JSON para la situación en la que necesita datos ...

... Y para extraerlos, supongo que el método de subcadena JS hará el truco ;-)

Pascal MARTIN
fuente
66
Todos los datos son finalmente presentación.
Cyril Gupta
47
@ Cirilo: ¿Eh? Creo que está tratando de decir que los datos, para ser útiles, deben usarse y, por lo tanto, presentarse en algún lugar de alguna forma, y ​​estoy de acuerdo. Pero decir que los datos son presentación parece, al menos, equivocado.
Vinko Vrsalovic
10
Hola Vinko, ¿te das cuenta del 'último'? Quiero decir exactamente lo que quieres decir. Solo trato de entrar en el libro de citas citables aquí. ¡Jaja!
Cyril Gupta
37
La pregunta básica es si está absolutamente, positivamente, en última instancia seguro de que no usará estos datos para nada más que HTML. Porque una vez empaquetado en HTML, los datos serán casi irrecuperables. Con JSON, su back-end puede trabajar con XML, SVG, motores de bases de datos, API de sitios cruzados y mil otras interfaces y sistemas que pueden aceptar JSON. Con HTML, solo podrá usarlo dentro de HTML.
SF.
3
@SF: Al devolver HTML del servidor, me aseguro de dividir el código generador de HTML del código que accede a la base de datos. De esa manera, también puedo agregar fácilmente un formulario JSON.
Casebash
114

Principalmente estoy de acuerdo con las opiniones expresadas aquí. Solo quería resumirlos como:

  • Es una mala práctica enviar HTML si termina analizándolo en el lado del cliente para hacer algunos cálculos sobre él.

  • Es una mala práctica enviar JSON si todo lo que terminas haciendo es incorporarlo al árbol DOM de la página.

Vinko Vrsalovic
fuente
3
¿Qué sucede si necesita hacer algunos cálculos y también incorporarlos al DOM de la página?
Enrique
Me pregunto cuánto tiempo la declaración anterior tendrá una veracidad adjunta, si agrega la " Vida media del conocimiento " en la ecuación.
Val
¿Es posible devolver un HTML que tenga etiquetas <script> y luego ejecutarlas en el lado del cliente cuando se carga la página?
nish1013
Esta. Además, si está devolviendo datos que deben ser fluidos en su presentación de alguna manera, por ejemplo, si tiene una tabla HTML con columnas que le gustaría poder ordenar. Ya sea que los haya ordenado ahora o no, es posible que desee hacerlo más tarde, por lo que en tal caso, la prueba del futuro vale la pena el esfuerzo adicional de ir a la ruta JSON.
trpt4him
También agregaría, si solicita URL de imágenes a través de JSON solo para intentar representarlas en la página, es mucho más eficaz incluirlas en HTML desde el principio, para que las imágenes puedan comenzar a cargarse antes (antes de que regrese su ajax) .
FailedUnitTest
30

Bien,

Soy una de esas raras personas a las que les gusta separar las cosas de esta manera: - El servidor es responsable de entregar los datos (modelo); - El cliente es responsable de mostrar (ver) y manipular los datos (modelo);

Entonces, el servidor debería enfocarse en entregar el modelo (en este caso, JSON es mejor). De esta manera, obtienes un enfoque flexible. Si desea cambiar la vista de su modelo, mantenga el servidor enviando los mismos datos y simplemente cambie el cliente, los componentes de JavaScript, que cambian esos datos en una vista. Imagine que tiene un servidor que entrega datos a dispositivos móviles, así como a aplicaciones de escritorio.

Además, este enfoque aumenta la productividad, ya que el código del servidor y del cliente se puede construir al mismo tiempo, sin perder nunca el foco, que es lo que sucede cuando se cambia de js a PHP / JAVA / etc.

En general, creo que la mayoría de las personas prefieren hacer todo lo posible en el lado del servidor porque no dominan js, por lo que intentan evitarlo tanto como sea posible.

Básicamente, tengo la misma opinión que esos tipos que están trabajando en Angular. En mi opinión, ese es el futuro de las aplicaciones web.

ramaralo
fuente
Sí, estoy totalmente de acuerdo contigo. Sin embargo, hacer tanto lado del servidor cuando se trata de información confidencial me parece mejor. Si necesita que el cliente reaccione de manera diferente dependiendo del resultado, usaría json; de lo contrario, usaría html.
Fi Horan
9

Tengo algo interesante que pensé que podría agregar. Desarrollé una aplicación que solo cargaba una vista completa una vez. A partir de ese momento, se comunicó de nuevo al servidor solo con ajax. Solo necesitaba cargar una página (mi razón para esto no es importante aquí). Lo interesante es que tenía una necesidad especial de devolver algunos datos para que se operaran en JavaScript Y una vista parcial para mostrar. Podría haber dividido esto en dos llamadas a dos métodos de acción separados, pero decidí ir con algo un poco más divertido.

Echale un vistazo:

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

¿Qué es RenderPartialViewToString () que podrías preguntar? Es esta pequeña pepita de frescura aquí:

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();
     }
}

No he hecho ninguna prueba de rendimiento en esto, así que no estoy seguro de si incurre en más o menos sobrecarga que llamar a un método de acción para JsonResult y uno para ParticalViewResult, pero aún así pensé que era genial. Simplemente serializa una vista parcial en una cadena y la envía junto con el Json como uno de sus parámetros. Luego uso JQuery para tomar ese parámetro y aplicarlo en su nodo DOM apropiado :)

¡Déjame saber lo que piensas de mi híbrido!

Chev
fuente
1
Enviar la vista renderizada y los datos en una solicitud parece un poco redundante. Es broma, si tuviera la capacidad de hacer una vista del lado del cliente, sería aún mejor enviar la plantilla de vista y los datos como solicitudes separadas. Se requirió una solicitud adicional, pero solo una vez, ya que la solicitud de plantilla se almacenará en caché para solicitudes posteriores. Idealmente, sería mejor usar una combinación de representación de la vista del lado del cliente y del servidor para poder crear páginas en el servidor y parciales en el navegador, pero si solo implementa la representación de la vista del lado del servidor, este no es un mal enfoque.
Evan Plaice el
8

Si la respuesta no necesita más procesamiento del lado del cliente, HTML está bien en mi opinión. Enviar JSON solo te obligará a hacer ese procesamiento del lado del cliente.

Por otro lado, uso JSON cuando no quiero usar todos los datos de respuesta a la vez. Por ejemplo, tengo una serie de tres selecciones encadenadas, donde el valor seleccionado de una determina qué valores se utilizarán para completar la segunda, y así sucesivamente.

Ionuț G. Stan
fuente
7

IMV, se trata de separar los datos de la presentación de los datos, pero estoy con Pascal, no necesariamente se deduce que esa separación solo pueda ser a través del límite cliente / servidor. Si ya tiene esa separación (en el servidor) y solo quiere mostrarle algo al cliente, ya sea que envíe JSON y lo procese posteriormente en el cliente, o simplemente que envíe HTML, depende completamente de sus necesidades. Decir que estás "equivocado" al enviar HTML en el caso general es una declaración IMV demasiado general.

TJ Crowder
fuente
6

JSON es un formato muy versátil y ligero. Descubrí su belleza cuando comencé a usarlo como un analizador de plantillas del lado del cliente. Permítanme explicar, mientras que antes estaba usando smarty y vistas en el lado del servidor (generando una alta carga del servidor), ahora uso algunas funciones jquery personalizadas y todos los datos se representan en el lado del cliente, usando el navegador de clientes como analizador de plantillas. ahorra recursos del servidor y, por otro lado, los navegadores mejoran sus motores JS todos los días. Por lo tanto, la velocidad del análisis del cliente no es un problema importante en este momento, incluso más, los objetos JSON son generalmente muy pequeños, por lo que no consumen muchos recursos del lado del cliente. Prefiero tener un sitio web lento para algunos usuarios con un navegador lento en lugar de un sitio lento para todos debido al servidor muy cargado.

Por otro lado, al enviar datos puros desde el servidor, los abstrae de la presentación, por lo que si mañana desea cambiarlos o integrar sus datos en otro servicio, puede hacerlo mucho más fácilmente.

Solo mis 2 centavos.

Miguel
fuente
¿Y cómo se asegura de obtener una página legible cuando JavaScript está deshabilitado?
Vinko Vrsalovic
8
Si JS está deshabilitado, no podrá cargar html también. JS está deshabilitado en el 2.3% de los usuarios de acuerdo con mis estadísticas de Google Analytics. La mejor manera de bajar es tratar de complacer a todos.
Mike
44
Estoy de acuerdo al 100% con Mike. Intentar complacer a todos es imposible y solo te hará daño. Si los usuarios están desactivando JS, deben estar acostumbrados a muchos sitios que no funcionan para ellos en este momento.
Chev
1
¿Cómo se obtienen las estadísticas de JavaScript en Analytics ya que Analytics usa Javascript para rastrear datos?
Nick
@Nick Buena pregunta, pero encontré esto: stackoverflow.com/questions/15265883/…
Renan Cavalieri
6

Si desea un cliente desacoplado limpio, que en mi opinión es la mejor práctica, entonces tiene sentido tener el 100% del DOM creado por javascript. Si crea un cliente basado en MVC que tiene todos los conocimientos para construir la interfaz de usuario, sus usuarios descargan un archivo javascript una vez y se almacena en caché en el cliente. Todas las solicitudes después de esa carga inicial se basan en Ajax y solo devuelven datos. Este enfoque es el más limpio que he encontrado y proporciona una encapsulación limpia e independiente de la presentación.

El lado del servidor solo se enfoca en entregar datos.

Así que mañana, cuando el producto le pida que cambie el diseño de una página por completo, todo lo que cambia es el JS de origen que crea el DOM, pero es probable que pueda reutilizar sus controladores de eventos ya existentes y el servidor es ajeno porque se desacopló al 100% de la presentación

Lance Caraccioli
fuente
1
Estoy de acuerdo, también puedes reutilizar el json para tu aplicación móvil.
Alex Shilman
Esta debería haber sido la respuesta aceptada: las primeras 6 - 7 palabras responden la pregunta sucintamente.
Nicholaswmin
De acuerdo. La ventaja de los datos de retorno (JSON) sobre la presentación (html) es que ahora tiene una API web "gratuita" que puede reutilizarse para otros clientes, ya sea móvil o una aplicación completamente diferente que esté interesada en algunos datos de esta aplicación En mi experiencia, el uso de un marco web simple en el lado del servidor que solo se ocupa de datos y no de presentaciones a menudo conduce a resultados buenos y simples. El navegador y las CPU modernas son tan rápidos que solo en casos especiales la representación será un cuello de botella. El mayor cuello de botella es principalmente la red en sí y la llamada a la base de datos.
principiante_
4

Dependiendo de su interfaz de usuario, es posible que necesite actualizar dos (o más) elementos diferentes en su DOM. Si su respuesta está en HTML, ¿va a analizar eso para averiguar qué va a dónde? O simplemente puede usar un hash JSON.

Incluso puede combinarlo, devolver un JSON con datos html :)

{ 'dom_ele_1' : '<p>My HTML part 1</p>', 'dome_ele_2' : '<div>Your payment has been received</div>' }
tchen
fuente
Es una mala práctica enviar JSON si todo lo que terminas haciendo es incorporarlo en el árbol DOM de la página ... y al combinar JSON con HTML estás usando esta mala práctica
thermz
2

HTML tiene muchos datos redundantes y no mostrados, es decir, etiquetas, hojas de estilo, etc. Por lo tanto, el tamaño de HTML en comparación con los datos de JSON será mayor, lo que generará más tiempo de descarga y renderización, además hará que el navegador esté ocupado procesando los nuevos datos.

John Saman
fuente
1

El envío de json generalmente se realiza cuando tiene un widget de JavaScript que solicita información del servidor, como una lista o una vista de árbol o un autocompletado. Aquí es cuando enviaría JSON, ya que son datos que se analizarán y usarán sin formato. Sin embargo, si solo va a mostrar HTML, es mucho menos trabajo generarlo en el lado del servidor y solo mostrarlo en el navegador. Los navegadores están optimizados para insertar HTML directamente en el dom con innerHTML = "" para que no pueda equivocarse con eso.

Zoidberg
fuente
FWIW, innerHTMLhistóricamente es mucho más lento que un fragmento de documento: coderwall.com/p/o9ws2g/… .
Nate Whittaker
0

Creo que depende de la estructura del diseño, es más sexy usar JSON que HTML, pero la pregunta es cómo se manejaría para que sea fácil de mantener.

Por ejemplo, supongamos que tengo la página de listado que utiliza el mismo html / estilo de todo el sitio, escribiría la función global para formatear esas partes de HTML y todo lo que tengo que hacer es pasar el objeto JSON a la función.

Methee
fuente
0

La respuesta HTML es suficiente en la mayoría de los casos a menos que tenga que realizar algún cálculo en el lado del cliente.

Mubashir
fuente
0

Depende de las circunstancias.

A veces es esencial evitar JSON. Cuando nuestros programadores tienen problemas para programar en js, por ejemplo.

Mi experiencia me dice que: mejor usar el servicio ajax que JSON en línea.

Tarde o temprano el js se convierte en un problema.

Alegorico
fuente