将ViewState移出页面?
我们正在尝试尽可能减轻页面加载量。由于ViewState有时可以放大多达100k的页面,所以我很想完全消除它。
我很想听听其他人将ViewState移至自定义提供程序的一些技巧。
也就是说,请注意以下几点:
- 我们每小时平均为200万唯一身份访问者提供服务。
- 因此,数据库读取一直是性能方面的严重问题,因此我不想将ViewState存储在数据库中。
- 我们还在负载均衡器后面,因此任何解决方案都必须与用户一起在每次回发之间从一台计算机跳到另一台计算机。
有想法吗?
解决方案
回答
我已经测试了许多方法来消除页面以及所有黑客与某些软件之间的视图状态负担,唯一真正可扩展的就是StrangeLoops As10000设备。透明,无需更改基础应用程序。
回答
如前所述,我过去曾使用该数据库存储ViewState。尽管这对我们有效,但每小时的独立访问者人数却接近200万。
我认为,无论使用StrangeLoop产品还是其他产品,硬件解决方案绝对是必经之路。
回答
由于典型的组织膨胀,要求新硬件接takes而来,而要求涉及我们现有设备的完整重新布线的硬件可能会受到工程部门的严重抵制。
我确实需要提出一个软件解决方案,因为那是我唯一可以控制的领域。
对企业来说是肯定的:(
回答
我试图找到我过去研究过的某些产品,这些产品的工作原理与StrangeLoops(但基于软件)类似,但它们似乎已经全部倒闭,这是我列表中唯一仍然存在的产品ScaleOut,但它们专用于会话状态缓存。
我知道向高级管理层出售硬件解决方案有多么困难,但是至少让管理层接受听取硬件销售代表的意见始终是一个好主意。我宁愿放置一些可以为我提供即时解决方案的硬件,因为它可以让我(或者给我一些时间)完成其他实际工作。
我知道,这确实很糟糕,但是替代方案是更改代码以进行优化,这可能比购买设备要花费更多。
如果我们找到其他基于软件的解决方案,请告诉我。
回答
我将查看是否可以提出一种利用当前状态服务器将viewstate包含在内存中的方法,我应该能够使用用户会话ID来保持机器之间的同步。
如果我想出一个好的解决方案,我将删除所有受IP保护的代码,并将其发布以供公众使用。
回答
哦,不,繁文tape节。好吧,这将是一个艰巨的任务。我们在这里提到使用状态服务器来提供会话状态。我们如何进行此设置?也许我们也可以在这里做类似的事情?
编辑
啊@乔纳森(Jonathan),我们在我输入此答案时发帖。我认为走这条路可能很有希望。一件事是,它肯定会占用大量内存。
@Mike我不认为将其存储在会话信息中是一个好主意,因为viewstate的内存密集性以及访问视图状态所需的次数。与视图状态相比,SessionState的访问频率要少得多。我将两者分开。
我认为最终的解决方案将是在客户端上存储ViewState的方式,也许值得一看。使用Google Gears,现在可以实现这一点。
回答
我们如何处理会话状态?有一个内置的"在会话状态中存储视图状态"提供程序。如果将会话状态存储在proc系统之外的某些快速系统中,则这可能是viewstate的最佳选择。
编辑:为此,将以下代码添加到Page类/全局页面基类中
protected override PageStatePersister PageStatePersister { get { return new SessionPageStatePersister(this); } }
同样,对于大的viewstate,这绝不是一个完美的(甚至是好的)解决方案。与往常一样,请尽可能减小视图状态的大小。但是,SessionPageStatePersister相对智能,并且避免为每个会话存储无数个视图状态,并且避免每个会话仅存储一个视图状态。
回答
我们是否考虑过是否真的需要所有视图状态?例如,如果我们从数据库填充数据网格,则默认情况下所有数据将保存在viewstate中。但是,如果网格仅用于显示数据,则不需要全部形式,因此不需要视图状态。
仅当通过回发与用户进行某些交互时,才需要viewstate,即使这样,实际的表单数据也可能足以重新创建视图。我们可以有选择地禁用页面上控件的viewstate。
如果我们实际上需要100K的viewstate,则我们有一个非常特殊的UI。如果将viewstate减少到绝对必要的程度,那么将viewstate保留在页面中可能是最简单,最具扩展性的。
回答
以下对我来说非常有效:
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页面本身中包含几行代码。如果将其与分布式缓存系统结合使用,由于viewstate很大且成本很高,则可以节省大量的面团。 Microsoft的速度也可能是添加此方法的好产品。如果我们确实使用它并节省了很多钱,尽管我很想提一下。另外,如果我们不确定任何事情,请告诉我,我可以亲自与我们联系。
这是我的代码的链接。连结文字
如果我们担心扩展,则可以保证将会话令牌用作唯一标识符或者将状态存储在会话中,这或者多或者少可以保证在Web场方案中工作。
回答
将viewstate存储在会话对象中,并使用分布式缓存或者状态服务存储与我们的服务器(例如Microsoft Velocity)分开的会话。
回答
我知道这有点陈旧,但是我已经在使用鱿鱼和ecap的开源"虚拟设备"上工作了几天,它可以:
1.)gzip
2.)处理SSL
3.)根据请求/响应用令牌替换viewstate
4.)用于对象缓存的内存缓存
无论如何,它看起来很有前途。基本上,它应该位于负载平衡器的前面,并且应该确实有助于提高客户端的性能。似乎也很难设置。
回答
不久前,我在博客上发布了解决方案,网址为http://www.adverseconditionals.com/2008/06/storing-viewstate-in-memcached-ultimate.html
这使我们可以通过使用自定义PageAdapter将ViewState提供程序更改为我们选择的一种,而不必更改每个Page类。我将ViewState存储在memcached中。回想起来,我认为将其存储在数据库或者磁盘中更好,我们可以非常快地填充memcached。它是一种非常低摩擦的解决方案。