We are trying to lighten our page load as much as possible. Since ViewState can sometimes swell up to 100k of the page, I'd love to completely eliminate it.
I'd love to hear some techniques other people have used to move ViewState to a custom provider.
That said, a few caveats:
Ideas?
How do you handle Session State? There is a built-in "store the viewstate in the session state" provider. If you are storing the session state in some fast, out of proc system, that might be the best option for the viewstate.
edit: to do this add the following code to the your Page classes / global page base class
protected override PageStatePersister PageStatePersister {
get { return new SessionPageStatePersister(this); }
}
Also... this is by no means a perfect (or even good) solution to a large viewstate. As always, minimize the size of the viewstate as much as possible. However, the SessionPageStatePersister is relatively intelligent and avoids storing an unbounded number of viewstates per session as well as avoids storing only a single viewstate per session.
I have tested many ways to remove the load of view state from the page and between all hacks and some software out there the only thing that it is truly scalable is the StrangeLoops As10000 appliance. Transparent, no need to change the underlying application.
As previously stated, I have used the database to store the ViewState in the past. Although this works for us, we don't come close to 2 million unique visitors per hour.
I think a hardware solution is definitely the way to go, whether using the StrangeLoop products or another product.
The following works quite well for me:
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));
}
You can always compress ViewState so you get the benefits of ViewState without so much bloat:
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();
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With