Categorias

Compactando ViewState no ASP.NET

Antes de iniciarmos esse artigo, irei explicar de forma rápida o que seria um ViewState.

“A grosso modo”, ViewState é uma string que armazena informações sobre o estado da página em um campo oculto dentro da mesma.

Bom, acho que agora já podemos iniciar este artigo! 🙂

Geralmente quanto maior a complexibilidade de uma página, maior será as informações armazenadas em seu ViewState. Chegando a um ponto em que o ViewState prejudica o carregamento de nossa página.

Antes a solução seria eliminar o ViewState, mas agora poderemos partir para outra solução.

Ao usarmos a lib GZipStream podemos compactar o viewstate e com isso reduzir em 45% o tamanho do ViewState.

Veremos a partir de agora como compactar e descompactar dados na memória.

Nossa Classe de compactação usará System.IO.Compression e System.IO;

Criaremos em nossa classe dois metodos estáticos:

public static byte[] CompactarViewState(byte[] bytes)

e

public static byte[] DescompactarViewState(byte[] bytes)

Para realmente compactarmos nosso ViewState, teremos que dar um override nos seguintes métodos em seu WEBFORM:

LoadPageStateFromPersistenceMedium e SavePageStateToPersistenceMedium

Nossa classe de compactação ficará assim:

public class ClassCompactarViewState
{

      public ClassCompactarViewState()

      {

            //

            // TODO: Add constructor logic here

            //

      }

 public static byte[] CompactarViewState(byte[] bytes)
 {

        MemoryStream MSsaida = new MemoryStream();
        GZipStream gzip = new GZipStream(MSsaida, CompressionMode.Compress, true);
        gzip.Write(bytes, 0, bytes.Length);
        gzip.Close();

        return MSsaida.ToArray();
    }

    public static byte[] DescompactarViewState(byte[] bytes)
    {
        MemoryStream MSentrada = new MemoryStream();
        MSentrada.Write(bytes, 0, bytes.Length);
        MSentrada.Position = 0;
        GZipStream gzip = new GZipStream(MSentrada,
                          CompressionMode.Decompress, true);

        MemoryStream MSsaida = new MemoryStream();

        byte[] buffer = new byte[64];

        int leitura = -1;

        leitura = gzip.Read(buffer, 0, buffer.Length);

        while (leitura > 0)

        {

            MSsaida.Write(buffer, 0, leitura);

            leitura = gzip.Read(buffer, 0, buffer.Length);

        }

        gzip.Close();

        return MSsaida.ToArray();

    }

 

}

WebForm.aspx

Abaixo de seu Page_Load adicione o código abaixo:

protected override object LoadPageStateFromPersistenceMedium()
   {
        string viewState = Request.Form["__VSTATE"];
        byte[] bytes = Convert.FromBase64String(viewState);
      // DESCOMPACTAR VIEWSTATE   
        bytes = ClassCompactarViewState.DescompactarViewState(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);

// COMPACTAR VIEWSTATE

        bytes = ClassCompactarViewState.CompactarViewState(bytes);
        ClientScript.RegisterHiddenField("__VSTATE", Convert.ToBase64String(bytes));
    }

Ao testar essa classe em uma página que gera pouca informação no ViewState, não será notado nenhuma diferença, mas caso seja alocado em uma página mais complexa a diferença será muito significativa.