¿Qué tan seguras son las solicitudes ocultas de AJAX que tienen un rendimiento falso?

48

¿Qué es una solicitud AJAX oculta?

He notado un aumento en el uso de solicitudes ocultas de AJAX diseñadas para hacer que la acción de un usuario parezca suceder de inmediato. Me referiré a este tipo de solicitud AJAX como sin bloqueo. Es una solicitud AJAX hecha sin que el usuario sepa que está sucediendo, se realiza en segundo plano y su operación es silenciosa ( no hay detalles para indicar una finalización exitosa de la llamada AJAX ). El objetivo es hacer que la operación parezca que ha sucedido inmediatamente cuando realmente no ha terminado.

Aquí hay ejemplos de solicitudes AJAX sin bloqueo;

  • El usuario hace clic en eliminar en una colección de correos electrónicos. Los elementos desaparecen inmediatamente de su bandeja de entrada y pueden continuar con otras operaciones. Mientras tanto, una solicitud AJAX está procesando la eliminación de los elementos en segundo plano.
  • El usuario completa un formulario para nuevos registros. Clics guardar. El nuevo elemento aparece en la lista de inmediato. El usuario puede continuar agregando nuevos registros.

Para aclarar, aquí hay ejemplos de bloqueo de solicitud AJAX;

  • El usuario hace clic en eliminar en una colección de correos electrónicos. Aparece un cursor de reloj de arena. Se realiza la solicitud AJAX y, cuando responde, el cursor del reloj de arena se apaga. El usuario tiene que esperar un segundo para que se complete la operación.
  • El usuario completa un formulario para nuevos registros. Clics guardar. El formulario se vuelve gris con una animación de cargador AJAX. Se muestra un mensaje "Se guardaron sus datos", y el nuevo registro aparece en la lista.

La diferencia entre los dos escenarios anteriores es que una configuración de AJAX sin bloqueo no proporciona retroalimentación de un rendimiento operativo, y una configuración de AJAX de bloqueo sí.

El riesgo de solicitudes ocultas de AJAX

El mayor riesgo de este estilo de solicitud AJAX es que la aplicación web podría estar en un estado completamente diferente cuando falla la solicitud AJAX.

Por ejemplo, un ejemplo sin bloqueo;

  • El usuario selecciona un montón de correos electrónicos. Hace clic en el botón Eliminar. La operación parece ocurrir de inmediato (los elementos simplemente desaparecen de la lista). Luego, el usuario hace clic en el botón de redacción y comienza a escribir un nuevo correo electrónico. Es en este momento que el código JavaScript descubre que la solicitud AJAX falló. El script podría mostrar un mensaje de error, pero realmente no tiene sentido en este momento.

Alternativamente, un ejemplo de bloqueo;

  • El usuario selecciona un montón de correos electrónicos. Hace clic en el botón Eliminar. Ve un reloj de arena, pero la operación falla. Reciben un mensaje de error que dice "error. Bla, bla, bla". Vuelven a la lista de correos electrónicos y todavía tienen seleccionados los correos que querían eliminar. Podrían intentar eliminarlos nuevamente.

También existen otros riesgos técnicos para realizar solicitudes AJAX sin bloqueo. El usuario puede cerrar el navegador, puede navegar a otro sitio web y puede navegar a otra ubicación en la web actual que hace que el contexto de cualquier respuesta de error no tenga sentido.

Entonces, ¿por qué se está volviendo tan popular?

Facebook, Google, Microsoft, etc. etc. Todos estos dominios grandes utilizan cada vez más solicitudes AJAX sin bloqueo para hacer que las operaciones parezcan que se realizan al instante. También he visto un aumento en los editores de formularios que no tienen botón de guardar o enviar . Tan pronto como salga de un campo o presione enter. El valor se guarda. No hay ningún mensaje de perfil actualizado o paso de guardado.

Las solicitudes de AJAX no son una certeza, y no deben tratarse como exitosas hasta que se hayan completado, pero muchas de las principales aplicaciones web están funcionando así.

¿Estos sitios web que usan llamadas AJAX sin bloqueo para simular aplicaciones receptivas corren un riesgo innecesario a costa de aparecer rápidamente?

¿Es este un patrón de diseño que todos deberíamos seguir para seguir siendo competitivos?

Reactgular
fuente
20
Esto se justifica por el hecho de que la operación exitosa es mucho más probable, por lo tanto, ser lento solo para evitar el raro caso de retroalimentación demasiado optimista es una mala compensación. Transpuesto a las relaciones personales, ¿preferiría interactuar con una persona tranquila y soleada o con una persona que asume categóricamente que todo lo que puede salir mal saldrá mal y actuará en consecuencia?
Kilian Foth
1
Para mí, con lo que estoy luchando es que una aplicación de escritorio tiene la operación y el error de inmediato. Donde como, con las aplicaciones web, la operación ocurre de inmediato, pero el error se retrasa. Sin embargo, los sitios operan con el diseño de una aplicación de escritorio.
Reactgular
77
¿También ha considerado lo que sucede cuando su aplicación de escritorio escribe en el disco, en realidad va a un búfer del sistema operativo y el disco falla antes de que pueda escribirse en el plato? O, para el caso, el disco falla después de que los bytes se escriben en el plato. En ambos casos, el usuario piensa que algo ha sucedido cuando realmente no ha sucedido.
kdgregory
2
@KilianFoth Prefiero el que asume que todo puede salir mal, si la persona "soleada" te golpeará y robará tu billetera a la primera señal de problemas. Por lo tanto, depende de la escala de la reacción de la página en caso de falla.
Izkata 01 de
1
@ButtleButkus Creo que esos mensajes guardados son nuevos. No estaban allí cuando hice la pregunta. Me di cuenta de que Google agregó más comentarios últimamente, que está haciendo cosas en segundo plano.
Reactgular

Respuestas:

62

No es tanto el rendimiento "falso" como la capacidad de respuesta real. Hay varias razones por las que es popular:

  • Las conexiones a Internet son bastante confiables hoy en día. El riesgo de que falle una solicitud AJAX es muy bajo.
  • Las operaciones que se realizan no son realmente críticas para la seguridad. Si sus correos electrónicos no se eliminan en el servidor, lo peor que sucede es que debe eliminarlos nuevamente la próxima vez que visite la página.
  • Puede diseñar su página para deshacer la acción si la solicitud falla, pero realmente no tiene que ser tan sutil porque significa que su conexión al servidor está interrumpida. Es más fácil decir "Conexión perdida. No se pueden guardar los cambios recientes. Inténtalo de nuevo más tarde".
  • Puede diseñar su página para permitir solo una solicitud AJAX pendiente, para que su estado no se desincronice demasiado del servidor.
  • El navegador le advierte si intenta cerrar o navegar fuera de una página mientras hay una solicitud AJAX pendiente.

Advertencia pendiente de AJAX

Karl Bielefeldt
fuente
8
Ese último punto, ¿todos los navegadores lo hacen por defecto?
Svish
No lo sé. Solo lo probé en IE9 y el último Chrome.
Karl Bielefeldt
3
Es obvio que no está familiarizado con Internet australiano, por no hablar de los pobres, desarrollar y lugares aislados, incluso móvil en un vehículo en movimiento ...
sendero hippie
2
@hippietrail Bueno, no puedes hacer felices a todos todo el tiempo.
KOVIKO
1
Cuando el usuario envía una solicitud, no siempre solicita una nueva página. Creo que las aplicaciones AJAX bien diseñadas pueden hacerlas más agradables, permitiéndole al usuario saber qué está pasando de manera más eficiente que con una recarga.
Frederik.L
32

Asumir que algo funcionará y mostrar un error en caso de que falle en el lado remoto es mucho más fácil de usar que bloquear al usuario para que no haga nada más hasta que haya una respuesta del servidor.

Un cliente de correo electrónico es en realidad un gran ejemplo para esto: cuando tengo una lista con 5 correos electrónicos y se selecciona el superior, espero que al presionar DELtres veces se eliminen los primeros tres correos electrónicos. Con "AJAX sin bloqueo" esto funciona bien: cada vez que presiono la tecla, el correo electrónico seleccionado se elimina de inmediato. Si algo sale mal, se muestra un error y los correos electrónicos no eliminados correctamente se muestran nuevamente O la página se vuelve a cargar para eliminar el estado local inconsistente.

Entonces, en el caso más común , que es el éxito, mejora la usabilidad. En el caso poco frecuente (falla), la usabilidad se degrada (el elemento eliminado vuelve a aparecer o la aplicación se "reinicia"), pero al crear una aplicación, generalmente desea tener la mejor usabilidad para casos comunes, no en caso de errores.

ThiefMaster
fuente
1
+1 este es el punto central del asunto. Hay tanta seguridad por defecto que las personas implementan en estos días que en el peor de los casos aún no se arriesga a cometer verdaderos errores de usuario: imagine que el cliente de correo electrónico no puede eliminar, ahora el estado local es malo e intenta eliminar el correo electrónico 4 que está desalineado con el servidor, la gran mayoría de los desarrolladores de back-end tendrán una captura de seguridad allí para asegurarse de que solo elimine lo que el usuario quiere absolutamente y, por lo tanto, esta desalineación no causará eliminaciones erróneas (puede fallar por error pero no se eliminará) .
Jimmy Hoffa
@JimmyHoffa usaría una identificación de correo electrónico única en la solicitud de eliminación. Sería realmente malo enviar solicitudes de eliminación según el orden de visualización arbitrario de los correos electrónicos en su bandeja de entrada.
Buttle Butkus
14

Los usuarios no se preocupan por lo que su software está haciendo detrás de escena: quieren que sus acciones tengan un impacto visible y que puedan trabajar a su ritmo.

Si una acción fue exitosa en el lado del cliente, como eliminar correos electrónicos, es su trabajo hacerla exitosa también en el lado del servidor. ¿Por qué falló la eliminación? Si se debe a algún tipo de limitación (por ejemplo, no puede eliminar un correo electrónico que se ha archivado), se debe informar al usuario antes de que su acción falle.

Si el error es causado por algo más grave (digamos un bloqueo de la base de datos), debe tener una forma de guardar la operación y volver a intentarlo cuando el sistema vuelva a funcionar.

Un buen ejemplo de cómo administrar esto es la forma en que Facebook maneja el chat. No hay forma de evitar que un usuario se desconecte repentinamente, lo que significa que no podrá leer los mensajes que envió antes de irse. En lugar de mostrar un error, el sistema guarda todos esos mensajes y los pone a disposición del usuario cuando regrese. No se pierden datos.

Eco distante
fuente
2
+1. Excelente ejemplo de chat. La mayoría de los usuarios esperan que su mensaje esté disponible de inmediato para todos, y dado que tales mensajes rara vez fallan, los usuarios tienen la ilusión de que ese es el caso.
Neil
1
@Niphra, "¿Por qué falló la eliminación?" La red puede fallar por muchas razones, ninguna de las cuales tiene que ver con su aplicación. No hay nada que puedas hacer para detener eso.
Pacerier
5

Puede comprometerse entre las dos opciones. Por ejemplo, si el usuario elimina un correo electrónico, puede marcarlo en rojo o gris hasta que reciba una confirmación del servidor, y solo luego eliminarlo de la lista. El usuario aún puede hacer otras cosas mientras una acción está pendiente, por lo que no está bloqueando, pero aún deja un pequeño recordatorio para el usuario de que sus acciones aún no se han comprometido.

Amazon AWS adopta este enfoque: cuando detiene / inicia una instancia, la casilla de verificación que le permite seleccionarla se convierte en una ruleta (por lo que no puede hacer nada durante unos segundos), pero esto no le impide interactuando con otras instancias.

valtron
fuente
Su sugerencia es similar a la forma en que gmail muestra el texto "Guardando ..." mientras se ejecuta el XHR, y "Guardado" después de hacerlo. Si siempre dijera "Salvado", ¿quién lo creería?
Buttle Butkus
3

Creo que esto se une a más y más sitios web que intentan comportarse como aplicaciones y hacen más procesamiento en el navegador (como validar los datos del formulario) que los sitios más tradicionales. No veo demasiado problema en eso, siempre y cuando su código sea confiable y pueda esperar que tenga éxito en condiciones normales.

Usted dice "Es en este momento que el código JavaScript descubre que la solicitud AJAX falló. El script podría mostrar un mensaje de error, pero en este momento no tiene sentido".

¿Por qué debería ser inútil? Puede volver a la lista de correos electrónicos y volver a eliminar. ¿Por qué esperar en su lugar? En realidad, no existe un gran "riesgo" y no "parecen" ser rápidos, en realidad funcionan más rápido. Entonces, si la actividad no es "crítica", ¿por qué ser lenta?

Thorsten Müller
fuente
1
Quizás no tenía sentido la palabra correcta, pero lo que quiero decir es que el mensaje de error carece de contexto relativo, porque el usuario ahora está haciendo algo completamente diferente. Intento decir que, para un usuario web ignorante, pensó que los correos electrónicos se eliminaron con éxito. Entonces, ¿por qué ahora, más tarde, reciben un mensaje de error por algo que "vieron" fueron eliminados. Para nosotros los programadores, entendemos, pero para el abuelo que usa gmail no lo entenderían.
Reactgular
La mayoría de las personas preferiría usar una aplicación donde las cosas suceden de inmediato, el sistema responde y hay una probabilidad de 1 en 10,000 de que la IU se actualice de manera extraña en caso de error que una aplicación que se congela por un segundo cada vez que cambian un valor.
Gort the Robot
1

Mi 2c es: hay situaciones en las que es mejor tener, como usted dice, operaciones de Ajax "sin bloqueo" y otras en las que es una mala elección de diseño. Ejemplo: votar un video de YouTube. Realmente no desea que se bloquee ninguna parte de la página mientras hace clic en los pequeños comienzos allí. Es mejor fallar en silencio. Incluso un mensaje de confirmación sería exagerado. Sin embargo, su ejemplo con la eliminación de correo electrónico calificaría como obligatorio para la solicitud de Ajax de tipo de bloqueo.

Mongo DB hace algo así (y esto podría considerarse como un ejemplo de aplicación de escritorio). Tienen varias "preocupaciones de escritura" para sus operaciones, y puede configurarlo con diferentes valores para cada operación, que van desde "regresar de inmediato y no esperar nada" hasta "bloquear" hasta que haya confirmado la transferencia exitosa de la red y luego regrese "a" espere hasta que el contenido esté correctamente programado para escritura en disco en la máquina remota antes de su devolución ". Obviamente, si crea un cliente grueso de escritorio (como C ++) con el controlador Mongo, establecería la preocupación de escritura más ligera para las operaciones de db de "criticidad" mínima (como verificar si hay correo electrónico nuevo) y otras cuestiones de escritura más estrictas .

Si bien veo la utilidad de Ajax sin bloqueo, estoy de acuerdo con usted en que está sucediendo demasiado. En un momento había al menos un sitio famoso de "redes sociales" que haría esto para subir fotos. Elegiste tu foto para subir y luego bam, de inmediato te diría que está hecha, y luego, al día siguiente, cuando quisiste agregar algunas fotos más (o usar en las que creías que ya habías agregado), nunca fue encontrado. Más tarde se dieron por vencidos con esto, y en realidad se tomaron el tiempo de esperar la respuesta (y de hecho a veces recibía mensajes como "no se pudo cargar la foto, intente más tarde").

Shivan Dragon
fuente
+1 por ver las cosas a mi manera :). La carga de fotos es un gran ejemplo de que falla.
Reactgular
1
¿Por qué sería preferible una carga de bloqueo? En Picasa (interfaz web), puede arrastrar fotos y, mientras se cargan en segundo plano, puede arrastrar más o etiquetar fotos que han terminado, etc. Una operación de carga de bloqueo haría que un UX horrible
BLSully