为 Web 应用程序提速的 50 条秘技

阅读数:4095 2012 年 11 月 26 日

话题:JavaScript性能调优HTML5语言 & 开发

Jatinder Mann是微软 Internet Explorer 产品的一名项目经理,在 BUILD 2012 大会上,他做了题为“提高 HTML5 应用和网站性能的 50 条秘技(50 performance tricks to make your HTML5 apps and sites faster)”的演讲,介绍了很多为 Web 应用程序提速的技巧。

Mann 的建议是按照下面六个原则组织的。

1. 快速响应网络请求。

  • 避免重定向。排名前 1000 的网站中,63% 使用了重定向。如果不执行重定向的话,页面速度可以提高 10%。
  • 避免Meta-refresh。世界上 14% 的 URL 使用了 Meta-refresh。
  • 尽可能通过 CDN 定位用户,使服务器响应时间最小化。
  • 从不同的域下载资源,使并发连接的应用最大化。
  • 复用连接。不要在响应请求时关闭连接。
  • 确保页面加载不会因合作伙伴网站提供的数据而延迟。
  • 了解耗时的网络组件,如重定向、缓存、DNS、请求和响应等。在 IE 9 和 10 中可以使用Navigation Timing API来测量浏览器花在每个操作上的时间。

2. 最小化下载的字节数。

加载页面时,要尽量减少下载的数据量。平均而言,每个页面要下载的数据量达 777KB,其中有 474KB 的图片、128KB 的脚本和 84KB 的 Flash。

  • 请求 gzip 压缩的内容。
  • 将资源保存在本地的包中,比如为 Windows 商店应用生成的包资源索引(Package Resource Index)文件。这样当需要这些资源时就可以很容易地获取到。
  • 使用 HTML5 App Cache 缓存动态资源。App Cache 会只下载一次资源,从而避免多次网络行程。当应用的版本号发生变化时,它会自动重新下载相应资源。
  • 尽量在响应中使用“Expires”字段来提供可缓存的内容。
  • 通过设定请求的If-Modified-Since字段来使用条件请求。
  • 缓存数据请求,如 HTTP、XML 和 JSON 等,因为大约 95-96% 的请求不会整天变化。虽然这个想法很合理,但实际缓存接收到的请求的网站所占比重还不到 1%。
  • 用大写将文件命名标准化。虽然服务器可能把 Icon.jpg 当作 icon.jpg,但是对于 Web 平台而言,它们是不同的资源,对应不同的网络请求。

3. 高效地组织标记。

对于 IE 而言,请使用最新的标记标准,因为它速度最快。IE 10 也能识别早期的 IE6-IE9 标记风格,但是其速度不如新的标记风格。

  • 特定的业务 Web 应用可能需要强制 IE 运行于传统模式,请使用 HTTP 头字段“X-UA-Compatible: IE=EmulateIE7”来代替 HTML 标签 ,这样速度会快一些。
  • 为了平滑地渲染,样式表应该链接在页面顶部的 <head> 之中的 <title> 后面。
  • 绝对不要在页面底部链接样式表。否则加载页面时可能会出现闪烁。
  • 对于分层样式,不要使用“@import”,因为它是同步的,会阻塞 CSS 数据结构的创建和屏幕绘制。
  • 避免样式的嵌入和内联,因为它会强制浏览器在 HTML 和 CSS 解析器之间进行上下文切换。
  • 仅包含必要的样式。不要下载和解析用不到的样式。
  • 仅在页面底部链接 JavaScript。这可以确保脚本执行时图片和 CSS 等资源已经加载,无需等待,也避免了上下文切换。
  • 不要在页面开头链接 JavaScript。如果某些脚本必须在开始处加载的话,请使用“defer”属性。
  • 不要内联 JavaScript,这样可以避免上下文切换。
  • 使用“async”属性加载 JavaScript,这样整个脚本就可以异步加载和执行。
  • 避免冗余代码。世界上 52% 的网页包含 100 行甚至更多的冗余代码,比如一个 JavaScript 文件被链接了两次。
  • 将一个 JS 框架标准化,无论是 jQuery,Dojo,Prototype.js 还是其他框架。浏览器没有必要加载多个功能基本相同的框架。
  • 不要加载 FB 和 Twitter 等网站的脚本,只是看起来很酷而已,它们会争用资源。

4. 优化多媒体资源的使用。

图片是最常用的资源,每个页面平均会下载 58 张图片。

  • 尽量避免下载太多图片,根据页面加载时间将图片最大数量控制在 20-30 之间。
  • 使用 Image Sprites 将多个图片组合成一个。该技术可以减少网络连接数,也会减少下载的字节数并节省 GPU 处理周期。
  • 手动创建 Image Sprites,因为工具创建的可能会留下较大的空洞,这会加大需要下载的数据量,也需要更多的 GPU 处理周期。
  • 使用 PNG 格式的图片,该格式在下载大小、解码时间、兼容性和压缩率之间实现了完美的折中。JPEG 格式可以用于照片。
  • 使用原始的图像分辨率,这样可以避免下载不必要的数据以及缩放所需的 CPU 处理。
  • 尽可能使用 CSS3 Gradient 替代图片。
  • 尽可能使用 CSS3 border radius 替代图片。
  • 使用 CSS3 Transform 来创建移动、旋转和倾斜效果。
  • 对于小型的单个图片,可以使用Data URI。这样可以节省一张图片的下载量。
  • 避免复杂的 SVG,因为它们会延长下载和处理时间。
  • 当包含 HTML5 时,指定一个预览图片。这样浏览器就不必下载整个视频文件来确定预览图片了。
  • 使用 HTML5 来代替 Flash、Silverlight 或 QuickTime。HTML5 速度更快,而且其他几种形式的运行时插件会消耗系统资源。
  • 主动地以异步方式下载富媒体资源并将其保存在 App Cache 中。

5. 编写快速的 JavaScript。

  • 在 JavaScript 中进行数学运算时尽量使用整型。JavaScript 的浮点运算比相应的整型运算耗费的时间要多得多。在进行数学运算,特别是计算密集型运算时,请使用 Math.floor 和 Math.ceil 将浮点数转换为整型数。
  • 降低 JavaScript 代码量,这样不但可以减少下载的数据量,而且能够提供更好的运行时性能。
  • 按需初始化 JS。当需要时动态加载 JS。
  • 通过缓存变量(如 document 和 body 等)使 DOM 交互减到最少。
  • 使用内置的 DOM 代码,如 element.firstChild 或 node.nextSibling 等。这些代码都是高度优化的,相对于第三方库能提供更好的性能。
  • 访问大量 DOM 元素时,使用 querySelectorAll。
  • 使用.innerHTML 来构建动态页面。
  • 批量标记更改。
  • 维护小巧而健壮的 DOM——将其元素数目控制在 1000 以内。.
  • JSON 快于 XML。
  • 使用浏览器的 JSON 原生方法。
  • 不要滥用正则表达式。

6. 知道你的应用在做什么。

  • 理解 JavaScript 定时器,了解 setTimeout 和 clearInterval。除非确定要使用定时器完成一些功能,否则不要启动定时器。组合定时器也是如此。
  • 如果监视器的刷新率是 60Hz,请将显式帧的定时器调整为 16.7 ms。
  • 在 IE 10、Chrome 和 Firefox 中,图形处理请使用 requestAnimationFrame 动画函数。其绘制通过回调实现,因此不需要定时器。
  • 使用可见性 API(document.hidden 和 Visibilityhange)来确定应用程序的可见状态,如果页面是隐藏的,就关闭该活动。这样可以节省 CPU 和电池寿命。

Mann 建议在 IE 中使用Windows Performance Tools来测试 Web 页面的性能, 并以减少 CPU 时间和增加并发性为目标进行优化。

参考英文原文50 Tricks for Faster Web Applications


给 InfoQ 中文站投稿或者参与内容翻译工作,请邮件至editors@cn.infoq.com。也欢迎大家通过新浪微博(@InfoQ)或者腾讯微博(@InfoQ)关注我们,并与我们的编辑和其他读者朋友交流。