为WebForms说几句话,以及一些ASP.NET开发上的经验(1)

简介:
记得数年前,当ASP.NET刚出现时,天下间Web开发框架中似乎出现了一个“巨人”,WebForms这种似乎人人都能掌握的开发框架几乎瞬间流行起来。如果谁还在用传统ASP这种控制与表现混合的开发方式,似乎立即变得低俗了许多。于是乎许许多多人都学会了拖控件+绑定的方式,“Web开发人员”也越来越多,一片红火,好不热闹。
  风水轮流转,不知从什么时候开始Rails框架随着RoR忽的流行了开来,.NET社区也出现了Monorail,批判WebForms声音也慢慢多了起来。如今微软自己也推出了基于ASP.NET平台的MVC框架,很多WebForms的反对者似乎更加自信了:连微软自己都抛弃了WebForms,证明WebForms的确该退出历史舞台了,也听到了一些类似于“WebForms不适合Web开发已经是公认的事实”这样“无比肯定”的话。先不说微软推出MVC到底是不是意味着它抛弃了WebForms,单从那些MVC追捧者们“念念不忘”的WebForms的缺点上来看,我认为他们大部分只是在“跟风”,就和当年许许多多人追捧WebForms一样。
  不过我必须承认,我对ASP.NET MVC的了解仅限于 Scott Gu博客上所写的内容,至今还没有下载过ASP.NET 3.5 Extensions CTP。而对于RoR和Monorail也仅限于一些资料和示例,从来没有写过一行代码。按照我的“标准”,我自己是没有资格评论MVC框架的优劣的。不过我还是想写这篇文章,因为我只会WebForms平反,而不会“贬低”MVC框架;我只是想证明WebForms的那些缺点到底真的是缺点,还是开发人员自身没有好好利用起这把利器。因此我将会根据我的经验,一一回应对WebForms比较常见的指责。如果措辞上有任何的不妥,也请大家多多包涵。
  我下面提到的做法,都是在经过实际开发过程检验的(例如开发人员与美工的合作),可能不是最佳,但是我认为还是不错的。

一、ViewState

  HTTP是无连接无状态的协议,因此ASP.NET中提出了ViewState的概念,这样数据被重新Post回页面时,页面(控件)的状态就能恢复,因此才有了很多丰富的功能,例如一些复杂的控件事件。但是ViewState带来的问题就是,如果使用不当,那么页面体积就会增加许多,网络中传输的数据太多自然会影响性能。
  但是ViewState真是必须的吗?我可以很负责任地说,在如今大部分Web应用的页面中,出现的几乎都是大量的链接,点击链接就会跳转到一个和当前页面完全无关的新页面,这样的话,页面上的ViewState又有什么用?因此我如果新建一个Web项目,做的第一件事情就是去Web.config中将enableViewState从全局关闭——同时关闭的还有enableSessionState,这也是影响性能的因素之一(stateless也便于做Web服务器层面的负载均衡)。
  有人曾经反驳我,关闭了ViewState,用WebForm还有什么意义?我的答案是:意义多的很。WebForm提供了控件模型,我能够使用“人人都能看懂和编写”的方式来设置或读取一个文本框里的值。我能轻松地响应不同按钮的事件来编写触发各种业务逻辑。这就是意义,WebForms的开发还是非常简单而清晰的(在一定程度上吧,不要“滥用”永远是正确的)。
  嗯?刚才不是说只有保持ViewState才能使用控件的事件吗?没有ViewState怎么从控件中重新获取状态呢?请注意我之前所说的是“复杂事件”。什么是复杂事件?TextBox的TextChange事件就是“复杂事件”,GridView的Command事件也是复杂事件,但是Button的Click事件就是“简单事件”;与此相对的,GridView里的每一行的数据每一个子控件的状态是“复杂状态”,而TextBox的Text属性则是“简单状态”。“复杂状态”和“复杂事件”需要ViewState,因为与之有关的这些“控件”是ASP.NET“无中生有”的,但是“简单事件”和“简单状态”基于页面中“必然”会提交的数据,它们自然能够还能够使用。在我的ASP.NET开发过程中,使用的几乎都是“简单事件”和“简单状态”,而印象中放弃“复杂事件”和“复杂状态”并没有给我带来任何的困扰。
  当某人送给我们10件礼物,而其中只有4件是我需要的,那么为什么不能简单地放弃其余6件,偏偏要去感谢只送给我们3件礼物的人而去指责前者呢?要知道他并没有恶意,那多余的6件也没有给我们造成任何困扰。
  但人就是那么奇怪。

二、性能

  WebForms的一个重要特点就是一个强大(很多情况下也是“复杂”的代名词)的组件模型。这个组件模型包含一个叫做“生命周期”的玩意儿,也就是这个玩意儿被不少人指责为性能杀手。这个复杂的生命周期的确在很多时候只是“无谓”地一遍遍执行,似乎的确造成了“浪费”,但是这真的到了“杀手”级别了吗?
  如果您认为这个组件模型为性能杀手,不如编写一个内置1000个动态Button控件的页面,然后部署到服务器上,我保证运行的飞快。1000个不够的话那么可以试试看3000、5000甚至10000个控件。您哪张页面上控件的数量会比这个还多?但是您多少页面的性能会比它高?也有文章说“尽可能少的使用服务器端控件,最多使用HTML控件加上runat=server”,这更加没有理由了:一个加了runat=server的HTML控件,它已经变成了服务器端控件了。而普通的HTML最后在控件树中仅仅被作为普通的文本而处理,在控件树中是用一个Literal保存其中的“字符”。至于具体内容是什么,ASP.NET根本不会关心。
  造成性能问题的原因多种多样,在对性能问题进行探索和优化之前,一定要找准性能瓶颈是什么,才能对症下药。如果从某些层面上讲,将公共部分提取成新的方法,会造成执行上多一次call指令的执行,性能也就“降低”了,但是我相信没有人会因此将同样的代码到处复制。在我们接触到的Web应用中,性能瓶颈大都是在数据库访问上(或者外部Service访问,等等),多执行一次数据库查询操作可能就能抵得上内存中1亿次引用拷贝。我相信,如果一个ASP.NET应用程序的性能不高,几乎不可能是因为组件模型或生命周期造成的问题。
  既然Web应用瓶颈大都在数据库访问上,那么一般该如何解决这个问题呢?最直接的方式应该是优化数据库的查询,但是最关键的可能还是缓存。君不见每个谈到Web应用性能优化的讲座都将Cache放在数一数二的位置上,因为这的确是最有效的优化方式之一。在一个并发较高的Web应用中,对一些数据进行1分钟的缓存也能带来相当可观的性能提高。其他的方式可能还有生成静态页面(没有比这访问速度更快的了),异步调用(例如一篇刚发布的文章,在数分钟后才能被搜索到也没有关系,那么何必一定要同步地、即时地写入数据或者创建索引呢?)、分离不同作用的服务器(可以为不同服务器进行有针对性的配置,例如分离图片服务器),做Web服务器端的负载均衡(stateless的重要性由此可见),对数据库进行纵向切割(加快内存中载入的数据量可以提高查询性能,并且纵向切割后能够使用多台数据库服务器分担压力),横向切割(sharding,将数据分置在不同的数据库中,以此可以通过scale out来扩展减少每台服务器的负载,提高性能),作数据冗余或Master-Slave(稍稍降低写操作的性能而提高读取数据的性能,普通Web应用大都“读取”远多于“写入”)等等。
  当然我上面提到的都是应用程序实现和架构方面的东西,事实上开发一个高性能Web应用还涉及到硬件/软件/操作系统等多方面,这里就不多解释了(其实这方面我也还在探索过程中)。其实我在这里想说的仍然是,开发高性能Web应用程序的关键大都与具体所用的实现技术无关:只要“实现”正确,做法大都相同,无论Sql Server/Oracle,Windows/Linux还是ASP.NET/RoR,其本质都差不多。Ruby和C#的性能相差十倍(存疑,求证),不还是能够开发出高性能的Web应用吗?


本文转自 jeffz 51CTO博客,原文链接:http://blog.51cto.com/jeffz/59539,如需转载请自行联系原作者
相关文章
|
1月前
|
人工智能 前端开发 Devops
.NET技术在现代开发中的作用:.NET技术的核心价值、在现代应用开发中的实际应用、以及面临的挑战与未来趋势。
.NET技术是软件开发领域的核心力量,本文从其核心价值、实际应用及未来挑战三方面进行探讨。它支持多种语言,提供强大的开发工具和丰富的类库,并具备跨平台能力。在现代应用开发中,.NET广泛应用于企业级系统、Web应用、移动应用、云服务和游戏开发等领域。面对性能优化、容器化、AI集成等挑战,.NET持续创新以适应不断发展变化的技术环境。
48 4
|
1月前
|
人工智能 开发框架 .NET
.NET技术的强大功能:.NET技术的基础特性、在现代开发中的应用、以及它如何助力未来的软件开发。
.NET技术是软件开发领域的核心支柱,以其强大功能、灵活性及安全性广受认可。本文分三部分解析:基础特性如多语言支持、统一运行时环境;现代应用如企业级与Web开发、移动应用、云服务及游戏开发;以及未来趋势如性能优化、容器化、AI集成等,展望.NET在不断变化的技术环境中持续发展与创新。
59 4
|
1月前
|
人工智能 开发框架 .NET
如何掌握.NET技术,引领开发前沿:.NET技术的核心能力、在现代开发中的应用实践、以及如何通过.NET技术实现持续创新。
.NET技术已成为软件开发不可或缺的部分,本文分三部分探讨:核心能力如多语言支持、统一运行时环境、丰富的类库及跨平台能力;现代开发实践包括企业级应用、Web与移动开发、云服务及游戏开发;并通过性能优化、容器化、AI集成等方面实现持续创新,使开发者站在技术前沿。
45 3
|
9天前
|
存储 运维
.NET开发必备技巧:使用Visual Studio分析.NET Dump,快速查找程序内存泄漏问题!
.NET开发必备技巧:使用Visual Studio分析.NET Dump,快速查找程序内存泄漏问题!
|
9天前
|
SQL 关系型数据库 数据库
七天.NET 8操作SQLite入门到实战详细教程(选型、开发、发布、部署)
七天.NET 8操作SQLite入门到实战详细教程(选型、开发、发布、部署)
|
9天前
|
消息中间件 开发框架 前端开发
YuebonCore:基于.NET8开源、免费的权限管理及快速开发框架
YuebonCore:基于.NET8开源、免费的权限管理及快速开发框架
|
14天前
|
开发框架 JavaScript 前端开发
|
19天前
|
JSON C# 开发者
💡探索C#语言进化论:揭秘.NET开发效率飙升的秘密武器💼
【8月更文挑战第28天】C#语言凭借其强大的功能与易用性深受开发者喜爱。伴随.NET平台演进,C#持续引入新特性,如C# 7.0的模式匹配,让处理复杂数据结构更直观简洁;C# 8.0的异步流则使异步编程更灵活高效,无需一次性加载全部数据至内存。通过示例展示了模式匹配简化JSON解析及异步流实现文件逐行读取的应用。此外,C# 8.0还提供了默认接口成员和可空引用类型等特性,进一步提高.NET开发效率与代码可维护性。随着C#的发展,未来的.NET开发将更加高效便捷。
35 1
|
16天前
|
C# Windows 开发者
超越选择焦虑:深入解析WinForms、WPF与UWP——谁才是打造顶级.NET桌面应用的终极利器?从开发效率到视觉享受,全面解读三大框架优劣,助你精准匹配项目需求,构建完美桌面应用生态系统
【8月更文挑战第31天】.NET框架为开发者提供了多种桌面应用开发选项,包括WinForms、WPF和UWP。WinForms简单易用,适合快速开发基本应用;WPF提供强大的UI设计工具和丰富的视觉体验,支持XAML,易于实现复杂布局;UWP专为Windows 10设计,支持多设备,充分利用现代硬件特性。本文通过示例代码详细介绍这三种框架的特点,帮助读者根据项目需求做出明智选择。以下是各框架的简单示例代码,便于理解其基本用法。
54 0