Compartir a través de



Octubre de 2017

Volumen 32, número 10

Desarrollo web y pasión por la velocidad: ¿pueden las técnicas de AJAX administrado acelerar su web?

Por Thomas Hansen | Octubre de 2017

Según diversos estudios sobre el tema, dos de las preocupaciones más importantes al crear una aplicación web AJAX son la velocidad y la capacidad de respuesta. Probablemente, son algunas de las razones por las que algunos desarrolladores deciden crear aplicaciones nativas, en lugar de aplicaciones web. Pero, ¿y si le dijera que existe una forma de crear aplicaciones web AJAX con una velocidad y capacidad de respuesta 100 veces superior a la de las aplicaciones que pueda conocer?

He inventado una forma de crear aplicaciones web AJAX basadas en JavaScript 100 % puras que consumen 10 veces (y, a veces, hasta 300 veces) menos ancho de banda, en función de los tipos de herramientas que use y lo que quiera crear. Me refiero a esta técnica como “AJAX administrado”.

De alguna manera, AJAX administrado está inspirado en la forma de crear Common Language Runtime (CLR) de Microsoft. Por ejemplo, al crear una aplicación C#, el compilador crea un ensamblado CLR. Esto implica que el entorno en tiempo de ejecución para el resultado final es un “entorno administrado”. Cuando crea una aplicación con AJAX administrado, el resultado compilado no es distinto de un sitio web de ASP.NET sencillo normal; se convierte en un entorno administrado, en que las partes JavaScript de los resultados finales se abstraen por completo, del mismo modo que las instrucciones de CPU se abstraen cuando tiene un ensamblado CLR.

¿Cómo funciona?

AJAX administrado no requiere conocimientos nuevos, prácticamente. Si ha hecho algún desarrollo en ASP.NET, puede colocar una biblioteca Control nueva en sus páginas .aspx y continuar con su trabajo, casi exactamente como antes. Debe crear un par de controles ASP.NET, bien desde el marcado .aspx o desde el código subyacente .NET en C#/F#/Visual Basic. A continuación, decore las propiedades de los controles, agregue un par de controladores de eventos de AJAX y ya estará listo.

La representación inicial crea un código HTML clásico y sencillo. Pero cada cambio que aplica a cualquiera de sus controles del lado servidor durante una solicitud AJAX se pasa al cliente como JSON. Por lo tanto, el cliente puede acabar con una minúscula biblioteca de JavaScript, de menos de 5 KB de tamaño total, y usted puede crear controles AJAX enriquecidos, como TreeView, DataGrid y TabView, sin tener que usar más de 5 KB de JavaScript.

Tenga en cuenta que, en este punto, ya ha superado el rendimiento de jQuery como archivo de JavaScript independiente en al menos una orden de magnitud (la versión 2.1.3 de jQuery después de la minificación y la compresión es de 30 KB). Por lo tanto, solo por el hecho de incluir jQuery en su página, y ningún otro código JavaScript, ya ha consumido 6 veces el ancho de banda que usaría con un enfoque de AJAX administrado. A medida que empieza a consumir jQuery en su propio JavaScript, este número se dispara.

La incorporación de cambios en la UI de jQuery en su versión minificada y comprimida aumenta el tamaño de las partes de JavaScript en 73,5 KB. Solo por incluir jQuery y la UI de jQuery en la página, aumenta su tamaño otros 103,4 KB (103,4 KB dividido por 4,8 KB supone multiplicar por 21,5 el consumo de ancho de banda). En este punto, aún no ha creado ni un solo elemento de UI en su página, pero jQuery y la UI de jQuery consumen casi 22 veces más espacio que el enfoque de AJAX administrado. Puede crear prácticamente cualquier widget de UI que se le ocurra con este código JavaScript de 5 KB, incluidos la mayoría de controles de UI que jQuery y la UI de jQuery puedan crear. En líneas generales, independientemente de lo que haga, difícilmente superará, si lo hace, este límite de 5 KB de JavaScript. Otras partes de la aplicación, como el código HTML y CSS, también podrían ver su tamaño reducido considerablemente.

Con este enfoque, se crean controles de UI de AJAX enriquecidos, como controles AJAX TreeView, DataGrid y TabView. Además, para crear estos widgets, no es necesario agregar más código JavaScript. Tampoco es necesario ningún conocimiento concreto para usar estos controles. Simplemente, se usan (casi) de la misma forma en que se consume un control WebControl de ASP.NET.

El enfoque de AJAX administrado tiene dos formas distintas de controlar las solicitudes HTTP que se envían a la página. Uno de los controladores es la solicitud HTTP sencilla normal, que sirve HTML al cliente. El otro controlador permite comprobar la existencia de un parámetro HTTP post. Si el parámetro existe, el controlador solo representará los cambios realizados en cada control en el cliente como JSON. Durante una solicitud AJAX, cada control creado mediante la modificación de la jerarquía de control de la página se volverá a crear automáticamente, con las propiedades que tenía en la solicitud previa. En el lado cliente, tiene un controlador general que controla las propiedades JSON en los controles y actualiza genéricamente los atributos y controladores de eventos DOM de los elementos DOM del cliente.

Este enfoque tiene muchos efectos secundarios positivos, ya que no va en contra de la forma en que se creó la página web originalmente, pues representa los elementos HTML como lo que son: elementos HTML. Esto implica que, semánticamente, las aplicaciones web resultan más fáciles de entender, por ejemplo, para spiders de motores de búsqueda. Además, crea un entorno superior para modificar cosas en el cliente, si quiere aprovechar lo mejor de ambos mundos.

Puede combinar este enfoque con tanto código JavaScript personalizado como desee. En ese caso, basta con inspeccionar el HTML representado en sus solicitudes HTML sencillas. Compare esto con el enfoque "div mágico" que usan muchas otras bibliotecas de UI de AJAX que, a menudo, contienen megabytes de JavaScript para crear controles DataGrid y TreeView.

De este modo, comprenderá que la cifra de una velocidad y capacidad de respuesta 100 veces más rápidas no es una exageración. De hecho, en comparación con los kits de herramientas de UI más usados, que se utilizan junto con C# y ASP.NET, supone una velocidad y capacidad de respuesta entre 100 y 250 veces superior en cuanto a consumo de ancho de banda. Recientemente, hice una medición del rendimiento entre el widget TreeView de AJAX administrado en System42 y tres de los mayores kits de herramientas de componentes de la pila ASP.NET. Descubrí que la diferencia en consumo de ancho de banda suponía una velocidad y capacidad de respuesta entre 150 y 220 veces superior.

Para ilustrar lo que implica esto, imagine que tiene una conexión a Internet extremadamente lenta que tarda 1 segundo en descargar 5 KB de JavaScript. Esto implica 1 segundo para descargar el código JavaScript de AJAX administrado y, probablemente, hasta 3 minutos y 40 segundos para descargar las partes de JavaScript de otros kits de herramientas. Imagine cuál sería la diferencia en términos de conversión si creara dos soluciones de comercio electrónico con estos dos enfoques.

El código

Dejemos las palabras y pasemos a la acción. En primer lugar, descargue Phosphorus Five desde bit.ly/2u5W0EO. Ahora, abra el archivo p5.sln y compile Phosphorus Five para poder acceder al ensamblado p5.ajax.dll. Va a consumir p5.ajax.dll en su aplicación web como referencia, así que deberá compilarlo antes de continuar. Tenga en cuenta que Phosphorus Five consta de más de 30 proyectos, pero, en este artículo, me centraré en el proyecto p5.ajax.

A continuación, cree un sitio web de ASP.NET en Visual Studio. Asegúrese de crear una aplicación de formularios Web Forms. En Visual Studio para Mac, puede encontrarlo en File (Archivo) | New Solution (Nueva solución) | Other (Otros) | .NET | ASP.NET Web Forms Project (Proyecto de Web Forms ASP.NET).

Cree una referencia dentro del sitio web que acaba de crear al ensamblado p5.ajax.dll ya compilado y modifique web.config para que se parezca al código siguiente:

<?xml version="1.0"?>
<configuration>
  <system.web>
    <pages clientIDMode="Static">
      <controls>
        <add assembly="p5.ajax" namespace="p5.ajax.widgets" tagPrefix="p5" />
      </controls>
    </pages>
    <compilation debug="true" targetFramework="4.5" />
    <httpRuntime targetFramework="4.5" />
  </system.web>
</configuration>

Las partes importantes de este código son "clientIDMode" y "add assembly". En este punto, puede usar cualquiera de los controles de p5.ajax desde el marcado .aspx con el prefijo p5. Asegúrese de modificar el contenido de la página Default.aspx para que se parezca al código de la Figura 1.

Figura 1 Creación de una página con un solo botón que cambia de texto cuando se hace clic en él

<%@ Page Language="C#" Inherits="foobar.Default" %>
<!DOCTYPE html>
<html>
<head runat="server">
  <title>Default</title>
</head>
<body>
  <form id="form1" runat="server">
    <p5:Literal 
      runat="server"
      id="foo"
      onclick="foo_onclick"
      Element="button">Click me!</p5:Literal>
  </form>
</body>
</html>

A continuación, cambie el código subyacente como se indica a continuación:

using System;
namespace foobar
{
  public partial class Default : p5.ajax.core.AjaxPage
  {
    [p5.ajax.core.WebMethod]
    public void foo_onclick(p5.ajax.widgets.Literal sender, EventArgs args)
    {
      sender.innerValue = "Hello World from Managed Ajax!";
    }
  }
}

Tenga en cuenta que, en primer lugar, debe heredar la página de AjaxPage, agregar un atributo WebMethod al controlador de eventos y convertir específicamente el primer parámetro en fuertemente tipado en el controlador de eventos como un widget "Literal". En este punto, puede iniciar el sitio web: haga clic en el botón y disfrute del resultado. Si recibe errores extraños al depurar el sitio web, asegúrese de desactivar la opción de configuración "Vínculo de explorador" de Visual Studio, que, normalmente, es un botón de barra de herramientas situado en la parte superior de Visual Studio. Si tiene curiosidad sobre lo que pasa aquí, inspeccione sus solicitudes HTTP. Además, asegúrese de echar un vistazo al HTML inicial.

Vaya, ¿qué ha sido eso?

Eso era AJAX administrado en la práctica. Hay puntos importantes de esta idea que se deben tener en cuenta. En primer lugar, puede modificar cualquier propiedad de cualquier control de la página desde cualquier controlador de eventos AJAX de la página. Si creó otro widget Literal, "Element" tipo "p", por ejemplo, podría actualizar su contenido desde el controlador de eventos "foo_onclick" del botón.

En segundo lugar, puede agregar, quitar, actualizar o recuperar de forma dinámica cualquier propiedad del widget como prefiera. Para hacer referencia a cualquier atributo o controlador de eventos, use el operador de subíndice de C#. En la Figura 2, en lugar de configurar el valor innerValue del widget, su propiedad de estilo se activa y el fondo cambia al color amarillo mediante la propiedad de estilo CSS. Tenga en cuenta que la propiedad de estilo del widget puede persistir y se recuerda. Observe también que esto se hace sin intercambiar grandes cantidades de datos ViewState entre el cliente y el servidor.

En una aplicación real, probablemente, utilizaría clases CSS. Para hacerlo, podría intercambiar la referencia de la Figura 2 de "style" a "class". Pero, dado que quería presentar un ejemplo sencillo aquí, no incluí archivos CSS, sino que usé el atributo style para mayor comodidad. Puede usar el enfoque que se muestra en la Figura 2 para agregar, quitar y cambiar el atributo que quiera, en cualquier widget de la página.

Figura 2 Cambio del color de fondo

using System;
namespace foobar
{
  public partial class Default : p5.ajax.core.AjaxPage
  {
    [p5.ajax.core.WebMethod]
    public void foo_onclick(p5.ajax.widgets.Literal sender, EventArgs args)
    {
      if (sender.HasAttribute ("style"))
        sender.DeleteAttribute ("style");
      else
        sender ["style"] = "background-color:Yellow;";
    }
  }
}

El tercer punto (y, probablemente, el más importante) es que puede agregar, quitar, actualizar e insertar de forma dinámica cualquier control AJAX nuevo en cualquier otro widget como prefiera. Sin embargo, antes de estudiar este último punto, es necesario examinar la "trinidad de widgets".

Hay tres widgets distintos en p5.ajax, pero también son muy parecidos en su API. Al combinar estos tres widgets juntos mediante composición, puede crear el marcado HTML que quiera. En el ejemplo de la Figura 2, se usó el widget Literal. El widget Literal tiene una propiedad "innerValue" que, en el lado cliente, se asigna a "innerHTML" y permite cambiar su contenido como una parte de cadena o HTML.

El widget Container puede contener widgets. Además, recuerda la colección Controls y permite agregar, quitar o cambiar su colección de controles dinámicamente durante las solicitudes AJAX.

El tercer widget es el widget Void, que se usa exclusivamente para controles sin contenido, como elementos de entrada HTML, elementos br, elementos hr, etc. El más importante para este ejemplo es, probablemente, el widget Container. Así pues, siga adelante y cambie el código de la página .aspx por el que ve en la Figura 3.

Figura 3 Creación de una página con un botón y una lista con viñetas que contenga un elemento de lista

<%@ Page Language="C#" Inherits="foobar.Default" %>
<!DOCTYPE html>
<html>
<head runat="server">
  <title>Default</title>
</head>
<body>
  <form id="form1" runat="server">
    <p5:Literal 
      runat="server"
      id="foo"
      onclick="foo_onclick"
      Element="button">Click me!</p5:Literal>
  <p5:Container
      runat="server"
      id="bar"
      Element="ul">
      <p5:Literal
        runat="server"
        id="initial"
        onclick="initial_onclick"
        Element="li">Initial list element, try clicking me!</p5:Literal>
  </p5:Container>
  </form>
</body>
</html>

La jerarquía de widgets de la Figura 3 creará un elemento "button" y un elemento "ul" con otro secundario, "li". A continuación, cambie el código C# subyacente por el código de la Figura 4.

Figura 4 Asignación de controladores de eventos AJAX para crear un nuevo elemento de lista

using System;

namespace foobar
{
  public partial class Default : p5.ajax.core.AjaxPage
  {
    protected p5.ajax.widgets.Container bar;

    [p5.ajax.core.WebMethod]
    public void foo_onclick(p5.ajax.widgets.Literal sender, EventArgs args)
    {
      // Using the factory method to create a new child widget for our "ul" widget.
      var widget = bar.CreatePersistentControl<p5.ajax.widgets.Literal>();
      widget.Element = "li";
      widget.innerValue = "Try clicking me too!";

      // Notice we supply the name of the method below here.
      widget ["onclick"] = "secondary_onclick";
    }

    [p5.ajax.core.WebMethod]
    public void initial_onclick(p5.ajax.widgets.Literal sender, EventArgs args)
    {
      sender.innerValue = "I was clicked!";
    }

    [p5.ajax.core.WebMethod]
    public void secondary_onclick(p5.ajax.widgets.Literal sender, EventArgs args)
    {
      sender.innerValue = "I was ALSO clicked!";
    }
  }
}

Tenga en cuenta que la última parte del código insertó nuevos widgets dinámicamente en el widget Container. Básicamente, se asignaron nuevos elementos "li" al elemento "ul" dinámicamente durante una solicitud AJAX y, simplemente, funcionó. Estos widgets se recuerdan de forma persistente entre solicitudes AJAX, de modo que puede cambiar sus propiedades e invocar controladores de eventos para ellos. Además, mediante la propiedad "Element", se puede representar cualquier elemento HTML y se puede agregar cualquier atributo con el operador de subíndice.

Ahora tiene un control 100 % perfecto sobre el marcado HTML y puede crear pequeñas solicitudes y respuestas AJAX que actualicen lo que quiera en la página como prefiera. Todo esto, con 4,8 KB de JavaScript. Ha convertido el desarrollo AJAX de aplicaciones web en algo tan fácil de hacer como el clásico y sencillo desarrollo de formularios Windows Forms. Además, durante el proceso, ha conseguido unas aplicaciones web con una velocidad y capacidad de respuesta 100 veces superior.

Un ejercicio en Hyperlambda

Hace unos meses, escribí un artículo en la edición de junio de 2017 de MSDN Magazine titulado “C#: hacer que C# sea más dinámico con Hyperlambda” (msdn.com/magazine/mt809119), que examinaba el lenguaje de programación no tradicional Hyperlambda basado en los árboles de ejecución. Lo menciono porque el enfoque basado en árbol de Hyperlambda hace que sea extremadamente fácil declarar una jerarquía de widgets AJAX. Combine p5.ajax con Hyperlambda para consumir un widget TreeView de AJAX y descubrirá unas eficiencias impresionantes.

Veámoslo. En primer lugar, además de Phosphorus Five, necesita descargar System42 y colocarlo en la carpeta principal de p5.webapp según las instrucciones que se describen en bit.ly/2vbkNpg. A continuación, inicie System42, que contiene un widget TreeView de AJAX ultrarrápido, abra "CMS", haga clic en + para crear una página lambda y pegue el código que se muestra en la Figura 5.

Figura 5 Creación de un elemento TreeView de AJAX que permitirá atravesar carpetas en el disco

create-widget
  parent:content
  widgets
    sys42.widgets.tree
      crawl:true
      items
        root:/
      .on-get-items
        list-folders:x:/../*/_item-id?value
        for-each:x:/@list-folders/*?name
          list-folders:x:/@_dp?value
          split:x:/@_dp?value
            =:/
          add:x:/../*/return/*
            src:@"{0}:{1}"
              :x:/@split/0/-?name
              :x:/@_dp?value
          if:x:/@list-folders/*
            not
            add:x:/../*/return/*/items/0/-
              src
                class:tree-leaf
        return
          items

Haga clic en Configuración, elija vacía como Plantilla, haga clic en Aceptar, guarde la página y haga clic en Ver página.

Intente expandir la vista de árbol de AJAX mientras examina lo que sucede en la red en sus solicitudes HTTP. Se dará cuenta de que acaba de crear una carpeta que examina una vista de árbol de AJAX con 24 líneas de Hyperlambda que mostrará sus carpetas a partir de la carpeta p5.webapp y que el consumo de ancho de banda total inicial es de solo 10,9 KB.

Si compara estos resultados con cualquier otro kit de herramientas de AJAX, a menudo descubrirá que otros kits de herramientas requieren que se descarguen varios megabytes de JavaScript, además de otras cosas que pasan por la red, mientras que TreeView de Hyperlambda no contiene más de 4,8 KB de JavaScript.

Esta vista de árbol de AJAX se creó con un total de 717 líneas de código en puro Hyperlambda, y solo se usaron los widgets Literal, Container y Void. La mayor parte del código está formada por comentarios, así que apenas se necesitaron 300 líneas de código para crear el control de vista de árbol de AJAX. El widget se consumió con 24 líneas de Hyperlambda, lo que le permite examinar las carpetas del disco. Para crear el control con cualquier otra cosa, se necesitarían miles de líneas de código, además de cientos de líneas para consumirlo, como se hizo con las 24 líneas de código de la Figura 5.

Si quiere, puede cambiar tres líneas de código del ejemplo de Hyperlambda y crear su propio widget personalizado de evento activo, lo que le permitiría consumir su propio widget especializado con una sola línea de código. Aprenda cómo hacerlo en bit.ly/2t96gsQ.

Así pues, ahora puede crear una vista de árbol de AJAX que examine las carpetas del servidor con una línea de código. Para crear algo equivalente en otros kits de herramientas, a menudo necesitaría cientos de líneas de código en cuatro lenguajes distintos. Aquí lo ha hecho con una línea de código y un lenguaje de programación, y funciona hasta 300 veces mejor que su competencia.

Resumen

Imagine poder producir resultados 100 veces mejores, más rápidos y optimizados, con una calidad 100 veces mayor, 100 veces menos errores y una productividad 100 veces superior que antes. Para asegurarse de usar los recursos más recientes, descargue Phosphorus Five desde bit.ly/2uwNv65 y System42 desde bit.ly/2vbkNpg.


Thomas Hansen crea software desde que tenía 8 años, cuando empezó a escribir código con un equipo Oric-1 en 1982. Ocasionalmente, crea código que hace más bien que mal. Entre sus pasiones se incluyen la arquitectura del software y las metodologías Web, AJAX y Agile. Puede ponerse en contacto con él a través de la dirección thomas@gaiasoul.com.

Gracias al siguiente experto técnico de Microsoft por revisar este artículo: James McCaffrey


Discuta sobre este artículo en el foro de MSDN Magazine