阿不

用勤奋寻找未来

  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
  181 随笔 :: 0 文章 :: 2308 评论 :: 75 引用

前段时间由于程序出现了比较大的性能问题,视图(View)之间的跳转速度非常慢。通过Fiddler调试和分析,查找到是由于在视图(View)转换(PostBack)过程中,客户端给服务器端的发送字节数非常大,一般在30K以上,就相当于客户端每次都要给服务器上传大十K的数据量,这如果是比较好的网络环境下完全是可以忽略的,但是目前的网络环境确实还达不到这样的要求。详细请看《无刷新视图跳转的局限性》。针对这一情况,我的解决方案就是禁用页面的ViewState,只有这样才是最根本的解决办法。原本还想写一篇blog来好好批一下ViewState,当初想好的标题是“asp.net程序的性能杀手----ViewState”。现在看来,还好没写,要不还不被人批是“没有真正会用 asp.net 的人”?(尽管确实还没有真正全面认识asp.net)。

jillzhang的blog《给页面减减肥!》中给页面减肥的办法是对页面进行压缩。这确实是一种办法,特别是当在硬件环境允许的条件下,可以带来非常大的好处,一般体积都可以减小好几倍。减小页面体积还有一种办法,那就是禁用ViewState,两种方法并不是互斥的,而且我认为只有禁用ViewState后,页面压缩的效果才更明显的。因为ViewState的值本身就是一些相对紧凑的字符,而HTML代码则相对松散,(我也不是特别肯定这对压缩有必然的联系。)。最近一直在从事页面速度的优化方面的工作,所以很多平常不注意的细节,它所造成的性能影响在这时候就体现出来了。一般的页面(服务器控件比较多)如果禁用ViewState后,它的体积至少会减小一半。而且这一半的数据在很多情况都是没用的(特别是在不需要PostBack的情况下,简直就是累赘),如果这时候再加HTML压缩的话,那压缩比就不止3-5倍了。有一个页面正常的大小(禁用ViewState后)是101,730 byte ,压缩后变成了11,182 byte。说实话我也很惊讶这样的压缩比。通过这里可以看这组惊人数据。

那这一切是不是都是Asp.net的错呢?ViewState是不是就是“万恶之源”呢?是,也不是。为什么呢?首先我们要正确认识ViewState存在的意义,更多的情况下MS是为我们这些新手快速入门而考虑的。正因为有了ViewState,让我们开发B/S应用程序能够按照我们的正常的思维逻辑来进行。而屏蔽了在PostBack时,还要去初始化一堆的页面控件,给这个控件还原我们提交的请求值等等,想想这对于我们来说是多少复杂而麻烦的一项工作啊!而不是像我们现在这样,直接在PostBack事件取我们想要的控件的值这么简单。而默认情况下ViewState=true,也是在为初学者着想的,不至于让一个初学asp.net的同学在写postback事件时出现一些奇怪的错误而灰心丧气,提高门坎。一段个人的理解可能还不能让一些朋友看得很明白,关于ViewState的讨论已经很多了,但是最重要一点就是理解页面的执行生命周期。如果把下面这张图啃下去后你也许就会有深刻理解了。

 ASP.NET+Page+Life+Cycle(图大占篇幅。)

谈点有意义的吧?是禁还是用?决定因素有以下几点(个人理解):

1.你的目标应用环境。

这是最根本的,如果你的asp.net应用程序只在局域网(Intertrant)内应用的话,那非常棒,我们完全可以忽略ViewState存在的影响。

2.页面的性质。

如果你的页面是一种信息浏览的性质,而完全没有PostBack事件的话。这里的ViewState就完全是可以被消灭的。反之,如果页面中有PostBack事件,尽管只有一个,那你如果禁用了ViewState,都有可能产生不可预期的错误。

3.你对ViewState和页面事件的理解程度。

如果你很理解页面的生命周期和执行过程,那你完全可以根据需要来设置哪些控件需要打开ViewState,哪些控件可以禁用ViewState,做到按需使用,合理使用ViewState。达到性能的最优化。

4.开发人员的勤劳程度和外在因素。

如果你很勤劳,而且你也了解了ViewState的原理,你可以按需使用。但是如果你很懒,而且很多外在因素(团队其它成员的理解程度)你没无法控制的话,那就直接禁用页面的ViewState好了。当然前提是你必须知道如果去正确处理禁用ViewState后遗留下的问题,这些问题一般都是一些让人难以捉摸的东西。如果你都是一一的解决了这些问题的话,那对ViewState的感情就更深了。呵呵。

可以这么说ViewState是页面控件状态的一个副本,比如一个DropDownList控件,它在asp.net页面上要是以select HTML tag 来展现的,而这时在ViewState中还保存着它所有Item的副本。当我们在postback的时候为什么能够取到值呢?就是因为ViewState,它会在ProcessPostData(before Load)之前将这个副本还原成了DropDownList的Item了。然后在ProcessPostData方法中将表单提交的选择项设置为DropDownList的SelectedValue。以前这一过程我们无需参与。而当我们禁用ViewState后,我们就要手动去维护DropDownList回发情况下的Item初始化,利用Request.Params(或Request.Form)取得SelectedValue值等等,而这些工作有可能就要在Page_Load事件之前做了。

对于ViewState,有一句话说的很好,“鱼与熊掌不可兼得”,欢迎讨论。

补充:可能有以下一些因素让你会选择坚定不移的使用ViewState

1.你认为ViewState所以来的负面影响在我所能接受的范围之内。

2.通过对ViewState的一些处理,如改变ViewState的保存机制,压缩ViewState等,我们能够得到比较好的结果。

3.由于一些客户原因,如第三控件需要,设计需要必须使用ViewState的。

4.禁用ViewState带来更多的工作量,但是改善效果不理想。

等等,但是有一个原则,既要合理使用,也要理性判断,做到效果最优化。

阿不 http://hjf1223.cnblogs.com
posted on 2006-09-29 15:35 阿不 阅读(5945) 评论(30)  编辑 收藏 网摘

评论

Agree, sometimes view state could degrade performance dramatically.

I had a web page saving some config information in viewstate, and the page was extremely slow when doing postback. After discarding viewstate, it is much much faster.

By default, the viewstate is a hidden field of web page, that is why the size of page increase. .NET provides a way to save view state at server side, so you could still use view state without increasing the page size. All you need to do is override below two methods

SavePageStateToPersistenceMedium(object viewState)

LoadPageStateFromPersistenceMedium()

You could find more details about viewstate on the web.

  回复  引用    

#2楼 2006-09-29 15:51 Jeffrey Zhao      
不错的总结的啊。

补充一下,就是打开ViewState不光是传输体积上去了,打开以后序列化和反序列化ViewState也对于性能有影响。服务器需要额外的运算和存储。

另外就是说,在ViewState里虽然能够放任何serializable的东西,但是最好还是放些特定的类型,比如int和string等基础类型,还有Array,Collection,Pair,Triple等。它们在序列化时都经过了优化。而且有了Pair和Triple,保存ViewState应该足够用了。

  回复  引用  查看    

#3楼[楼主] 2006-09-29 15:56 阿不      
@Jeffrey Zhao
谢谢,是的,把序列化和反序化这方面的影响给忘记上去了。上面的侧重点在于内网和外网环境下的差别,而Serialize造成的性能问题与环境无关的。特别在进行文本序列化的时候会更慢。

  回复  引用  查看    

#4楼[楼主] 2006-09-29 15:59 阿不      
@liuzhuang
是的,在.NET 2.0当中,已经允许我们扩展ViewState的存放位置,还有就是进行ViewState压缩。所有这些手段都是有利弊的吧。

  回复  引用  查看    

#5楼 2006-09-29 16:18 aspnetx      
这个东西我就感觉和session或者application一样
不能滥用地

  回复  引用  查看    

#6楼 2006-09-29 16:19 henry      
使用者除知道有ViewState这个功能外,还必须了解ViewState处理的整个过程,什么情况使用ViewState会发生什么事情;这样才不会导致滥用。
一直觉得ViewState是个好东西,也见过有开发人员滥用后导致非常严重的后果。

  回复  引用  查看    

@阿不
Agree, there is no perfect solution. Only work around depending on particular situations. I just want to remind other users there is alternative since you did not metion this in your article.

  回复  引用    

#8楼 2006-09-29 16:31 Jeffrey Zhao      
@henry
其实ASP.NET好像一直被随意使用了,不管是ViewState,呵呵。

  回复  引用  查看    

#9楼[楼主] 2006-09-29 16:37 阿不      
@ Jeffrey Zhao
asp.net,包括.NET的很多东西都太方便了,以至于有大家不会去深究相关的影响,这也可能是别人说.NET写的程序比java慢的一个因素吧?呵呵。

  回复  引用  查看    

@阿不
True, it is much easier for a learner to write a simple application using .net without knowing too much. So even application works, there are many things need to be improved.

If a platform does too much for user, then user will become lazy sometimes.

By the way, let me introduce myself, my name is zhuang liu, I am working in a Telecom company in Manchester, UK. Nice to meet you here hope we could become friends. I am in my office now, so could not type chinese.


  回复  引用    

#11楼 2006-09-29 16:49 Jeffrey Zhao      
@阿不
是的,关键在于上手太快,就不愿深究。

  回复  引用  查看    

#12楼 2006-09-29 16:55 木野狐[匿名]
禁用 ViewState 可以说基本丧失了采用 ASP.NET 开发的一半优势,特别对于控件开发而言。基本上没有哪个第三方控件可以脱离 ViewState 而运作的。
ASP.NET 的优势就在于能够用 OO 的方式,控件化的方式去方便的处理复杂的编程逻辑,因此更适合做逻辑密集型程序。而不是普通的小网站。

如果禁用了 ViewState 来使用 ASP.NET, 那跟用 asp, php 有什么区别?甚至对于这种规模的应用 php 要方便多了。

  回复  引用    

#13楼[楼主] 2006-09-29 16:55 阿不      
@liuzhuang
谢谢。呵呵,我的E文不大好,没法用E文回复,不过勉强能看得懂你的回复,呵呵。
非常期待与你成为朋友。Nice to meet you too.hehe

  回复  引用  查看    

#14楼[楼主] 2006-09-29 17:00 阿不      
@木野狐[匿名]
你说的有道理,确实是这样的。如果从方便的角度,来说ViewState确实有它独有优势,但是我不同意去掉ViewState的asp.net就成了asp或php,ViewState并不应该成为区别他们的标准。
如果在逻辑密集型的程序当中,我相信它的应用环境肯定是有要求的,而不是普通的Internet网络,那这样的话,ViewState也是非常有必要使用的。而对网站而言,不管是大的还是小的,速度决定你的生命。

  回复  引用  查看    

#15楼 2006-09-29 17:02 Jeffrey Zhao      
@木野狐[匿名]
ASP.NET的模型以及思维方式高出ASP何止一点点,不同时代的了。

  回复  引用  查看    

#16楼 2006-09-29 17:05 aspnetx      
@liuzhuang
so I think, it doesn't mean dotnet do too much things for users(and even "lazy"),if one want to make a solution,not a simple project,these "lazy things" maybe helpless then.
and just as we can not tell which is easier to implement Design Pattern in .Net and J2EE.
just see what you are going to do.

  回复  引用  查看    

#17楼[楼主] 2006-09-29 17:11 阿不      
@ aspnetx
所以,还是回到一句老话,不管什么技术,关键在于精。

  回复  引用  查看    

@aspnetx
Agree, if you want to do real world project, no platform could do everything for you. There is no magic wand like Harry Porter's.

Nice to meet you, where are you from(I know you are in Beijing now)

  回复  引用    

#19楼[楼主] 2006-09-29 17:28 阿不      
@liuzhuang
如果有魔法的话,那要我们这些程序员干什么啊。呵呵
aspnetx come from 长春

  回复  引用  查看    

#20楼 2006-09-29 17:35 liu zhuang      
@阿不
Hehe, I am from Harbin, I have never been to FuJian(I think you from FuJian), but I tried FuJian FishBall(with meat inside), it is very nice, and bigger!

  回复  引用  查看    

#21楼 2006-09-29 18:37 小新0574      
一篇解释ViewState运行机制的一片好文章
http://weblogs.asp.net/infinitiesloop/archive/2006/08/03/Truly-Understanding-Viewstate.aspx">http://weblogs.asp.net/infinitiesloop/archive/2006/08/03/Truly-Understanding-Viewstate.aspx

有时间的话翻译给大家,不过可能没有时间。

BTW,manage viewstate on the server side is a good idea

  回复  引用  查看    

#22楼 2006-09-29 20:18 jillzhang      
怎么说呢?
性能ViewState是影响性能,和反射一样,有利必有弊,争论这个问题是争论先有鸡,还是先有蛋。
我以前也会直接将viewstate pass掉,因为这样最简单亚,也最有效,但是你在pass掉它的同时你也会有所失,而且代价不会太小,细想一下viewstate的原理,你会发现它是一个非常的设计,他类似于一个小小的cookie,但是生命周期仅仅限定于一个页面,cookie也是一直受到争论的东西,有人说他是web的一块小甜饼,也有人说它是定时炸弹,但无论如何,这个东西都是很好的设计思路,一个方案,无论你怎么设计,始终会有缺陷,关键是怎么弥补,一块洁白的玉,只因为上面有一丁点的斑点,就应该被丢弃么?显然不是这样的。
就像性能和扩展一样,这种是一种互相矛盾的东西。对于这样的事务,关键是把握一个度的问题。大家总是说reflection性能低,但是spring,hibernate这些现下都比较流行得技术却是冒天下之大不韪,当然不会傻到直接用,我的那篇文章dflyingchen第一个回复就是浪费服务器资源。的确浪费,压缩也只是其中一种解决方案,只不过是除了您的办法外的又一个可取的方法。另外,页面是可以压缩的,而ViewState也是可以压缩的。如果您原来有30K的ViewState,我可以将它压缩到10K以下,甚至更低。我的意思只是说不一定说viewstate有些缺点,那么就抛弃它,它毕竟有它的优点,更认真,也更有效的是取其所长,弃其所短。当然我不说压缩就是这样的,我只是希望有更多的可选方案罢了。

  回复  引用  查看    

#23楼 2006-09-29 20:29 aspnetx      
@liuzhuang
nonono
I am from NorthEast of China,Changchun City in Jilin
Glad to see you!
Everyone here try to make one's work to be Harry Porter's like,
to give our clients that feeling,I think,is what we shoule do in the following years.
and how you know I am from Beijing?IP address?
just as a friend upstairs said,hehe,I am Changchun native

  回复  引用  查看    

#24楼[楼主] 2006-09-29 23:12 阿不      
@liu zhuang
你说的是福州鱼丸吧?确实是福州最有名的小吃,很不错的。里面包的是鱼肉,煮熟了会很大的,如果有来福州的话一定要吃的。我目前是在福州,我是在福州读书,现在也在福州工作。不过我人是闽南的,来自漳州。

  回复  引用  查看    

#25楼[楼主] 2006-09-29 23:15 阿不      
@jillzhang
没错如果它是在我们的接受范畴之内,那完全是可以用的,也不能一棍子打死,所以这才有了我上面提出的几点要素?经过大家的讨论,可能还需用再加几点。不过我曾经也试过了直接压缩ViewState的方式,但是效果不明显,感觉ViewState不好压缩啊。序列化的时候好像已经做处理了?

  回复  引用  查看    

#26楼 2006-09-29 23:26 aspnetx      
也许博客园再早几年的话就会有这种话题

客观看待Session与Cookie对asp程序作用的影响

我想这是不同时代的不同话题吧

  回复  引用  查看    

#27楼 2008-01-15 15:56 邓林海      
页面压缩怎么整啊?
  回复  引用  查看    

#28楼[楼主] 2008-01-16 09:36 阿不      
@邓林海
页面压缩在园子里面有很多这样的文章。

  回复  引用  查看    

#29楼 2008-04-23 10:36 梦心[未注册用户]
So good!
Thanks everyone that replies the atricle for using of ViewState!
I think whether or not to use it is depend to you!

PS:It is my first time to reply English.I don't know whether there are some mistakes.hehe~~

  回复  引用    

#30楼 2008-07-01 03:15 廉毅      
--引用--------------------------------------------------
Jeffrey Zhao: @阿不
是的,关键在于上手太快,就不愿深究。
--------------------------------------------------------
也许再深究一下,你又会发现ViewState原来是个好东西

  回复  引用  查看    




发表评论

昵称: [登录] [注册]

主页:

邮箱:(仅博主可见)

评论内容:

  登录  注册

[使用Ctrl+Enter键快速提交评论]

0 518305




相关文章:

相关链接: