《重构HTML:改善Web应用的设计(修订版)》——1.3 重构什么

简介:

本节书摘来自异步社区《重构HTML:改善Web应用的设计(修订版)》一书中的第1章,第1.3节,作者: 【美】Elliotte Rusty Harold 更多章节内容可以访问云栖社区“异步社区”公众号查看。

1.3 重构什么

诸如Java之类的编程语言和诸如HTML之类的标记语言的重构有一个关键的区别。与HTML相比,Java变化相对缓慢,C++的变化很少,C就更不用说了。用Java 1.0编写的程序跟Java 6的跑起来没有什么大的不同。Java增加了大量新特性,但大体上能保证一致性。

然而,HTML和相应的技术在同样的时间范围内却发生了巨大的变化。今天的HTML跟1995年的根本不是一码事。新版不仅剔除了一些关键字,也加入了一些新的关键字,在语法和解析算法上也有所改变。尽管现代浏览器如Firefox或IE 7通常可以显示一个过时的页面,但你会发现很多东西根本无法正常运作。进一步讲,浏览器必须处理CSS和ECMAScript等全新组件。

本书给出的大部分重构建议,将会重点围绕升级网站以支持Web标准,尤其是:

  • XHTML
  • CSS
  • REST

这有助于将开发人员从以下困境中解救出来:

  • 标签汤
  • 基于表现的标记
  • 有状态(stateful)应用

这里并没有非此即彼的选择或是孤注一掷的决定。你总是可以从3个方面入手改善网站的特性,用不着追求尽善尽美。持续改进是重构的重要特征。小改动产生小改善,没有必要毕其功于一役。你可以在实现有效的XHTML之前先实现良构的XHTML;在转向CSS之前也可以先实现有效的XHTML;在进一步考虑消除会话(session)或会话cookie之前,可以先把网站完全符合CSS的布局做完。

当然不一定得按照这些顺序来执行这些改动。你可以从建议列表中选择能为应用程序带来最大好处的重构方案。这有可能是不需要XHTML但是急需CSS的情况;又或者需要把应用程序的架构转向REST以提升性能,但并不关心把文档转为XHTML。不过最终选择权在你手中。本书给出了各种建议和方案,帮你权衡各种重构方式的代价和收益。

使用标签汤、基于表格的布局、图像映射和cookie构建Web应用当然是可以的,但扩展它的投入大部分人都担负不起。横向(更多用户)和纵向(更多功能)的扩展均需要一个比较健壮的根基,而这些正是XHTML、CSS和REST所能提供的。

1.3.1 为何要用XHTML
XHTML只不过是XML化的HTML。HTML至少在理论上基于SGML,而XHTML则基于XML。XML是一个比SGML更简洁和清晰的规范。因此,XHTML是HTML简洁、清晰的一个变体。选择XHTML还是选择HTML,这就像眼前摆着一把枪,你是去扣动扳机,还是去做靶子,那感受可是天壤之别。

对用户更友好的XHTML页面是以编写者更难开发为代价的。HTML容许犯错,但XHTML不容许。在HTML中,如果忽略了结束标签或是在这里或那里留下了多余的引号,不会发生什么大事,最多只是有些文本被标记为粗体了,或者不正确地缩进了。即使是最坏的情况,也只是在这、在那少了一些词语而已,页面的大部分还是能显示出来的。这种宽容的本性使得HTML的学习更加容易。因为你编写的HTML即使是不正确的,也不至于发生严重的问题。

但XHTML非常严格。诸如漏掉引号或忽略结束标签这些细微的错误,在HTML中浏览器会默默补上,但在XHTML中就会成为严重的四级警报。在XHTML文档中,就算是小小的错误,浏览器也只能举手缴械,拒绝显示页面,如图1-2所示。这让编写XHTML页面的工作难度加大,特别是在使用纯文本编辑器时。但就跟编写计算机程序一样,一个语法错误能破坏所有东西。错误是没有商量的余地的。


<a href=https://yqfile.alicdn.com/6c98d24759dab9b137d06f9054c57ad60b3ae64b.png" >

那么为什么大家都要选择XHTML呢?这是因为,虽然这些限制加大了编写XHTML的难度(严格的错误处理),但却简化了XHTML的处理。现在接力棒已经从浏览器交到了编写者的手中。浏览器(或者其他要读取页面的设备)不必再试图弄懂混乱的标签汤,并去猜测页面的真正意图。只要页面有一丁点儿的不清晰,浏览器就可以(实际上也是有必要的)放弃并拒绝处理。这能让浏览器的工作更简单。当前大多数浏览器在解析HTML代码时,都把精力投入到纠正页面的错误中去了,有了XHTML后就没有必要这么费心了。

当然,我们绝大部分人都不是浏览器开发者,而且可能永远没有开发浏览器的机会。我们能从XHTML及其严格的错误处理中得到什么好处呢?自然有好几条。首先,尽管大多数人不用去开发浏览器,但大部分人要编写支持网页的程序。这些程序可以是混搭(mashup)、Web Spider、Blog聚合器、搜索引擎、开发工具等,它们都需要读取网页。这些程序处理XHTML要比处理HTML容易得多。

当然,通过Web工作或者编写网页的大多数人都不是传统的程序员,而且不会去编写 Web Spider或Blog聚合器。但有两样很有可能需要他们去编写:JavaScript以及样式表。从数量上来说,这是最普遍的一类读取网页的程序。所有嵌入到网页中的JavaScript程序都需读取网页。所有的CSS样式表(尽管从传统的角度来看,它并不是程序)也需读取页面。如果JavaScript和CSS读取的是XHTML而不是HTML,就更容易编写和除错。实际上,编写有效的XHTML所付出的额外代价,在为JavaScript和CSS除错时会获得更多的时间补偿。

修复XHTML错误是恼人和花费时间的,但这是一个相当直接的过程,并不是那么困难。验证器能列出这些错误,你可以浏览这个错误清单并逐一修正它们。事实上,这种层次上的错误比较明显,可以自动修复它,这会在第3章和第4章中介绍。修复XHTML可能得花费些时间,但这些时间总量是可预估的。这样才不至于让你在病态的HTML中,进行JavaScript或CSS的跨浏览器排错时变得沮丧,看不到完工的尽头。

使用文本编辑器手工编写正确的XHTML也是一个不小的挑战。不过由工具生成标记的话,XHTML会变得更容易。良好的WYSIWYG(所见即所得)HTML编辑器(比如Dreamweaver 8)可以(而且应该)被配置为在默认情况下生成有效的XHTML。标记级别的编辑器(如BBEdit)也可以设置为使用XHTML规则,尽管编写者需要小心对待。很多编辑器都有检查XHTML有效性的选项,可以设置为通过单击一个按钮就可自动修正任何错误。

保证你已经开启编辑器的一些必要选项。与良好的CMS和Wiki类似,Blog引擎也可以根据需要生成XHTML。如果你的编写工具不支持XHTML,尽一切办法找个更好的工具。在21世纪的今天,HTML编辑器或Web发布系统不会不支持XHTML。

如果你的网站是手工搭起的模板系统,有可能得多做些工作,在第3章和第4章中我们会看到这种需求。尽管这种处理手工做得多了一些,但一旦做完就能自动生成有效的XHTML。发布者通过数据库或者Web表单输入内容时,或许完全不需要改变他们的工作流程,特别是在使用如markdown或wikitext等非HTML格式的数据时。系统可以轻松地将它们转换为XHTML。

使用XHTML而不是HTML的第二个理由是跨浏览器兼容性。实际上,在今天的浏览器上XHTML比HTML更具有一致性,大量使用CSS和JavaScript的复杂网页更是如此。尽管浏览器可以修正传统HTML的标记错误,但并不是总能以相同的方式处理。虽然两个不同的浏览器读取的是相同的页面,但会产生不同的内部模块。这给编写跨浏览器的样式表或脚本增加了难度。反之,XHTML并不需要浏览器做大量解释,也减少了浏览器抓狂的机会。诚然,不同的浏览器对CSS、JavaScript和DOM(文档对象模型)兼容性的支持不同,但转向XHTML清除了跨浏览器兼容性的一大障碍。即使不是完整的方案,但也可以修正大量的问题。

第三个理由是在页面中加入未来的新技术。从上面详细列出的理由可知,XHTML是更为强大的平台。HTML善于显示文本和图片,对于简单的表单来说也还不错。但除此之外,浏览器也是Flash、Java和Ajax等其他技术的宿主。很多功能在浏览器中并不容易实现,比如数学公式和音乐曲谱。有些功能本来就是不难的,比如在表单中输入错误的值时提示用户。

为改善这些问题的技术在不断发展,而且还有更多的技术正在开发当中,包括为数学公式准备的MathML,为乐谱准备的MusicXML、为动画准备的SVG(Scalable Vector Graphics,可伸缩矢量图形)和为强大客户端程序准备的XForms等。所有这些都是以XHTML为基础的,但它们都不能正确地基于传统的HTML使用。把页面重构为XHTML可以利用即将到来的新技术。在某些情况下,新技术可以让你做到原先做不到的事。在其他情况下,让你做到现阶段技术所能做到的,而且更快更容易。无论是哪一种情况,只要是其中之一,都值得你去把HTML重构成XHTML。

1.3.2 为何要用CSS
把表现从内容中分离出来是HTML的基本设计原则。这让你可以为不同的客户端提供相同的内容,但可以由客户端来决定样式,最大程度上适应它们所需要的环境。手机浏览器不具备Firefox等桌面浏览器一样的性能。实际上,手机浏览器很可能根本不去可视化地显示内容,而是只把文档内容读给用户听。

因此,HTML文档应该侧重表达的是文档的意义而不是文档的表现。更重要的是,这种编写风格尊重用户的偏好。访问者可以选择适合自己的字体和颜色,而不是编写者提供的默认值。一种尺码并不能适合所有人。拥有正常视力的30岁飞行员非常容易看清的网站,可能对于一位85岁的老奶奶来说就是模糊不清的;一个漂亮的蓝绿设计对于一个色盲用户来说可能就是很费解的;一个精心设计的表格布局,对于正在花园州高速公路(Garden State Parkway)上兜风时使用手机收听网页的司机来说,只不过是一些杂乱无序的词组。

在HTML中,你不应将一些段落格式CSS化为左对齐的11点的加粗Arial字体,而应该指定它是一个H2标题。自从Netscape出现并发明了font标签和其他一些表现性元素后,人们就马上开始使用——恐怕你也没少用吧。虽然之后W3C以CSS作为回应,但是这种破坏业已产生。网页到处充斥着font、frame、marquee以及其他表现性元素。语义元素如blockquote、table、img和ul的本身意义都被颠覆了,只用来达到布局的目的。坦白地说,虽然运作并不是那么好,但很长一段时期内,这是我们所能做到的最好状态。

但现在不一样。今天的CSS不仅仅是简单的重复,比起使用frame、占位GIF以及图片隐藏文本等做法实现的布局和表现相比,它要优秀得多。CSS布局不仅更精美,而且更少偏差、更高效、更好用,而且页面加载变得更快,显示得更好。多做些努力,CSS就能让页面在多平台多浏览器上运作得更好。

把表现标记挪出页面并放到分离的样式表中去,你就可以从一个简单的页面开始,这种简单性对所有访问者都是清晰的,即使使用的是10年前的浏览器。然后可以为这些页面赋予漂亮的外观效果,改善使用它们的用户的体验。这么一来不会有任何人被拒之门外,页面实现了优雅降级(degrade gracefully)。

这种方式也对开发者有利。首先,它让掌握不同技术的不同开发者可以发挥自己的长处:内容作者不用顾忌最终格式而奋笔直书,设计者可以不了解内容作者的语句就组织和重排页面,程序员可以不妨碍页面的表现而开发脚本,为页面添加功能。CSS让每个人在互不干扰的情况下各司其职发挥所长。

如果CSS对于内容作者和设计者来说是小恩小惠的话,那么对开发者来说简直是天大的恩赐。从程序员的角度来看,把所有的布局和样式挪出来放到一个分离的CSS样式表中后,页面会变得非常简洁。文档树内的元素更少,嵌套深度也更低,编写与页面有关的交互脚本的难度也大幅度下降。

最后的赢家莫过于勤勤恳恳管理整个网站的站长(Web Master)了。移除表现性标记和分离样式表,可以组合通用的样式,并保持整站一致的观感。把默认字体从Arial修改为Helvetica不再需要编辑上千个HTML文档,现在只需在一个独立的样式文件中修改一行就能搞定。

CSS让Web开发者、站长和Web设计者都能遵从DRY原则:别自我重复(Don’t Repeat Yourself)。把通用的规则组合成独立的、可复用的文件,可以简化维护、更新和编辑。甚至最终用户也能从中得益,因为他们只需载入一次网站的样式规则,而不是每个页面都得重新下载一遍。更轻量的页面载入得更快,显示得更流畅。这真是一个共赢的局面。

最后,不要忽略了CSS对网络管理者和会计师的重要性。虽然每个页面中纯表现性的信息可能只占1KB到2KB,但对于上千个页面和百万之巨的用户,总量就会大得惊人。只载入一次样式,不用每个页面都载入额外的表现性标记,就可以节省带宽。ESPN在转向CSS标记时,每天节省了2TB的流量。从这个层次上说,这能转化为实实在在的收益,节省程度大致上是可以估量的。诚然,我们开发的绝大多数站点都不能跟ESPN相提并论,只能幻想着每天能先有2TB的日流量,而我们能够节省日流量则远远少于2TB。但不管怎么说,如果你正经历着流量超载,或是有希望被Digg首页推介而流量大涨,把样式挪到外部的CSS样式表中肯定会大有帮助。

1.3.3 为何要用REST
REST(Representational State Transfer,表述性状态转移)是本书提出的出现最早但可能知道的人最少的重构目标。尽管本书侧重于HTML,但也不会忽视HTML的传输协议HTTP,REST是HTTP的架构。

理解HTTP和REST对如何设计Web应用程序非常重要。在页面中放置表单,或使用Ajax在JavaScript程序中传递数据时,使用的就是HTTP。正确使用HTTP可以开发健壮、安全和可扩展的应用程序。但使用不慎的话,你能祈祷的最好结果只是一个功能勉强可用的系统,但可能会发生的最坏情况是非常不妙的:Web Spider会删掉整个站点、购物中心在圣诞购物期间由于繁忙的业务而宕机或者搜索引擎无法索引导致用户无法找到你的网站。

尽管基本的静态HTML页面有着内在的REST方式,但大部分更为复杂的Web应用程序并不是。特别是在应用程序涉及以下常见的特性时,必须考虑使用REST:

  • 表单
  • 用户验证
  • Cookie
  • 会话
  • 状态

人们很容易在这些特性上犯错,现在很多应用程序使用它们的方式也是错比对多。Web不是LAN,那种为少数而且有限C/S系统服务的技术,都不能扩展为可以容纳千万级用户的Web系统。基于会话和持久连接技术的C/S架构对Web并不适用。试图重建它们会败在扩展上,通常会导致损失惨重的后果。

使用HTTP实现的REST拥有一些关键的概念,这会在接下来的内容中讨论。

  1. 所有的资源通过URL定位
    使用不同的URL给不同的资源打上标签,让它可以被收藏、链接,被搜索引擎索引或印到广告牌上。

别抵触URL,大部分资源都应该只通过URL定位。就是说,每个客户都应该有一个独立的URL直接链接到他的记录(当然有密码保护),而不是所有客户都共享同一个URL,通过不同的登录cookie才能改变这个URL下的内容。

  1. 通过GET进行诸如查询或浏览等安全无副作用的操作
    Google只能索引通过GET访问的页面,用户只能收藏通过GET访问的页面,其他网站只能链接使用GET的页面。如果想提升网站的流量,应该让用户尽可能以GET方式访问网站。
  2. 通过POST进行诸如购买或添加评论等非安全的操作
    Web Spider按惯例在页面上抓取的是通过GET访问的链接,即使有时被告知是不应抓取的。用户在浏览器地址栏中键入URL,然后修改它们就能看到发生的结果。浏览器预抓取链接页面也是通过GET。如果存在如删除内容、签署合同或重新排序等通过GET执行的操作,有些程序某种程度上并不会征求真实用户的同意就开始执行,这有时会产生十分严重的后果。当Google发现并抓取“删除此页”之类的链接时,整个站点可能就会因此消失,这都是因为使用GET取代了POST。
  3. 各个请求彼此独立
    客户端和服务器端都可以有自己的状态,而且互不依赖对方。所有必要的信息都在每一次通信中传递。无状态让扩展得以通过缓存和代理服务器来实现,在有必要时同样也支持服务器群代替单台服务器。同样,服务器对相同客户端没有必要连续响应两次。

健壮、可扩展的Web应用程序应该使用HTTP而不是抵触HTTP。常见的C/S应用程序是可以做到的,REST风格的应用程序也可以照单全收,而且能做到充分的可扩展性。但是,这样的实现可能要求系统进行巨大的改动。尽管如此,如果你擅于解决扩展性问题,那么这就可以成为一项重要的重构技术。

相关文章
|
8天前
|
搜索推荐 定位技术 UED
HTML定位技术:种类、特点与应用
HTML定位技术:种类、特点与应用
|
10天前
|
前端开发 JavaScript 关系型数据库
从前端到后端:构建现代化Web应用的技术探索
在当今互联网时代,Web应用的开发已成为了各行各业不可或缺的一部分。从前端到后端,这篇文章将带你深入探索如何构建现代化的Web应用。我们将介绍多种技术,包括前端开发、后端开发以及各种编程语言(如Java、Python、C、PHP、Go)和数据库,帮助你了解如何利用这些技术构建出高效、安全和可扩展的Web应用。
|
25天前
|
监控 Serverless 测试技术
Serverless 应用引擎常见问题之做的web服务计费如何解决
Serverless 应用引擎(Serverless Application Engine, SAE)是一种完全托管的应用平台,它允许开发者无需管理服务器即可构建和部署应用。以下是Serverless 应用引擎使用过程中的一些常见问题及其答案的汇总:
329 3
|
3天前
|
缓存 负载均衡 数据库
优化后端性能:提升Web应用响应速度的关键策略
在当今数字化时代,Web应用的性能对于用户体验至关重要。本文探讨了如何通过优化后端架构和技术手段,提升Web应用的响应速度。从数据库优化、缓存机制到异步处理等多个方面进行了深入分析,并提出了一系列实用的优化策略,以帮助开发者更好地应对日益增长的用户访问量和复杂的业务需求。
9 1
|
3天前
|
缓存 监控 数据库
Flask性能优化:打造高性能Web应用
【4月更文挑战第16天】本文介绍了提升Flask应用性能的七大策略:优化代码逻辑,减少数据库查询,使用WSGI服务器(如Gunicorn、uWSGI),启用缓存(如Flask-Caching),优化数据库操作,采用异步处理与并发(如Celery、Sanic),以及持续监控与调优。通过这些手段,开发者能有效优化Flask应用,适应大型或高并发场景,打造高性能的Web服务。
|
4天前
|
前端开发 搜索推荐 数据安全/隐私保护
HTML标签详解 HTML5+CSS3+移动web 前端开发入门笔记(四)
HTML标签详解 HTML5+CSS3+移动web 前端开发入门笔记(四)
13 1
|
4天前
|
PHP
web简易开发——通过php与HTML+css+mysql实现用户的登录,注册
web简易开发——通过php与HTML+css+mysql实现用户的登录,注册
|
4天前
|
数据库 开发者 Python
Python中使用Flask构建简单Web应用的例子
【4月更文挑战第15天】Flask是一个轻量级的Python Web框架,它允许开发者快速搭建Web应用,同时保持代码的简洁和清晰。下面,我们将通过一个简单的例子来展示如何在Python中使用Flask创建一个基本的Web应用。
|
8天前
|
JavaScript 前端开发 API
Vue.js:构建高效且灵活的Web应用的利器
Vue.js:构建高效且灵活的Web应用的利器
|
16天前
|
XML JSON JavaScript
使用JSON和XML:数据交换格式在Java Web开发中的应用
【4月更文挑战第3天】本文比较了JSON和XML在Java Web开发中的应用。JSON是一种轻量级、易读的数据交换格式,适合快速解析和节省空间,常用于API和Web服务。XML则提供更强的灵活性和数据描述能力,适合复杂数据结构。Java有Jackson和Gson等库处理JSON,JAXB和DOM/SAX处理XML。选择格式需根据应用场景和需求。