Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Ajax应用开发最佳实践

2,468 views

Published on

Ajax应用开发的最佳实践

Published in: Technology, Design

Ajax应用开发最佳实践

  1. 1. Ajax 应用开发最佳实践 Alex Cheng http://www.cheng-fu.com http://cn.linkedin.com/in/chengfu
  2. 2. Web 2.0 应用开发 <ul><li>Web 2.0 应用一般是富互联网应用( RIA , Rich Internet Application )。 </li></ul><ul><li>RIA 应用有很多的实现方式: </li></ul><ul><ul><li>Ajax </li></ul></ul><ul><ul><li>Flash </li></ul></ul><ul><ul><li>JavaFX </li></ul></ul><ul><ul><li>Sliverlight </li></ul></ul><ul><li>Ajax </li></ul><ul><ul><li>Ajax 的含义是异步 JavaScript 和 XML 。 </li></ul></ul><ul><ul><li>通过 XMLHTTPRequest 来异步的从服务器获取数据并对页面进行局部更新 </li></ul></ul><ul><ul><li>由于不会打断当前用户的使用流程,提升了用户体验。 </li></ul></ul><ul><li>Ajax 由于不需要额外的浏览器插件支持,在 RIA 应用开发中得到了广泛的使用。 </li></ul>
  3. 3. Ajax 应用组成元素 <ul><li>HTML </li></ul><ul><ul><li>基本内容结构 </li></ul></ul><ul><li>CSS </li></ul><ul><ul><li>外观与样式 </li></ul></ul><ul><li>JavaScript </li></ul><ul><ul><li>与用户的交互 </li></ul></ul>
  4. 4. 使用富含语义的 HTML <ul><li>在编写 HTML 文档时,尽可能的使用 HTML 规范中定义的与文档结构相关的富含语义的元素,而避免使用与展示相关的元素,将展示相关的内容交给 CSS 去处理 。 </li></ul><ul><li>应用的结构 和展示可以分别独立变化 。 </li></ul>
  5. 5. HTML 中表示文档结构和富含语义的元素 元素 说明 <h1> 、 <h2> 、 <h3> 、 <h4> 、 <h5> 和 <h6> 表示不同级别的标题。 <p> 表示文档中的一个段落。 <em> 、 <strong> 表示对文档中文本的强调。 <abbr> 、 <acronym> 表示缩写词。 <blockquote> 、 <q> 表示文档中的引用。 <ul> 、 <ol> 、 <li> 表示列表型的内容和其中的条目。 <dl> 、 <dt> 、 <dd> 表示术语及其描述。 <cite> 表示对外部资料的引用。 <code> 表示程序源代码。
  6. 6. 富含语义的 HTML 最佳实践 <ul><li>选用合适的 DTD </li></ul><ul><ul><li>目前来说最合适的 DTD 是 <!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.01 Transitional//EN&quot; &quot;http://www.w3.org/TR/html4/loose.dtd&quot;> 。 </li></ul></ul><ul><li>验证你的 HTML </li></ul><ul><ul><li>使用 W3C 提供的 HTML 文档验证器。 </li></ul></ul><ul><li>使用合适的元素 </li></ul><ul><li>避免错误的元素使用 </li></ul><ul><ul><li>不要为了达到某种显示效果而使用错误的元素。 </li></ul></ul><ul><li>使用富含语义的 class 属性 </li></ul><ul><ul><li>好的 class 属性可以为已有的 HTML 元素增加语义,尤其适合与 div 和 span 元素。 </li></ul></ul><ul><ul><li>好的 class 属性值应该要说明其对应的 HTML 元素的作用,而不应该说明该元素的展现样式。 </li></ul></ul>
  7. 7. 使用微格式( Microformat ) <ul><li>微格式( Microformat )是满足特定模式的有组织的 HTML 片断,用来描述网页中富含语义的实体。 </li></ul><ul><li>这些实体包括人、事件、评论、地理位置和个人简历等。 </li></ul><ul><li>微格式将对语义的保留提升到了 HTML 片断的层次。 </li></ul>
  8. 8. CSS <ul><li>熟悉常用的 CSS 选择器 </li></ul><ul><ul><li>通用选择器( * ):匹配文档中的任意元素。 </li></ul></ul><ul><ul><li>元素类型选择器:匹配文档中的某类元素。 </li></ul></ul><ul><ul><li>直接后代选择器:匹配作为特定元素的直接后代出现的元素。 </li></ul></ul><ul><ul><li>相邻兄弟元素选择器:匹配与特定元素有相同父节点,并且直接出现在该元素后面的元素。 </li></ul></ul><ul><ul><li>属性选择器:匹配属性值满足某些条件的元素。 </li></ul></ul><ul><ul><li>类选择器:匹配包含某个 CSS 类的元素。类选择器实际上是属性选择器的一种,是根据属性 class 的值来进行选择的。 </li></ul></ul><ul><ul><li>ID 选择器:匹配指定 ID 属性值的元素。 </li></ul></ul><ul><ul><li>伪元素和伪类选择器:匹配一些无法根据其在文档树中的位置来定位的元素。 </li></ul></ul><ul><li>熟悉常用的 CSS 样式声明 </li></ul><ul><ul><li>声明是 CSS 中样式属性的名值对,其形式是“属性名称 : 属性值”。如声明“ font-color : red” 把样式 font-color 的值设为 red 。 </li></ul></ul>
  9. 9. 解决浏览器兼容性问题 <ul><li>使用 IE 条件注释 </li></ul><ul><li>使用招数 </li></ul><ul><ul><li>利用浏览器本身对 CSS 规范支持的不完善或是实现上的 bug ,来针对特定的浏览器应用样式的一些做法 。 </li></ul></ul><ul><ul><li>招数可能随着浏览器的升级而变得不可用,建议只在必要的时候才使用 。 </li></ul></ul><ul><li>使用 JavaScript </li></ul><ul><ul><li>通过 JavaScript 可以判断当前的浏览器类型,从而应用不同的样式 。 </li></ul></ul>
  10. 10. 可维护的 CSS <ul><li>组件化 </li></ul><ul><ul><li>开发出针对页面上某类元素的样式组件。 </li></ul></ul><ul><ul><li>这些样式组件可以在不同的页面中任意组合使用。 </li></ul></ul><ul><ul><li>常用的样式组件有标题( h1-h6 )、列表( ul 和 ol )和按钮等。 </li></ul></ul><ul><li>单一职责 </li></ul><ul><ul><li>把结构和外观分开,让它们分别变化 。 </li></ul></ul>
  11. 11. DOM 操作 <ul><li>DOM 操作是 Ajax 应用中页面动态和局部刷新的实现基础。 </li></ul><ul><li>DOM 定义了文档的逻辑结构,以及对文档进行访问和操作的方式。 </li></ul><ul><li>通过 DOM ,开发人员可以在文档中自由导航, 也可以添加、更新和删除其中的元素和内容。 </li></ul><ul><li>基本上文档中的任何内容都是可以通过 DOM 进行访问和操作的。 </li></ul>
  12. 12. 使用 DOM 的方式 <ul><li>服务器端返回数据,浏览器端使用 DOM 操作 </li></ul><ul><ul><li>服务器端返回的只是数据本身,并不包含展示相关的内容。浏览器端通过 XMLHTTPRequest 请求获取到数据之后,通过 DOM 操作来生成所需的页面片段,并添加到当前页面中。 </li></ul></ul><ul><li>服务器端返回 HTML 片段,浏览器端简单显示 </li></ul><ul><ul><li>服务器端通过模板技术,如 JSP™ 、 Apache Velocity 、等生成 HTML 片段,返回给浏览器。浏览器只需要用获取的 HTML 片段更新当前页面即可。 </li></ul></ul><ul><li>服务器端返回数据,浏览器端使用模板 </li></ul><ul><ul><li>服务器端返回的只是数据。浏览器端不是通过 DOM 操作来生成 HTML 片段,而是通过模板来进行生成。 </li></ul></ul>
  13. 13. 选择最适合的技术 <ul><li>服务器端返回数据还是展示 ? </li></ul><ul><ul><li>服务器端返回数据的好处是传输量较小、和客户端的耦合较松散以及较容易支持除浏览器之外的其它客户端 。 </li></ul></ul><ul><ul><li>不足之处在于在浏览器端有比较多的逻辑来生成 HTML 片段。 </li></ul></ul><ul><li>浏览器端使用 DOM 操作还是模板 技术? </li></ul><ul><ul><li>DOM 操作的好处是简单易用,使用起来比较直接。 </li></ul></ul><ul><ul><li>不足之处在于代码编写比较复杂和冗长。而使用模板的话,所生成的 HTML 片段的结构可以从模板中很直观的看到,修改起来比较方便。 </li></ul></ul>
  14. 14. 提高 DOM 操作性能 <ul><li>使用文档片段 </li></ul><ul><ul><li>文档片段是一个轻量级的文档对象,可以用来包含其它节点。当文档片段被插入到文档树中的时候,其本身并不会被插入,而只有其子节点被插入。 </li></ul></ul><ul><ul><li>一个常见的提高 DOM 操作性能的做法是利用文档片段来插入新创建的节点。首先创建一个文档片段,再把新创建的节点插入到文档片段中,再把该文档片段插入到文档树中。这样做的好处是可以减少页面的重新排列( reflow )。 </li></ul></ul><ul><li>使用 innerHTML </li></ul><ul><ul><li>这种做法是通过字符串拼接来构造 HTML 文档,再通过设置元素的 innerHTML 来修改其内容。使用 innerHTML 比一般的 DOM 操作要快。 </li></ul></ul><ul><li>使用 cloneNode() </li></ul><ul><ul><li>当需要创建多个结构相同的元素时,比较好的办法是首先创建出一个元素作为模板,然后用 cloneNode() 方法复制出其它的元素。这样比逐个创建每个元素速度要快。需要注意的是,通过 cloneNode() 复制出来的元素会丢失原来绑定在其上的事件处理方法,需要重新进行事件绑定。 </li></ul></ul>
  15. 15. 事件处理 <ul><li>事件处理是 Ajax 应用中的重要组成部分,也是应用动态变化的源动力。 </li></ul><ul><li>尽量使用 JavaScript 框架的支持来注册事件监听器。 </li></ul><ul><li>了解事件的传播过程。 </li></ul><ul><ul><li>捕获阶段:事件首先从文档的根节点开始,传播给目标节点的祖先节点,直到目标节点的直接父节点。 </li></ul></ul><ul><ul><li>目标阶段:事件传播到目标节点。 </li></ul></ul><ul><ul><li>冒泡阶段:事件从目标节点的直接父节点开始,传播到目标节点的祖先节点,直到文档的根节点。 </li></ul></ul><ul><li>处理事件 </li></ul><ul><ul><li>注意事件处理方法中 this 所引用的对象 </li></ul></ul><ul><li>阻止事件传播 </li></ul>
  16. 16. 事件传播过程
  17. 17. 避免内存泄露 <ul><li>在事件监听器方法中很容易不正确的使用闭包,造成 DOM 节点对象和 JavaScript 对象之间的循环引用。 IE 的垃圾回收机制不能正确处理这种循环引用,从而导致内存泄露。 </li></ul><ul><ul><li>使用 JavaScript 框架提供的 事件 注册支持 。这样不仅兼容性更好,而且减少了无意中创建的闭包,不容易造成内存泄露。 </li></ul></ul><ul><ul><li>事件监听器方法应该尽可能的简单。方法体的代码应该尽可能的少,把业务逻辑代理给其它方法来完成。这样做的好处是容易识别出其中的对象引用,便于检查是否有内存泄露。 </li></ul></ul><ul><ul><li>尽量不要在事件监听器方法中为 DOM 节点对象添加额外的属性。 </li></ul></ul><ul><ul><li>显式的删除对象引用 </li></ul></ul>
  18. 18. 提高事件处理性能 <ul><li>减少事件监听器的注册,充分利用事件的传播机制 </li></ul><ul><ul><li>如果需要为多个子节点添加逻辑相同的事件监听器,更好的做法是把监听器添加到其某个祖先节点上。这样的话就会减少事件监听器的数量。 </li></ul></ul><ul><li>适时的阻止事件传播 </li></ul><ul><ul><li>当 Ajax 应用比较复杂,并且其中包含的组件比较多的时候,适时的阻止事件传播可以减少组件间的互相影响。 </li></ul></ul>
  19. 19. 安全 <ul><li>CSRF = Cross-site request forgery 跨站点请求伪造 </li></ul><ul><li>对于那些只使用 cookie 来保护资源的站点 </li></ul>Bank.com http://www.bank.com/transfer?to=xxx&amount=10000 BankHacker.com <img src=‘http://www.bank.com/transfer?to=hacker&amout=10’ > Bank.com Login Cookie saved Use BankHacker.com Use saved cookie
  20. 20. 安全 <ul><li>JSON 劫持 </li></ul>http://www.bank.com/history [{“time” : “”, “name” : “”}, {}, {}] <script src=‘http://www.bank.com/history’></script> Array 的构造方法是可以被重定义的。 <script type='text/javascript'> function Array() { var obj = this; var ind = 0; var getNext = function(x) { obj[ind++] setter = getNext; if (x) alert(“Data stolen from array: &quot; + x.toString()); }; this[ind++] setter = getNext; } </script> <script type='text/javascript' src='http://bank.com/history'> </script>
  21. 21. 性能 <ul><li>关于 Web 2.0 应用的性能,有很多的最佳实践可以遵守 </li></ul><ul><li>推荐两本书来阅读 </li></ul>

×