Autor en Google+
Saltar al contenido

Artículos, tutoriales, trucos, curiosidades, reflexiones y links sobre programación web ASP.NET Core, MVC, Blazor, SignalR, Entity Framework, C#, Azure, Javascript... y lo que venga ;)

15 años online

el blog de José M. Aguilar

Inicio El autor Contactar

Artículos, tutoriales, trucos, curiosidades, reflexiones y links sobre programación web
ASP.NET Core, MVC, Blazor, SignalR, Entity Framework, C#, Azure, Javascript...

¡Microsoft MVP!
Syncfusion UI Components for Blazor
martes, 2 de febrero de 2021
Blazor

El parser de Blazor de versiones anteriores a la 5.0 era bastante permisivo con los espacios no significativos que los desarrolladores dejamos a la hora de escribir nuestro código de marcado. Es decir, todos los espacios incluidos en el código fuente, fueran importantes o no para el resultado final, formaban parte del proceso de renderización y, por tanto, trasladados tal cual al navegador. 

Entendemos por espacio no significativo aquél carácter espacio, tabulador, saltos de línea o similares que el navegador no va a representar visualmente al componer la página. Por ejemplo, un marcado como "<h2>1        2</h2>" suele representarse en el browser exactamente igual que si hubiéramos enviado "<h2>1 2</h2>" (salvo que hayamos usado reglas CSS específicas en dirección contraria), porque todos los espacios intermedios son ignorados.

Un buen ejemplo es el siguiente; fijaos la estructura de un código Blazor que seguro usáis de forma habitual:

<ul>
   @foreach (var item in Items)
   {
      <li>
         @item.Text
      </li>
   }
</ul>

Realmente es código muy bonito y legible pero, desde el punto de vista del parser, tiene otra pinta si vemos los espacios que estamos introduciendo (sustituyo los espacios por guiones):

<ul>
---@foreach (var item in Items)
---{
------<li>
---------@item.Text
------</li>
---}
</ul>

Al renderizar este código con una lista de, digamos, 10.000 letras "A", al navegador llegarían como mínimo (omitiendo los saltos de línea):

  • Los tres espacios antes del @foreach.
  • Los tres espacios antes de la apertura de la llave.
  • Por cada uno de los 10.000 elementos de la lista:
    • Seis espacios ante el primer <li>.
    • Nueve espacios antes del texto del elemento.
    • El texto del elemento, la letra "A"
    • Seis espacios ante el cierre del <li>.
  • Tres espacios antes del cierre de de la llave

Aunque podéis usar la calculadora, seguro que a ojo podéis haceros una idea del volumen que suponen los espacios frente a los contenidos que realmente interesan.

Ya, probablemente el ejemplo anterior es algo exagerado, pero seguro que os ha llevado a ver la magnitud del problema: el contenido realmente importante puede representar una mínima parte de la información enviada al navegador.

Aunque en menor medida, podemos sufrir el mismo efecto en el interior de las etiquetas. Por ejemplo, ¿qué aportan los siguientes espacios extra?

<p      style="font-weight: bold"       class="main-text"          title="Woa"   >

Pues bien, en benchmarks realizados por el equipo de desarrollo de Blazor han medido que esos espacios no significativos pueden consumir hasta un 40% del tiempo de renderización. Y como uno de los objetivos de Blazor 5 era aumentar el rendimiento, esto no podía quedar así ;)

A partir de Blazor 5, por defecto los espacios no significativos serán eliminados en tiempo de compilación, reduciéndose así la complejidad del árbol y, por tanto, acelerando la renderización.

Según la documentación oficial, el comportamiento por defecto eliminará los espacios que:

  • Se encuentren por detrás o delante de cualquier otro elemento.
  • Se encuentren detrás o delante de un RenderFragment (por ejemplo, contenidos hijo siendo enviados a otros componentes).
  • Se encuentren delante o detrás de un bloque C# como @if o @foreach.

En principio no es algo que nos debiera afectar demasiado, aunque sí habrá casos en los que nos fastidiará un poco el resultado si estamos tenemos partes del marcado afectados por reglas CSS como white-space: pre.

Si tenemos páginas o componentes donde este nuevo comportamiento supusiera un problema, siempre podemos desactivarlo a nivel de componente (bueno, o de forma global usando los _ViewImports.razor) simplemente introduciendo en su encabezado la siguiente directiva:

@preservewhitespace true

Y con esto, todo volverá a la normalidad :)

Os dejo aquí un código por si queréis hacer la comparativa del peso de la página con una u otra opción:

@page "/"
@* @preservewhitespace true
   Descomentar la línea de arriba para ver el
   el comportamiento de Blazor pre-5.0 
*@

<ul>
    @foreach (var item in new string('a', 10000))
    {
        <li>
            @item
        </li>
    }
</ul>

Os recomiendo que os fijéis en los cambios del peso del archivo y en el código fuente generado tanto sin la directiva (el comportamiento por defecto de Blazor 5) como con ella, insertándole el @preservewhitespace true (el comportamiento por defecto de las versiones anteriores de Blazor.)

Publicado en Variable not found.

Estos contenidos se publican bajo una licencia de Creative Commons Licencia Reconocimiento-No comercial-Compartir bajo la misma licencia 3.0 España de Creative Commons

Aún no hay comentarios, ¡sé el primero!

Artículos relacionados: