Перемещение ViewState со страницы? - PullRequest
10 голосов
/ 07 сентября 2008

Мы стараемся максимально облегчить загрузку нашей страницы. Поскольку ViewState иногда может увеличивать размер страницы до 100 КБ, я бы хотел полностью ее устранить.

Мне бы очень хотелось услышать о некоторых приемах, которые другие люди использовали для перехода ViewState к пользовательскому провайдеру.

Тем не менее, несколько предостережений:

  • Мы обслуживаем в среднем 2 миллиона уникальных посетителей в час.
  • Из-за этого чтение базы данных является серьезной проблемой в производительности, поэтому я не хочу хранить ViewState в базе данных.
  • Мы также поддерживаем балансировщик нагрузки, поэтому любое решение должно работать с тем, чтобы пользователь отскакивал от машины к машине при обратной передаче.

Идеи

Ответы [ 15 ]

5 голосов
/ 07 сентября 2008

Как вы обрабатываете состояние сеанса? Существует встроенный поставщик «сохранить состояние представления в состоянии сеанса». Если вы сохраняете состояние сеанса в какой-то быстрой, вне процедурной системе, это может быть лучшим вариантом для состояния представления.

edit: для этого добавьте следующий код в базовый класс вашей страницы Page / классы глобальной страницы

    protected override PageStatePersister PageStatePersister {
        get { return new SessionPageStatePersister(this); }
    }

Также ... это ни в коем случае не идеальное (или даже хорошее) решение для большого состояния обзора. Как всегда, максимально уменьшите размер viewstate. Тем не менее, SessionPageStatePersister является относительно интеллектуальным и избегает хранения неограниченного количества состояний просмотра за сеанс, а также избегает хранения только одного представления за сеанс.

2 голосов
/ 17 сентября 2008

У меня довольно хорошо работает следующее:

string vsid;

protected override object LoadPageStateFromPersistenceMedium()
{
  Pair vs = base.LoadPageStateFromPersistenceMedium() as Pair;
  vsid = vs.First as string;
  object result = Session[vsid];
  Session.Remove(vsid);
  return result;
}

protected override void SavePageStateToPersistenceMedium(object state)
{
  if (vsid == null)
  {
    vsid = Guid.NewGuid().ToString();
  }
  Session[vsid] = state;
  base.SavePageStateToPersistenceMedium(new Pair(vsid, null));
}
2 голосов
/ 07 сентября 2008

Как ранее было указано , я использовал базу данных для хранения ViewState в прошлом. Хотя это работает для нас, мы не приближаемся к 2 миллионам уникальных посетителей в час.

Я думаю, что аппаратное решение определенно подходит, будь то использование StrangeLoop или другого продукта.

2 голосов
/ 07 сентября 2008

Я протестировал много способов, чтобы убрать загрузку состояния просмотра со страницы, а также между всеми взломами и некоторым программным обеспечением, единственное, что действительно масштабируемо, это устройство StrangeLoops As10000 . Прозрачный, не нужно менять базовое приложение.

1 голос
/ 27 марта 2011

Вы всегда можете сжать ViewState, так что вы получите преимущества ViewState без большого количества наворотов:

public partial class _Default : 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));
  }

  // ...

}

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();
  }
}
0 голосов
/ 22 ноября 2011

Нет необходимости покупать или продавать что-либо, чтобы устранить вздутие живота. Просто нужно расширить HiddenFieldPageStatePersister. 100-200KB ViewState останется на сервере и вместо этого отправит на страницу только 62-байтовый токен.

Вот подробная статья о том, как это можно сделать:

http://ashishnangla.com/2011/07/21/reducing-size-of-viewstate-in-asp-net-webforms-by-writing-a-custom-viewstate-provider-pagestatepersister-part-12/

0 голосов
/ 12 августа 2009

Я писал об этом некоторое время назад - решение на http://www.adverseconditionals.com/2008/06/storing-viewstate-in-memcached-ultimate.html

Это позволяет вам сменить поставщика ViewState на любого по вашему выбору, не меняя каждый из классов вашей страницы, используя специальный PageAdapter. Я сохранил ViewState в memcached. Оглядываясь назад, я думаю, что лучше хранить его в базе данных или на диске - мы заполнили memcached очень быстро. Это решение с очень низким трением.

0 голосов
/ 29 июля 2009

Я знаю, что это немного устарело, но я пару дней работал над «виртуальным устройством» с открытым исходным кодом, используя squid и ecap для:

1.) Gzip 2.) справиться ссл 3.) заменить viewstate токеном по запросу / ответу 4.) memcache для кеширования объектов

В любом случае, это выглядит довольно многообещающе. в основном это будет сидеть перед балансировщиками нагрузки и должно реально помочь клиенту в производительности. Кажется, что не очень сложно настроить.

0 голосов
/ 11 января 2009

Сохранение состояния просмотра в объекте сеанса и использование распределенного кэша или службы состояний для хранения сеансов, отделенных от серверов we, таких как скорость микроуровней.

0 голосов
/ 07 ноября 2008

У меня может быть простое решение для вас в другом посте. Это простой класс для включения в ваше приложение и несколько строк кода на самой странице asp.net. Если вы объедините его с распределенной системой кэширования, вы можете сэкономить много теста, так как viewstate является большим и дорогостоящим. Скорость Microsoft может быть хорошим продуктом, чтобы присоединить этот метод тоже. Если вы используете его и сэкономите кучу денег, я бы хотел немного упомянуть об этом. Также, если вы не уверены ни в чем, дайте мне знать, и я могу поговорить с вами лично.

Вот ссылка на мой код. текст ссылки

Если вас интересует масштабирование, то использование маркера сеанса в качестве уникального идентификатора или сохранение состояния в сеансе более или менее гарантированно работает в сценарии веб-фермы.

...