呵呵,我最在乎的就是这个尊重,尊重,还是尊重。我也说过类似于你说过的话去说别人,一般是我真确认对方有明显的倾向性,或者是对方有商业意图;即使这样,最近我说的也比以前少多了,这给别人带来愉快的同时,很重要的是让自己也能避免不愉快。另外一点是,无论是技术,还是其他网上的讨论,或者是一些其他方面的博客什么的,很常出现的就是臆测其它人的水平如何,比如说大多数人都怎么怎么样,把目标读者当成了什么什么样。这个我特别反感,因为实在是无利于讨论,如果每个人尽量把其他人都当成自己师傅一个级别,比较能够让大家顺利进行下去。技术以外的不讨论了。

你用FireBug看看Atlas的真正传输量吧,如果只有核心的话,大概是24KB,如果加上UpdatePanel所需的,大概是32KB。但实际上即使核心还能精简。比如PageFlakes精简过的Atlas核心文件,不超过18KB,而PageFlakes最大的JS,全都是与Atlas无关的,它自己业务需求的JS,相比全部JS的大小,这18KB哪怕32KB,无关痛痒。说到PageFlakes,对于其作者Omar来说,这点JS小意思了,就是我上贴所说,其实你自己做,随着需求的增加,也要做这些东西,所以不如直接拿来,如果水平达到像你一样,也绝对不存在什么扩展性、维护性的问题,恰恰相反,由于JS的特性,微软的分类和扩展方式在很多时候仅是一个整理事物的指导。

再说回ASP.NET本身,一些问题首先澄清一下,以你的水平,页面生命周期一定是不在话下了,大多数控件在打开ViewState的情况下,实际上相同的数据不需要第二次取数据库;当然这导致ViewState过大,问题是ViewState也不见得一定要传输到客户端。(以上这些话是给不了解生命周期的人看的,防止别人对你的话断章取义。)关键的问题是怎么灵活应用上,在我看来,所有的问题都是咱们如何认识事物的问题,该不该维护状态,用什么方式怎么维护状态。这个对事物的认识是普遍的,比如现在Java社区讨论高深OO知识的很多,甚至更超前的也大把抓,但诸如“两个类有相互联系,但到底是A has B合理还是B has A合理”这样的问题,我想都不是每个人都很清楚的。问题是就这种简单的认识,对日后的扩展、维护,带来的影响要远远大于咱们是不是能把23种设计模式用全。

不过,即使我的论调有一半是老赵说的,不是东西的问题、是你怎么用的问题,在ASP.NET的结构上,我比你还激进,我对目前的状况看法是,对开发者的限制、负担大于帮助。不过ASP.NET设计师的出发点是好的,每一个概念在目前的业界的认识水平上可以说也是绝对正确的,主要问题是组合的不正确;这种不正确一方面来自于很多东西是新的他们在一些方面也欠缺经验,另一方面,他们的工作量不足以用正确的方式去组织,因为组织本身要耗费的精力远远大于实现一个Web框架。但只要微软的人、SUN的人没一直睡觉,总会进步的。

效率问题,你可以参照php5和php4大概几倍的差距。到底什么时候效率重要?效率重要到什么程度? 我想这帮子大师未必永远正确一贯正确,但他们做出的决定有时候可以作为一种参考。比如博客园的.Text吧,比你说的那种情况按理说效率还低,也承载了这么多人。影响效率的有多种因素,改进效率也可以从不同的点切入。一个简单的输出20行Html代码方法,在.NET里确实很可能一个调一个,叠了甚至好几十层,这个很可怕,但很多时候并非不能接受的,因为在其他方面的益处抵消了这种开销。

不知道你做过压力测试没有,静态文件在PD 2.8G,普通SATA硬盘上大概是1500个请求每秒,一个复杂的页面如果没有OutputCache大概是300多个,加上OutputCache就是1000个不到。而且我们还有静态化的手段,提到静态化,又得考虑静态化的方式和时机。我说这些东西是表明一点,效率是一个很大的问题,如果联系起来看就变得一环扣一环,不是简简单单考虑我程序执行快慢即可的。可每考虑一个环节,又引出其它问题。但综观所有解决效率问题的手段,最有效的永远也论不到页面执行效率上,因为可改进的方式,根本性的方式太多了。比如我举个反面教材,象DELL的开发人员应该不至于水平太差,他们的网站也运行了很多年了,你看他们的页面,看不到ViewState,看不到传统的由大大小小一堆INamingContainer起的名字,可不照样慢?

我有一个基调就是,先尽可能的学习,而不是着急否定现有的东西,在自己生涯的很早的阶段就着急怎么样,志要立,但过于快速总是不能长好,中国技术人员前进的道路,实际上就是柏拉图讲的那个挑最大的麦穗的故事,前1/3看,中间1/3验证,在最后1/3,我们就能更有把握的把事情做成。说到这里,觉得我说的都是反对的话,其实不是这样,你的工作和努力非常的有意义,如果没有你这样热情的人和老赵这样的宣讲者,国内的进步肯定要变慢。我只是尽我所能的多那出些“他山之石”,希望对你能有点帮助。

你的控件动态加载部分,能不能说个大概的步骤? 我在这方面过去也做过一些工作,所以感兴趣是不是有所不同,另外也许我能提供一些经验 :)。

@Jeffrey Zhao
先说说您对UpdatePanel的理解吧,您对UpdatePanel的理解相当正确,通过我对源码的分析,的确发现UpdatePanel设计是这样的。既然您和我的理解都一样,那么也不甚么值得讨论的事情,只不过作为业余爱好者的我对效率有一种固执的执著,我在此谈谈我的看法。首先针对单个页面来说,一个PostBack将整个页面都回传了过去,这个PostBack传到服务器的数据量虽然有多余,但是肯定不是太大多,如果ViewState控制的好地话,一般不会超过2K(排除发表文章或回复这种性质),这个数据虽然我不太满意(实际的可能不到800Byte),但是是一种全能的解决方式,没有什么太值得挑剔的地方。问题又回到了服务器端,UpdatePanel渲染的是所有的组件,拿您的这个Blog做个例子,如果我发一篇回复,很显然我唯一需要更新的是这个评论一块,但是比如您的文章、您左边的最新文章、最新回复……这些肯定都是使用诸如Repeater控件将其表现出来的,而这些表现层级有可能又放到了一个User Defined Component里面了,实际上您可以发现这些都是不需要渲染的,既然渲染了,那么UpdatePanel肯定就做的不够好,实际上我设计的UpdatePanel就能很成功的避免此问题,整个页面只渲染需要更新的部分。当然设计人员如果做得好的话,完全可以实现动态加载组件,这样一来的话前面的问题也就不算问题了,因为组件根本没有加载。

@Jeffrey Zhao & @怪怪
另外就是我说到的桌面化的问题。您的Blog只有在回帖的时候能做到无刷新,其它的地方都需要刷新,这谈不上是桌面化,是目前的UpdatePanel不能做到,还是设计本身的问题?相信以您的水平应该早有对策。我开发过桌面Blog和桌面论坛,所要实现的就是完全的无刷新,无论从什么地方进入。下面我就来提提进入桌面开发后所面对的问题。一旦进入桌面开发,所有的页面必须整合到一个页面,这个是必须的,那么所有的页面势必都只能有一种结果,变成User Defined Component,再剩下的问题就是:如何将所有的User Difined Component 整合到一个页面?最简单,也最合实际的做法是将所有的User Defined Component拖入到一个Default.aspx里面,然后根据需要将需要输出的渲染输出,不需要渲染的依旧渲染,只是不输出,不知道我这样说您能不能理解。那么问题也来了,稍微大一点的系统,就拿这个Blog来说,原本在许多不同的Page都有各自的ViewState,都有各自的TextBox,分散在不同的Page里面,它们的回传量不算什么,但是如果将其全部放到一个页面里,这个回传量会递增,尤其对于设计把握不好的人来说就相当痛苦,因为速度不仅没有变快,反而变慢。这样来说的话,我的感觉是还不如不要刷新,并且以往的设计对于松散耦合要做的更好一些。但是这样说是不是桌面化就没有意义了呢?不是,问题又回到了开发者身上,需要开发者对ASP.NET生命周期机制、ViewState实现机制、事件回传机制、状态维护机制、控件渲染机制……都有一个比较详细的了解,才能突破ASP.NET 本身的限制。那么问题虽然又都回到了开发者的身上,但是UpdatePanel是不是又没有责任了呢?我的答案是:UpdatePanel大有可为。很显然对于提交回复,UpdatePanel需要做的事情只有一个:渲染回复Repeater,其余的通通丢掉。对于追求效率的我来说,这个很显然需要更值得深入。

@Jeffrey Zhao
“扩充性、维护性”,这个先赞同您的说法,“与Javascript语言本身无关”,但是需要从另一个层面来考虑。以往的设计是没有考虑将页面整合到一起的,但是当考虑到桌面化的时候,问题出现了,Ajax影响了原先的设计模式的一些地方,不知道我这个说法您赞不赞同?如果您不赞同,下面的观点也就没有太大必要了。既然影响到了以往的设计模式的一些地方,就不能说对“扩充性、维护性”没有影响了。因为很大程度上,我们的代码开始依赖于ASP.NET Ajax提供的控件库。如果当您的页面发生变化,或者说影响事件的方式发生改变,我想虽然微软的控件库封装的不错,但始终都会有一种依赖性。至于我所说的“逻辑和代码可以全部放置到表现层”,这个只是一个结论,我看过一个微软官方的例子,但没有接触很多,我并没有就此说明我们的开发只需要放到表现层,我显然很反对这种做法。


@Jeffrey Zhao
基于对上篇回复我对Javascript语句的理解,下面我针对您这次的话语来做个补充。我对Javascript语言本身没什么偏见,事实上,我想当喜欢Javascript,它相当的灵活,其灵活度要超越我所学过的任何计算机语言,但是同时您也应该有所体悟:Javascript不是不能做大型开发,只是不太适合做大型开发。Javascript多有的对象全部是一个Function,同时Function里面可以有任何多个Function,这样的灵活度与它的设计初衷有关系,可以发现Javascript不太适合做继承、不太适合封装、不太适合归类。至于ASP.NET Ajax将其变得C#化,居然出现了命名空间、类继承这种功能,我的感觉是对Javascript语言本身的糟踏,个人观点,完全不必理会。如果说要做实际开发的话,Ajax有很大的优势,相对于Flex来说还算比较小。但是我研究过的大型项目里面,所有的Menu、Tree、DataGrid……之类的东西全部都用Javascript去实现,只有一种体会:麻烦,相当的麻烦。开发周期比较长,但是我更喜欢使用Flex来开发,虽然最终生成的swf文件有300多K,但是开发周期短,速度快,并且MVC模式在这里面完全适用,老板和客户的满意度也相当高。当然如果考虑到面向用户、适用范围的话,另当别论,这可能要激起Flex、Flash VS Ajax的大战了,然后又激起WPF和 VS Apollo的大战了……呵呵。

@怪怪
哎呀,对于我上次的发言,我只有一个词来形容“惭愧”,我明白的,“尊重”,这堂课,我会记住您的,谢谢。我测试过Atlas的传输量的,因而才会提出UpdatePanel做的不够好。24K的确不太大,正如我上面所说的,如果要一个网站完全的桌面化的话,问题就大了。如果您用FireBug看看我的Blog的传输量的话(注意,我在这不是要标榜我的Blog系统,只是觉得有个例子更具有说服力一点),您会发现PostBack到服务器端的不会超过1K(排除回复的可能性),然后从服务器端传到客户端的一般不会超过10K(除非文章比较大)。当然我并不说对于一个像ASP.NET Ajax这样的大型框架,传个32K不可取,只是作为追求者,我们能做的更多。还有就是在客户端的代码量,这个数目相当“可观”,您做过相关开发,这个“可观”的数字我想不会不给与理睬。您应该查看过我Blog的一些Javascript代码,的确有上20K,但这些代码没有一个Byte是需要回传的,请您理解这点。上面的核心Ajax只有不到10K,剩下的上10K是我自己开发的在现编辑器所使用需要的,还有就是一些动态验证所需要的,并不是您所理解的需要回传的代码。

“关键的问题是怎么灵活应用上,在我看来,所有的问题都是咱们如何认识事物的问题,该不该维护状态,用什么方式怎么维护状态”这句话说得太好了!我没有任何反驳的理由,对状态的理解完全在个人。说实话啊,我除了学习过Flash里面的MVC设计模式之外,然后看过一个XMLChina这个论坛的设计模式之外,我对设计模式几乎是个“门外汉”,对您所说的23种设计模式,我倒是被吓出了一身冷汗,居然那么多!呵呵,不过在实际开发的过程中,我能发现不同的代码应该有不同的放置地方,很快我发现如果放置的地方对了,那么代码将会变得很“艺术化”(请允许我使用这个词),并且代码量急剧地减少,最后是发现居然能很好的扩展和维护,这个与其说是我的预期效果,倒不如说是我的意外收获,当时我唯一的目的是为了减少代码量。我适用以下几个层次:“DataAccess,DataRules,DataExcute,DataInstance,DataFramework,DataShow”,然后对所有数据的操作,只有一种情况,那就是单个或多个,于是每个层次下又对应一个“Single”和“Multi”层次(以上的说法应该很不专业,这些词也是我自己胡编乱造的,加上篇幅关系,我没办法让大家理解)。然而我很快也发现,这种方式能很快地融入到我的所有开发中来,并且能很好的解决我实际开发中的所有问题。啊。。。不好意思,说走题了,说到这,我稍微有点兴奋了。。。回到主题上。

至于效率问题,我明白您所说的意思,只是我觉得在我们所能及的地方,能将Pefermence做到最优,为什么不做呢?如果在不改变我的设计体系的情况下,我会优先考虑效率,甚至乐此不疲,虽然我也赞同一种说法“随着硬件的发展,效率已经不是我们太值得关心的地方”,但是怎么说呢?我想我对我所开发的东西不是当作一个做完即扔的弃婴,而是一个充满生命活力的孩子,我喜欢看着我的孩子能健康快乐的成长,而没有瑕疵。您的观点我很赞同,我只是提出另一种思想而已,在现代的IT界,据我所知,很多老板需要的不是有思想的程序员,而是编码的机器,尤其是在中国,大部分老板并不懂代码。这算是对这种老板的一种“回敬”吧,也算是对作为程序员的一种“庇护”。当然很可能,实际的生产过程中,利益往往大于思想。不过作为开发人员的我,在同一个项目中,我不关心别人做的怎么样,对于我负责的部分,我尽己所能,也算是问心无愧。

您其余的观点我都相当的赞同,都说到了点子上,我没什么好说的,只是我所希望的是,能更理性的、站在更多的立场上看待一件事,势必要比单纯的宣传要好的多。

至于关于动态加载组件的方式,我这个也一时半会说不明白,也解释不清楚,在加上时间的关系,我可能要放在以后的时间里在我的Blog上仔细阐明了。


@Jeffrey Zhao & @怪怪 & Everyone
最后我想说的是关于ASP.NET Ajax中的一些问题,这些问题影响到它本身的生存问题和发展。

首先是浏览器的前进和后退功能,受限于UpdatePanel本身的回传的缘故,ASP.NET Ajax本身没办法做到支持浏览器前进和后退的功能。对于一个桌面化的网站来说,或者说对于任何一个软件项目来说,不能前进和后退,这是个相当大的问题,如果解决不了,这是个很严重的问题,在我的Blog里面,如果您使用IE或以IE为核心的浏览器的时候,会发现支持前进和后退的功能的,并且没有任何限制(呵呵,不好意思,再次申明我不是标榜我的blog,对于已有的Ajax框架,我实际上做过许多深入的研究,我知道这些Ajax框架存在什么样的问题)。

其次,是关于灵活性的问题,我之所以说UpdatePanel不够灵活,不知您有没有考虑以下几个问题。1.随着桌面化方向的发展,势必在一个页面上会有多个UpdatePanel,同时在一个页面的User Defined Component 里面也可能存在很多个UpdatePanel,很多情况下,往往一个事件被触发,只需要Response是一个UpdatePanle里面的数据,而不是所有的数据,但是实际情况下,ASP.NET Ajax 会Response所有的UpdatePanel里面的数据,这是不是要被解决的问题呢,如何控制。2.如果能控制,我又该如何使得User Defined Component里面的UpdatePanel事件来触发页面上的另一个UpdatePanel的事件响应,从而使得其里面的数据得以更新?

最后,对于譬如“在线编辑器”这样类似的组件,它们所生成的HTML和javascript代码都比较大,我显然很希望在进入首页的时候就讷能生成这些代码,只不过加一个“display:none",然后在进入某一篇文章的时候,将“display”设置成“inline”。而不是每次进入一篇文章的时候都需要加载相同的代码,这个ASP.NET Ajax可能又欠缺考虑了吧。不知各位在实际开发过程中,有没有深入去了解这些问题,这些实际上是我在桌面化应用当中所遇到的很大的问题,当然这些问题我都以我的方式解决了。

@Bing
啊,写太多了,我回不过来,我就说一些地方。

首先就是:我还是这么说,ASP.NET AJAX我觉得它更强调的是开发效率(尤其是UpdatePanel),而使用上得性能,因为本身就需要编写大量代码,加上优秀的程序开发人员,所以自然有一套别的方法来开发,这样的开发成本是比较大的。而ASP.NET AJAX将客户端进行各种扩展,这也是为了开发效率考虑的,这个框架的构造的各种模型都能非常方便地辅助开发,这就是它的作用。如果没有这些扩展,我相信JS的使用还是会随着代码量的增加可维护性直线下降。我认为这样的扩展不是糟践了JavaScript,它给JavaScript提供了新的使用方式,而且完全不影响JavaScript的灵活性。我觉得两者配合的很好。

至于您提到的Cnblog方面传输了太大量的数据,为什么呢?因为我相信只是使用一个UpdatePanel将一个Repeater包含了起来,这的特点还是一个:方便,快捷,AJAX效果(当然效果一般)立马见效。

至于JavaScript开发控件的复杂性,的确的确,很复杂。这也就是为什么世界上会出现那么多封装好的组件了,它们的初衷,就是将这些复杂的劳动一次做完,然后可以让别人很方便地重复使用。至于效果如何,个人认为还是可以接受的,虽然自定义程度高的组件的确还不多。

还有前进和后退功能,其实同时支持IE和FireFox的做法由来已久,我记得我也写过这么一片文章在Blog里,但是我觉得封装的不太优雅,但是方向性是正确的,效果也是有的。而至于针对UpdatePanel的前进后退,我想我有空也会开发一个组件为它提供这个功能——而且支持Bookmark,发现您的Blog虽然能够前进后退但是还不能bookmark,我觉得您可以把它一并放入todo list。:)

至于您说的UpdatePanel只能回传所有的UserComponent的数据……不知道您为什么这么说,UpdatePanel的确可以只是回传需要的数据啊。至于最后一个在线编辑器的例子,我不知道这和ASP.NET AJAX有什么关系。

不过,您的一句话让我觉得很振奋啊!“艺术性”,真好,呵呵。:)
@sxhoho
你都说得出关键问题了就不是初学者了,这个问题我稍微接触过一点,替老赵说说。进度条的问题,实际上不是ASP.NET的问题,是IIS的问题,IIS对上传的内容,会一次读取,再交给ASP.NET,这是导致进度条不能实现的原因。但实际上IIS接收的内容也并非完全不可控的。你可以实现一个IHttpModule,获取HttpWorkerRequest,然后做你想做的事。

细的我就不说了,IIS 5/6下这可以说是唯一的解决办法,你可以沿这条路走下去,老赵有很多自己的事,别人也是,恐怕不要希望别人都给弄好。还是我那句话,如果不着急,几个月之内我会实现几个这种帮助大家的控件,比如对WebPart兼容Atlas的Workaround,和这个,但什么时候有时间就不确定了 :P。另外我记得codeproject上有类似的例子你可以去查一查。
@Bing
哈哈你和我一样,我就是被老赵引出来的,你不也是? 但我有一点和你不一样,即使我不说话我也总受外部世界的影响,所以看法变得很快 :P。

我指的传输是说JS的传输,你说的回发,UpdatePanel方面想必你和老赵谈过,你俩比我清楚。我自己是不用UpdatePanel的。另外,一个站只有一个页面,这个我也琢磨过,PageFlakes也是,但是照样用了Atlas的核心部分作为基础,因为你所抨击的在很多方面都是事实,但那只是UpdatePanel,而并非Atlas的核心。回发的过程,如果仅用WebService的方式,绝非达到你说的那种夸张的情况。另外UpdatePanel服务器端的渲染问题确实可怕,所以我也是同意你的。我表达的意思是,用Atlas的同时,完全可以避免使用UpdatePanel和其它的影响效率的方式,所以Atlas并不如你的感觉是一个鸡肋。

最后一个为什么要使用一个流行框架,因为大家都在用,比如说这个框架存在问题A,我开始应用的时候不知道,这就是一个隐患,但是我可以跟踪别人的言论,从而及早发现这个隐患并排出。而我自己写这么一套东西,即使不费劲,但是由于用的人少,隐患并非是不存在了(除非我自信所有的事我都知道),而是不可能被提早发现。前一段时间AJAXControlToolkit的DragDropManager出现一个BUG,而这个Bug实际上是Atlas核心的Bug,而这个Bug在未来肯定会影响到我,因为社区提出来,我自然知道什么情况下我能碰到,它是因为什么产生的。但假设另外一种情况,我用的是自己的代码,就需要花大量时间找出因为所以,然后结果它。

比如前进后退,在我看来只是一个小问题,决定不了我使用谁这样的大事。因为大家都有这种需要,肯定会有人解决,你解决了我使,我解决了他使,这就是你所说的跟风的另一面,它将大量的节约我的时间。

不多说了,每次我总是起头吵架,把老赵这里搅得一团糟,再次致歉了 :) 。