为什么 Web 前端开发不抛弃 HTML 和 CSS,用纯 JavaScript 开发?

简单的讲: 程序本质是数据结构和算法,HTML 和 CSS只能表达简单的树形结构,适合简单的内容型网站,不适合复杂的Web程序。以它们为核心的开发会:把简单变的更简单,但把复杂变的更复杂。石头搭得了石屋,不一定盖得了大厦。 啰嗦的讲: HTML和CSS的语言表达能力,用JavaScript的一个子集JSON(其实就是JavaScript对象和数组)就可以代替,但缺少基本运算符、语句、函数、对象等,为啥不干脆用JavaScript代替,还能保持统一性和…
关注者
1249
被浏览
98875

105 个回答

考虑到题主是做游戏开发出身,有这种疑问不算稀奇,因为平日的开发几乎不用编写HTML和CSS。
类似的问题如下:
为什么应用程序不抛弃WPF和WinForm,用纯DirectX开发?
为什么APP不抛弃Cocoa,用纯OpenGL ES开发?

因为游戏是离原生界面最远的应用,它几乎完全用不到通用的界面元素,但大部分非游戏应用恰恰要大量使用这些。想象一下每个文字处理、绘图、工具软件在开发时连菜单、对话框和按钮都要自己重写,那是多么费时费力又得不偿失的一件事。

我猜测你的意思是把整个页面当成一个canvas,在上面绘制文字和控件,用js对象代替DOM对象,重写鼠标事件的处理……除了游戏之外,几乎没有网站会这么做。
你所说的“除非是很简单的页面结构”,恰恰是整个因特网上超过95%页面的结构。这些页面最大的功能就是展示信息和简单互动,包括门户网站、社交网络、搜索引擎、博客、微博,还有你正在看的这个页面。这些页面有必要用脚本整个重写一遍吗?当然没有,如果那样的话,可能平添几十倍工作量、页面性能降到10%以下、而且可靠性没法保证——你自己写的引擎,能和ie或webkit比稳定吗?

这就是HTML和CSS不能抛弃的原因。
泻药。

首先要确定,即使抛开游戏不论,一般的Web应用或者网站,完全用JavaScript开发也是可行的。比如ExtJS、webOS的Enyo等。但是主流Web开发很少采用全JS的方案。原因大体有以下几点:


1. 注重考虑那些无法运行JS的用户代理。

用户使用不支持JS的浏览器(比如较老的手机浏览器),或者禁用脚本。当然你可以选择忽略这一小撮用户,尤其是现在绝大多数网站和应用也是如此选择的,但是至少我们应该对坚持考虑无JS情况的开发者予以基本的尊重。此外,如 Mobile Transcoder或某些手机浏览器的“极速模式”是基于服务器端对网页的解析和重组,是否能支持JS很够呛。

更重要的因素是SEO friendly。如果是全JS生成的网页,搜索引擎无法索引内容。这一点对于许多网站是性命攸关的。

注意,有人提到screen reader。但绝大多数读屏软件是根据DOM来的,因此全部由JS生成DOM也不会有问题。然而这前提是JS所生成的DOM是符合accessibility要求的。


2. 注重HTML/CSS本身的优点。

诚然JS本身也可以通过精心设计的框架和库来实现分离等所有HTML/CSS模型的优点。但是存在许多不确定因素:

1) 有足够好的框架和库吗?
要考虑是否能满足你的业务需求,还可能要考虑性能、可扩展性、之前提到的accessibility、学习曲线、工具链,乃至此框架和库的长久的生存(有人维护,修bug、加新功能比如对HTML5新API的支持之类的)。关键是,理论上说JavaScript具有更高的弹性,但是更大的自由度未必能得到更好的

2) 框架和库给出的抽象模型和HTML/CSS模型的阻抗是否匹配?
假如该框架或库本质上仍然使用HTML/CSS模型,只是改变了语法(比如从markup改为json),那么其提供的好处在哪里?仅仅是语法统一?
如果该框架或库有自己独立的抽象层,比如widget/component等,那么它是建筑在HTML/CSS之上的额外抽象层(即最终映射到HTML/CSS),还是仅仅以HTML/CSS为纯粹实现工具?对于前者,实际上最终会回归HTML/CSS模型。而后者,可以参考的经验教训就是ASP.NET WebForm和JSF。

3) 框架和库所设定的约束能否在开发中一以贯之的执行?
无论是理论或者现实,HTML/CSS模型都算不上完美。但是至少是清晰和较容易被一致的执行的。但是单一语言即使提供分层机制,也容易被绕过——尤其是框架和库本身不够好的情况下,可能由于不能满足需求、有bug等情况而倾向于hack之,更不要说deadline紧迫时。


3. 注重性能。

须知,最终Web应用、页面是在浏览器中执行,而浏览器完全是按照HTML/CSS所设计。抛开Canvas不论,纯JS的实现最终还是要生成DOM。从性能的角度看,纯JS生成DOM自然赶不上直接的markup。同样的道理,就算用CSS预处理器也都会在部署时预先编译——尽管在运行时可以做出更牛逼的特性(然而实际上目前我不知道有任何CSS预处理器干了这样的事情——因为它们都是按照预编译的场景设计的),再如HTML/CSS是按照渐进显示优化的(页面不用全下载完就可以看部分),而纯JS的架构没有精心设计是很难做到的(比如json数据全部下载完你才能parse,数据才可用,DOM才能生成)。

[补充:尽管LESS是可以在运行时执行的,但是从性能的角度出发是不合适的,因为CSS通常必须在页面rendering之前就全部就位。而运行时产生CSS, 就要求在页面rending之前至少要先下载执行LESS的脚本,然后解析编译你的.less源代码。这个性能开销至少目前还不容忽视。]

[补充:性能优化的另一点是基于HTML/CSS的声明性特点,即只表明high-level的目标,浏览器才能获得更大的优化自由度。比如CSS transition/animation,与JavaScript通过修改style达到效果比,前者性能表现要好得多。]


4. 注重Web开发的独特特点。

1) HTML/CSS 都是声明式的,也就是其本身并不希望是程序员来编程。当然,一个编程语言能干所有的事情,但是即使考虑编程本身,为什么在通用编程语言之外还要有SQL、还有以各种语法写的配置文件?

2) HTML/CSS是基于标准的。这与ASP.NET WebForm、JSF、Flash/Flex等私有技术或一个语言和平台下的标准有天壤之别。具体就不展开了。

3) Web开发和一般应用开发有个重大区别是,Web应用、网页的最终表现和行为,或者说Web的用户体验,并不是完全由开发者决定的,而是开发者和用户共同决定的。用户选择不同的设备、不同的浏览器、不同的浏览器设置、不同的浏览器扩展等,都能影响结果。这是缺点,也是优点。看你如何体会了。这里具体不展开。只是一点,纯JavaScript开发通常表示你想更多的控制用户体验,但这并非简单的多写代码就能做到。

[补充:举个例子,表单控件上的autofocus属性,乍一看脚本也可以做嘛。但是其实脚本要做对很难!比如页面已然加载一半,用户开始在某个输入框里输入了,但是后续载入的控件要求focus,如果是脚本实现,通常就武断的调用focus(),打断了用户输入(特别是东亚用户使用输入法时被打断很是受伤)。而HTML本身所定义的属性,是由浏览器实现,则可以做恰当的处理。特别注意的是,从老浏览器到新浏览器的升级,你自然就获得了用户体验的提升。另一方面,用户可以主动选择他想用的浏览器,来主动升级他自己的用户体验。这样的例子还有许多许多,不胜枚举。]

以上。
为什么?