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

简介

大多 HTML5 旨在为到目前为止通过 JavaScript 库实现的组件和技术提供原生浏览器支持。使用这些功能(如果存在)最终可以为您的用户带来更快的体验。在此教程中,我不会回顾您在 Yahoo 的卓越性能网站、Google Page Speed 文档让网络变得更快网站上所做的出色性能研究。因此,我将重点介绍如何立即使用 HTML5 和 CSS3,以便让您的 Web 应用响应更快。

提示 1:使用网络存储代替 Cookie

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

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

// 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 幻灯片。 以下是您可以使用 Web Workers 的一些可能情况:

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

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

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

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

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

  • 线性渐变和径向渐变
  • 圆角的边框半径
  • 用于实现阴影和发光的方框阴影
  • 用于 Alpha 不透明度的 RGBA
  • 用于旋转的转换
  • CSS 遮罩

例如,您可以使用渐变效果创建非常精致的按钮,并复制许多其他效果(无效果图片)。浏览器对大多数此类功能都非常支持,因此您可以使用 Modernizr 之类的库来捕获不支持这些功能的浏览器,以便在后备情形中使用图片。

提示 10:使用 WebSocket 实现更快的传送速度,且带宽低于 XHR

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。 此外,Speed Tracer for ChromeDynaTrace Ajax for IE 也提供更详细的分析日志记录。