Bueno, es obvio que útlimamente se me da por la caché. El motivo es que he trabajado bastante con ella en los últimos meses por motivos de trabajo en la empresa, por un curso que he estado haciendo para campusMVP, y ya finalmente por parte de la charla que impartí en el developer Day, si bien en este caso por el tiempo que había apenas pude rozar la superficie del asunto... En fin..

El caso es que ya he mencionado alguna vez en posts anteriores que si movemos nuestra aplicación a Windows Server 2003 con Internet Information Server 6.0, podremos sacar partido de la nueva caché en modo núcleo que éste implementa a través de HTTP.sys. Esta caché de modo núcleo se comunica directamente con los componentes de E/S del kernel del sistema, sin pasar por el modo de ejecución usuario, e incrementa el rendimiento de la caché una barbaridad. Como ejemplo podemos ver los resultados del procesamiento de una página ASP.NET cuyo resultado ocupa 4KB de tamaño, usando una caché en modo núcleo y una caché "normal" en modo usuario (obtenido en este documento):

  Caché en modo usuario Caché en modo núcleo
Peticiones por segundo 1,394 15,416
TTFB / TTLB (mseg) 70.82 / 70.97 3.39 / 4.02
User Mode CPU % 76.57% 0.78%
Kernel Mode CPU % 22.69% 99.22%
Llamadas al sistema / Seg 20,11 2,101
Uso de la red (KB / Seg) 6,153 68,326
Cambios de contexto / Seg 2,621 6,261

¡Espectacular la diferencia! ¿no?

¿Significa eso que sólo con trasladar una aplicacón a IIS 6.0 ya va a sacar partido a la caché en modo núcleo?. Repeat after me: "Nooo, padre".

¿Cuando entra en acción la caché en modo núcleo?

En condiciones normales los archivos que estén asociados con el manejador de archivos estáticos de IIS (por ejemplo imágenes, hojas de estilo .css, etc..) se almacenarán en la caché de modo núcleo. Está claro que sólo esto ya ayudará bastante porque este tipo de contenidos se obtendrán con mayor rapidez desde el servidor, si bien muchos de ellos realmente ya se "cachean" en el cliente/navegador generalmente por lo que ni siquiera se realiza una llamada al servidor para obtenerlos en sucesivas ocasiones.

¿Y qué pasa con las páginas ASPX? ¿Llega con usar unadirectiva VarBy... o similar en la cabecera para que entre en juego la caché en modo núcleo?

Pues tampoco. Las páginas ASPX deben cumplir una serie de condiciones, a saber:

· Sólo funcionan con la directiva VaryByParam="None". Si usamos cualquier otra variante de VaryBy o si en VaryByparam establecemos algunos parémetros con los que variar la caché, ésta se hará en modo usuario.

· No puede haber parte "QueryString" en la URL, es decir, no puede haber una interrogación seguida de parámetros para la página.

· Se trata de una petición no autenticada. Es decir, sirve en páginas públicas pero no se cachean páginas para las que primeramente es necesaria una autorización para acceder.

· No se puede estar usando compresión dinámica de las respuestas.

· El tamaño total de la respuesta no puede superar los 256 Kb (que también le llega bien), ni tampoco ser cero (es decir, no devolver nada, lo cual tampoco tendría mucho sentido). Este tamño máximo se puede cambiar tocando la clave del registro: HKLM\SYSTEM\CurrentControlSet\Services\HTTP\Parameters\UriMaxUriBytes.

· No se puede usar un "pie de página" de los que se ajustan directamente en IIS (hace poco alguien me preguntó sobre esto y creo que fue en este blog).

· La petición se realiza a través del protocolo HTTP 1.0 o superior (esta es fácil de cumplir pues todos los navegadores modernos suelen usar 1.1).

· Hay una serie de encabezados que no pueden estar presentes en la petición:

· "Translate: f": que indica al servidor que no debe procesar la página sino devolver su código. Usado en WebDaV.

· "Expect: 100-Continue": cabecera de HTTP 1.1 para envío de datos de formularios en dos tiempos: primero se solicita la página y si el servidor responde con el código 100 se envían los datos codificados en Base64

· "Range" y "If-Range": cabeceras HTTP 1.1 que sirven para indicar al servidor que, en determinadas condiciones, devuelva la última versión de algo que hay en caché parcialmente en el cliente.

Es decir, que no siempre entra en juego esta caché de modo núcleo, en contra de lo que se puede leer en multitud de sitios de Internet que juzgaron a la ligera esta capacidad cuando apareción Windows Server 2003 e IIS 6.0.

¿Alguna cosa más que deba saber?

De hecho hay un montón de condiciones más que se deben cumplir en otras circunstancias y que impiden que actúe la caché en modo núcleo, así que no nos sorprendamos si no nos funciona muchas veces. Ahora bien, todas las importantes están descritas en el apartado anterior. De hecho la mayoría las podemos cumplir en condiciones normales sin mucho problema así que tengámoslas en cuenta para mejorar el rendimiento de nuestras aplicaciones ASP.NET. Si realmente te interesa conocerlas todas al detalle puedes consultar este artículo de la Knowledge Base de Microsoft cuyo título es bien claro: Reasons content is not cached by HTTP.sys in kernel.

Además ten en cuenta lo siguiente:

1.- Si se hace caché en modo usuario (la más común) se anulan los eventos de la petición excepto Application_BeginRequest y Application_EndRequest de global.asax.

2.- Si la caché se está haciendo en modo núcleo no salta ningún evento, ni siquiera los dos anteriores. Así que mucho ojo con esto si queremos hacer una especie de 'logging' propio de la aplicación.

Espero que encuentres todo esto útil.

Escrito por un humano, no por una IA