使用 HTML5 打造速度更快的 Web 应用的最佳做法

简介

HTML5 的许多功能旨在为我们目前通过 JavaScript 库实现的组件和技术提供原生浏览器支持。使用这些功能(如果有)最终可以为用户提供更快捷的体验。在本教程中,我不会重复介绍您在 Yahoo 的卓越性能网站或 Google 的网页速度文档让网络变得更快网站上看到的出色性能研究。我将重点介绍如何使用 HTML5 和 CSS3 让您的 Web 应用更具响应能力。

提示 1:使用 Web 存储空间代替 Cookie

虽然 Cookie 已被用于跟踪唯一身份用户数据多年,但存在严重的缺点。最大的缺点是,您的所有 Cookie 数据都会添加到每个 HTTP 请求标头中。这最终可能会对响应时间产生可衡量的影响,尤其是在 XHR 期间。因此,最佳做法是缩减 Cookie 大小。在 HTML5 中,我们可以做得更好:使用 sessionStoragelocalStorage 来代替 Cookie。

这两个 Web 存储对象可用于在会话期间或无限期地在客户端保留用户数据。他们的数据也不会通过每个 HTTP 请求传输到服务器。他们提供了一个 API,可让您轻松摆脱 Cookie。下面是这两个 API,都使用 Cookie 作为后备。

// if localStorage is present, use that
if (('localStorage' in window) && window.localStorage !== null) {

  // easy object property API
  localStorage.wishlist = '["Unicorn","Narwhal","Deathbear"]';

} else {

  // without sessionStorage we'll have to use a far-future cookie
  //   with document.cookie's awkward API :(
  var date = new Date();
  date.setTime(date.getTime()+(365*24*60*60*1000));
  var expires = date.toGMTString();
  var cookiestr = 'wishlist=["Unicorn","Narwhal","Deathbear"];'+
                  ' expires='+expires+'; path=/';
  document.cookie = cookiestr;
}

提示 2:使用 CSS 转场效果,而不是 JavaScript 动画

CSS 转场效果可让您在两种状态之间实现富有吸引力的视觉转换。大多数样式属性都可以进行转换,例如操控文本阴影、位置、背景或颜色。您可以使用过渡进入 :hover 等伪选择器状态,也可以从 HTML5 表单 :invalid:valid 进入这些状态(包含表单验证状态的示例)。但它们功能更强大,可以在您向元素添加任何类时触发。

div.box {
  left: 40px;
  -webkit-transition: all 0.3s ease-out;
     -moz-transition: all 0.3s ease-out;
       -o-transition: all 0.3s ease-out;
          transition: all 0.3s ease-out;
}
div.box.totheleft { left: 0px; }
div.box.totheright { left: 80px; }

通过添加 tothelefttotheright 的切换类,您可以移动该框。将此代码量与 JavaScript 动画库的代码量进行比较。显然,使用基于 CSS 的动画时,发送到浏览器的字节数要少得多。此外,借助 GPU 级加速,这些视觉转换将尽可能流畅。

提示 3:使用客户端数据库,而不是服务器往返

Web SQL 数据库IndexedDB 将数据库引入了客户端。您可以利用这些客户端数据库,而无需采用通过 XMLHttpRequest 或表单提交方式将数据发布到服务器的常见模式。减少 HTTP 请求是所有性能工程师的主要目标,因此将这些数据作为数据存储可以避免多次通过 XHR 或表单提交返回到服务器。在某些情况下(例如捕获表单提交进度),可以使用 localStoragesessionStorage,并且它们的速度明显快于客户端数据库 API。例如,如果您有一个包含数百条消息的数据网格组件或收件箱,将数据本地存储在数据库中,可在用户想要搜索、过滤或排序时减少 HTTP 往返次数。系统可以按每个按键操作过滤好友列表或文本输入自动补全,从而提供更灵敏的用户体验。

提示 4:JavaScript 改进可带来显著的性能优势

JavaScript 1.6 向数组原型添加了许多其他方法。目前,除 IE 外,大多数浏览器都支持这些功能。例如:

// Give me a new array of all values multiplied by 10.
[5, 6, 7, 8, 900].map(function(value) { return value * 10; });
// [50, 60, 70, 80, 9000]

// Create links to specs and drop them into #links.
['html5', 'css3', 'webgl'].forEach(function(value) {
  var linksList = document.querySelector('#links');
  var newLink = value.link('http://google.com/search?btnI=1&q=' + value + ' spec');
  linksList.innerHTML +=  newLink;
});


// Return a new array of all mathematical constants under 2.
[3.14, 2.718, 1.618].filter(function(number) {
  return number < 2;
});
// [1.618]


// You can also use these extras on other collections like nodeLists.
[].forEach.call(document.querySelectorAll('section[data-bucket]'), function(elem, i) {
  localStorage['bucket' + i] = elem.getAttribute('data-bucket');
});

在大多数情况下,使用这些原生方法比使用常规的 for 循环(例如 for (var i = 0, len = arr.length; i &lt; len; i++))能显著提高速度。原生 JSON 解析(通过 JSON.parse())取代了我们之前一直习惯添加的 json2.js 文件。与使用外部脚本相比,原生 JSON 的速度和安全性要高得多,并且已在 IE8、Opera 10.50、Firefox 3.5、Safari 4.0.3 和 Chrome 中提供。 原生 String.trim 就是另一个很好的例子,它不仅比等效的长格式 JS 更快,而且可能更准确。从技术层面来看,这些新增的 JavaScript 功能都不是 HTML5,但它们属于近期推出的技术范畴。

提示 5:为正式版网站(而不仅仅是离线应用)使用缓存清单

两年前,WordPress 使用 Google Gears 添加了一项名为 WordPress Turbo 的功能。它本质上会在本地缓存管理控制台中使用的许多资源,从而加快对这些资源的文件访问速度。我们可以使用 HTML5 的 applicationCache 和 cache.manifest 来重现此行为。与设置 Expires 标头相比,应用缓存略有优势;因为您可以创建一个声明文件来指明可缓存的静态资源,浏览器可以对其进行大量优化,甚至可能在您使用之前预缓存这些资源。将您网站的基本结构视为模板。您有可能会发生变化的数据,但周围的 HTML 通常保持不变。借助应用缓存,您可以将 HTML 视为一系列纯模板,通过 cache.manifest 缓存标记,然后通过网络传送 JSON 以更新内容。此模型与 iPhone 或 Android 原生新闻应用的运作方式非常相似。

提示 6:启用硬件加速以提升视觉体验

在领先的浏览器中,许多视觉操作都可以利用 GPU 级加速,这可以让高度动态的视觉操作更加流畅。Firefox MinefieldIE9 已宣布支持硬件加速,Safari 在版本 5 中添加了硬件级加速。(Mobile Safari 早就支持了该功能。)Chromium 刚刚为 Windows 添加了 3D 转换和硬件加速功能,其他两个平台也将很快推出。

GPU 加速仅在非常有限的条件下启用,但 3D 转换和动画不透明度是触发该开关的最常见方式。一种虽然有点粗糙但不显眼的开启方法是:

.hwaccel {  -webkit-transform: translateZ(0); }

不过,我们无法保证一定能成功。:) 在支持并启用硬件加速后,借助 GPU 合成,动画平移、旋转、缩放和不透明度肯定会更流畅。它们的好处在于可直接在 GPU 上处理,且无需重新绘制图层内容。不过,影响网页布局的任何属性仍会相对较慢。

提示 7:对于 CPU 密集型操作,Web Worker 可提供

Web Worker 有两个显著优势:1) 速度快。2) 在执行任务时,浏览器仍能保持响应。查看 HTML5 幻灯片,了解 Worker 的运作方式。 您可以使用 Web Worker 的一些可能场景:

  • 长文档的文本格式
  • 语法突出显示
  • 图像处理
  • 图片合成
  • 处理大型数组

提示 8:HTML5 表单属性和输入类型

HTML5 引入了一系列新的输入类型,将 textpasswordfile 升级为包括 searchtelurlemaildatetimedatemonthweektimedatetime-localnumberrangecolor。浏览器对这些功能的支持各不相同,Opera 目前实现了其中的大多数功能。借助功能检测,您可以确定浏览器是否提供原生支持(并提供日期选择器或颜色选择器等界面),如果不支持,您可以继续使用 JS widget 来完成这些常见任务。 除了类型之外,我们还在常规输入字段中添加了一些实用功能。输入 placeholder 会提供默认文本,当您点击该输入框时,系统会清除该文本;autofocus 会在页面加载时将光标聚焦到该输入框,以便您立即与该字段互动。输入验证是 HTML5 中引入的另一项功能。添加 required 属性意味着,只有在该字段填充后,浏览器才会允许提交表单。此外,您还可以使用 pattern 属性为要进行测试的输入指定自定义正则表达式;如果值无效,则会阻止表单提交。这种声明式语法不仅在可读性方面进行了重大升级,还大大减少了所需的 JavaScript 代码。同样,如果不支持这些功能,您可以使用功能检测来提供回退解决方案。在此处使用原生 widget 意味着您无需发送用于显示这些 widget 所需的大量 JavaScript 和 CSS,从而加快网页加载速度并可能提高 widget 的响应速度。如需试用其中的一些输入增强功能,请查看 HTML5 幻灯片

提示 9:使用 CSS3 效果,而不是请求大型图片精灵

CSS3 提供了许多新的样式可能性,可取代我们使用图片来准确呈现视觉设计的方式。将 2 KB 的图片替换为 100 字节的 CSS 是一个巨大的胜利,更不用说您还移除了另一个 HTTP 请求。您需要熟悉以下几个属性:

  • 线性渐变和径向渐变
  • 用于圆角的 Border-radius
  • 用于阴影和光晕的 box-shadow
  • RGBA 用于 Alpha 不透明度
  • 用于旋转的转换
  • CSS 遮罩

例如,您可以通过渐变效果制作出精致的按钮,并在不使用图片的情况下复制许多其他效果。大多数浏览器都支持这些功能,您可以使用 Modernizr 等库来捕获不支持这些功能的浏览器,以便在后备情况下使用图片。

提示 10:与 XHR 相比,WebSocket 可在更少的带宽下更快地传送

WebSockets 的设计是为了应对Comet 日益普及的情况。现在,使用 WebSocket(而不是 Comet over XHR 模型)确实有优势。

WebSocket 的帧非常轻量,因此其占用的带宽通常比 XHR 少。 一些报告表明,通过网络发送的字节数减少了 35%。此外,在消息传送量较大时,性能差异会更加明显;在本测试中,XHR 的总时间比 WebSocket 长了 3500%。最后,Ericcson Labs 考虑了 WebSocket 的性能,发现通过 HTTP 进行的 ping 时间是通过 WebSocket 进行的 ping 时间的 3-5 倍,因为处理要求更高。他们得出结论,WebSocket 协议显然更适合实时应用。

其他资源

如需获取衡量和效果建议,您应使用 Firefox 扩展程序 Page SpeedYSlow。此外,适用于 Chrome 的 Speed Tracer适用于 IE 的 DynaTrace Ajax 可提供更详细的分析日志记录。