El primer paso para detectar la raiz del problema es identificar si proviene del manejo del view state de los web control que usamos, recordemos que esta propiedad se utiliza para mantener el estado (los caracteres, palabras, numeros etc. que ingresamos a nuestras cajas de texto por poner un ejemplo) entre invocaciones, esto es necesario debido a que como posiblemente sepa, el protocolo http esta basado en datagramas o paquetes que se envian a una maquina cliente determinada que si bien puede tener una referencia de session no mantiene una conexion permanente entre el cliente y el servidor, por tal motivo, la unica manera de recordar el contenido de nuestros inputs es atraves de esta 'memoria' de controles llamada view state. El problema con el view state se presenta cuando son tantos controles y tantas las cosas que estos tiene que recordar que simplemente la cadena que genera el view state llega a ser tan grande o mas que la propia pagina.
Existen algunos metodos para minimizar el impacto del view state, uno de ellos, el cual considero mas eficaz es el comprimir el view state, esto reduce significativamente el tamaño del stream enviado a los clientes pero implica sacrificar carga de procesamiento en el servidor, es decir, el servidor adicionalmente tendra que comprimir y administar en memoria el view state, puede hacer uso de esta tecnica cuando cuente con un servidor de gran capacidad.
Lo primero que tendriamos que hacer seria un objeto encargado de la compresion, en este caso lo llamaremos 'Compressor'
using System.IO;
using System.IO.Compression;
public static class Compressor {
public static byte[] Compress(byte[] data)
{
MemoryStream output = new MemoryStream();
GZipStream gzip = new GZipStream(output, CompressionMode.Compress, true);
gzip.Write(data, 0, data.Length);
gzip.Close();
return output.ToArray();
}
public static byte[] Decompress(byte[] data)
{
MemoryStream input = new MemoryStream();
input.Write(data, 0, data.Length);
input.Position = 0;
GZipStream gzip = new GZipStream(input, CompressionMode.Decompress, true);
MemoryStream output = new MemoryStream();
byte[] buff = new byte[64];
int read = -1;
read = gzip.Read(buff, 0, buff.Length);
while(read > 0) {
output.Write(buff, 0, read);
read = gzip.Read(buff, 0, buff.Length);
}
gzip.Close();
return output.ToArray();
}
}
Como podran notar, esta clase es muy simple, esta compuesta de 2 metodos estaticos uno para comprimir y otro para descomprimir, los cuales usaremos despues en nuestras paginas para 'invalidar' el comprotamiento por defecto de los metodos de persistencia de estado.
public partial class SomePage : System.Web.UI.Page
{
protected override object LoadPageStateFromPersistenceMedium()
{
string viewState = Request.Form["__VSTATE"];
byte[] bytes = Convert.FromBase64String(viewState);
bytes = Compressor.Decompress(bytes);
LosFormatter formatter = new LosFormatter();
return formatter.Deserialize(Convert.ToBase64String(bytes));
}
protected override void SavePageStateToPersistenceMedium(object viewState)
{
LosFormatter formatter = new LosFormatter();
StringWriter writer = new StringWriter();
formatter.Serialize(writer, viewState);
string viewStateString = writer.ToString();
byte[] bytes = Convert.FromBase64String(viewStateString);
bytes = Compressor.Compress(bytes);
ClientScript.RegisterHiddenField("__VSTATE", Convert.ToBase64String(bytes));
}
}
Ahora puede hacerlo mismo con cada pagina que necesite comprimir el view state, o mejor aun ... puede crear una clase base con estas implementaciones de compresion del view state y derivar las demas paginas de esta clase base.
Una nota final... gzip es el algoritmo de compresion que por defecto manejan navegadores convencionales como el Internet Explorer y Firefox, basado en esto continuaremos esta serie de post con un metodo de compresion un poco mas avanzado.