Перенести ViewState со страницы?

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

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

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

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

Идеи?

2 миллиона уникальных посетителей в час? Ух ты! Это биржа экспертов или какой-то (другой) сайт pr0n? ;-)

splattne 03.11.2008 18:21

pr0n точно :))))))) (шучу Джонатана)

Andrei Rînea 05.01.2009 04:00

100к для ViewState? Это не может быть нормально.

Andrei Rînea 05.01.2009 04:01

@Andrei: просто добавьте GridView на страницу с дюжиной столбцов, включенными редактированием / удалением / сортировкой / разбиением по страницам и несколькими сотнями строк на странице. Для ViewState нет ничего необычного в том, что он очень легко достигает 100 КБ.

saille 27.03.2011 06:07

@saille: Да, согласен. Что я имел в виду: этого следует избегать (100k ViewState).

Andrei Rînea 28.03.2011 15:12
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
10
5
3 549
15

Ответы 15

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

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

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

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

Мне действительно нужно придумать программное решение, потому что это единственный мир, который я могу контролировать.

Ура для предприятия :(

Я попытался найти некоторые из продуктов, которые я исследовал в прошлом, которые работают так же, как Странные петли (но основаны на программном обеспечении). Похоже, они полностью разорились, единственное, что все еще находится в моем списке, - это Уменьшить масштаб, но они специализируются на кэшировании состояния сеанса.

Я понимаю, насколько сложно продавать аппаратные решения высшему руководству, но всегда полезно, по крайней мере, убедить руководство согласиться выслушать представителя отдела продаж оборудования. Я скорее поставлю какое-то оборудование, которое предоставит мне немедленное решение, потому что оно позволяет мне (или дает мне время) выполнить другую реальную работу.

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

Сообщите мне, если найдете другое программное решение.

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

Если я найду хорошее решение, я удалю весь код, защищенный IP, и выложу его для всеобщего использования.

Есть ли конкретная причина, по которой вы не используете встроенный SessionPageStatePersister? msdn.microsoft.com/en-us/library/…

Mike 07.09.2008 10:47

О нет, Красная лента. Что ж, это будет трудная задача. Вы упомянули здесь, что вы используете сервер состояний для обслуживания состояния сеанса. Как у вас такая установка? Может, и здесь можно сделать нечто подобное?

Редактировать

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

@Майк Я не думаю, что сохранение его в информации о сеансе будет хорошей идеей из-за интенсивного использования памяти в состоянии просмотра, а также из-за того, сколько раз вам нужно будет получить доступ к состоянию просмотра. К SessionState обращаются гораздо реже, чем к состоянию просмотра. Я бы держал их отдельно.

Я думаю, что окончательным решением было бы каким-то образом сохранить ViewState на клиенте, и, возможно, на него стоит обратить внимание. С Google Gears это возможно сейчас.

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

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

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

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

Я использовал это в ключевом производственном приложении на странице, на которой было всего несколько пользователей. Это был огромный успех (после попытки многих неудачных альтернатив) ... ОДНАКО, он не масштабируется. Убедитесь, что вы посчитали это!

Brian MacKay 25.11.2008 03:11

Это то, что я искал.

Przemek 24.01.2009 11:18

Лучше использовать настраиваемый PageAdapter, поскольку вам не нужно наследовать свои страницы от базового класса.

mcintyre321 12.08.2009 19:29

Вы думали, действительно ли вы необходимость все это состояние просмотра? Например, если вы заполняете сетку данных из базы данных, все данные по умолчанию будут сохранены в состоянии просмотра. Однако, если сетка предназначена только для представления данных, вам не нужна вся форма и, следовательно, состояние просмотра.

Viewstate нужен только тогда, когда есть какое-то взаимодействие с пользователем посредством обратной передачи, и даже тогда фактических данных формы может быть достаточно для воссоздания представления. Вы можете выборочно отключить состояние просмотра для элементов управления на странице.

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

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

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));
}

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

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

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

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

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

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

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

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

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

Вы всегда можете сжать 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();
  }
}

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

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

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

Другие вопросы по теме