下载本文的 PDF 版本 PDF

移动设备 Web 开发的演变

构建在移动设备上表现良好的网站仍然是一项挑战。


Nicholas C. Zakas


过去几年 Web 开发中最大的变化是移动计算的显着兴起。移动电话曾经是非常有限的设备,最适合用于拨打电话和发送短信。今天的移动电话比将阿波罗 11 号送上月球的计算机10更强大,并且能够在几乎任何地方发送和接收数据。再加上用于数据传输的 3G 和 4G 网络,现在随时随地使用互联网比我的第一个互联网连接更快,我的第一个互联网连接配备了 AOL 和一个 14.4-kbps 的拨号调制解调器。

然而,尽管移动计算取得了这些强大的进步,但在移动设备上浏览 Web 的体验通常令人沮丧。iPhone 为智能手机用户打开了“真正的”互联网。这很重要,因为开发人员不再需要在 WAP(无线应用协议)等自定义语言中编写特定于移动设备的界面。相反,所有现有的网站和应用程序都可以在 iPhone 上完美运行。至少想法是这样的。

凭借快速的 iPhone 和 3G 连接,人们可能会期望移动互联网体验非常流畅。然而,Web 的发展时期正值台式机可用带宽逐年增加的时期。这意味着网站和应用程序开始变得更大,使用了更多的资源,例如 CSS(层叠样式表)、JavaScript、图像和视频。所有这一切都是为了在许多人拥有的唯一互联网上提供更好的体验:连接到家庭或办公室的有线连接。

然而,通过使用移动设备访问相同的互联网,用户再次体验到更慢的 Web。尽管蜂窝连接多年来一直在改进,但它们仍然远不如有线连接快。此外,尽管今天的智能手机功能非常强大,但与普通台式电脑相比,它们仍然相形见绌。因此,使互联网在移动设备上快速运行是一个奇怪的问题。一方面,这很像 1996 年的 Web 开发,当时每个人都连接速度很慢。另一方面,今天的移动设备比 1996 年的计算机强大得多。

延迟问题

移动 Web 性能的最大问题之一是延迟——请求和响应之间经历的延迟。任何给定的互联网连接都能够在指定的时间内传输一定量的数据,这称为带宽。延迟是阻止用户接收到最佳带宽的原因,即使他们的连接在理论上能够处理它。

有线延迟

每个互联网连接都有一定的延迟。有线连接的延迟要低得多,因为请求的数据受到的阻碍较少。有线连接允许数据在点之间更直接地传输,因此接收速度相当快。此处延迟的最大原因是电线材料的电阻。除非电线已损坏,否则这通常可以忽略不计。否则,有线连接的延迟在一段时间内保持相当稳定。

当有线网络的延迟意外变化时,原因可能是网络拥塞。如果您曾经在晚上回到家,发现您的互联网连接比早上慢,那可能是因为您社区中的每个人都在同一时间上网。也可能是您家中的几个人同时上网并使用了大量带宽(流式传输 Netflix、浏览 Web、使用 FaceTime 等)。无论网络类型如何,当延迟较高时,网络拥塞始终是一个需要考虑的因素。

无线延迟

无线互联网连接与有线连接截然不同。无论连接是 3G、4G 还是 Wi-Fi,通过空气发送和接收数据都会引入可变的延迟量。空气本身不仅会引起电阻,而且还为其他干扰源提供了开放空间。无线电、微波炉、墙壁以及任何数量的其他物理或电磁障碍物都可能对有效带宽产生不利影响。

Tom Hughes-Croucher 运行了一个模拟,以确定延迟对连接吞吐量的影响程度。2 通过仅引入 50 毫秒的延迟,他发现 300 秒内可以完成的请求数减少了近 67%。在 300 毫秒的延迟下,请求数减少了近 90%。他在模拟中使用什么来影响延迟?一个简单的微波炉。现在想象一下您每天周围的电子设备产生的所有干扰。

完成的请求数非常重要,因为典型的网页在加载时会发出数十个请求。首次访问网站会立即按顺序触发两个请求。第一个是 DNS(域名系统)请求,用于查找用户输入的域名。对该请求的响应包含该域名的 IP 地址。然后,向该 IP 地址发送 HTTP 请求以获取页面的 HTML。当然,页面通常会指示浏览器下载更多资源,这意味着在页面完全可用之前需要更多的 DNS 请求和 HTTP 请求。有线连接可以很快地完成此操作,但智能手机等无线连接会引入大量延迟。

请求首先必须从手机发送到最近的蜂窝塔。该请求通过空气传播,在此过程中会受到很大程度的干扰。一旦到达蜂窝塔,请求将被路由到移动公司服务器,该服务器使用 GPRS(通用分组无线服务)。对于 3G,这是一个 GGSN(网关 GPRS 支持节点),它充当用户和互联网之间的中介(参见图 1)。GGSN 分配 IP 地址、过滤数据包,并且通常充当通往真实互联网的网关。然后,GGSN 将请求发送到适当的位置(DNS、HTTP 或其他),响应必须从互联网一直返回到 GGSN,再到蜂窝塔,最后到手机。所有这些来回都会在系统中产生大量延迟。

更糟糕的是,移动网络只有少量的 GGSN;因此,用户与 GGSN 的距离对他们体验到的延迟具有可衡量的影响。例如,开发人员 Israel Nir 指出,从拉斯维加斯通过手机向也位于拉斯维加斯的资源发出请求实际上会导致请求首先被路由到加利福尼亚州,然后才最终到达设备。9 因为 GGSN 往往集中分布而不是分散分布,所以这种情况非常普遍。

延迟始终是无线通信的一个因素,因此开发人员在从事移动项目时需要为此做好计划。克服延迟的最佳方法是使网站或应用程序尽可能少地使用 HTTP 请求。在高延迟连接上创建新请求的开销非常高,因此,向互联网发出的请求越少,页面加载速度就越快。幸运的是,与 1996 年整个互联网速度缓慢时相比,今天有更多的工具可用于减少请求。

提高 Web 性能

在 2007 年出版的高性能网站中,Steve Souders 撰写了第一本关于 Web 性能的详尽参考书。11 行业中的许多最佳实践都可以追溯到这本重要的书。尽管这本书是在移动 Web 开发以当前形式存在之前发布的,但其中的许多建议仍然适用。

减少 HTTP 请求

高性能网站中的第一条规则是减少 HTTP 请求。这可以通过连接外部 JavaScript 和 CSS 文件来完成。许多站点包含数百 KB 的 JavaScript 和 CSS,以创建更丰富的体验。在可能的情况下,服务器上的多个文件应合并为一个下载到浏览器的文件。理想的设置是每个页面加载最多有两个外部 JavaScript 文件引用和两个外部 CSS 文件引用(其他资源可以在页面加载完成后下载)。

传统上,文件是在构建时连接的。现在,更常见的是使用 CDN(内容交付网络)在运行时进行连接。Google 甚至发布了一个名为mod_concat3 的 Apache 模块,它可以轻松地在运行时动态连接文件。该模块通过使用特殊的 URL 格式来使用单个请求下载多个文件。例如,假设您想在页面中包含以下文件


http://www.example.com/assets/js/main.js
http://www.example.com/assets/js/utils.js
http://www.example.com/assets/js/lang.js

mod_concat 允许您使用以下 URL 将它们组合成一个请求,而不是单独引用这些文件

http://www.example.com/assets/js??main.js,utils.js,lang.js

此 URL 连接main.js, utils.jslang.js按指定的顺序组合成单个响应。请注意双问号,它向服务器指示此 URL 应使用连接行为。在服务器上设置 mod_concat,然后将服务器用作 CDN 后面的源,可以为生成的文件提供更好的边缘缓存。

消除图像

图像是互联网上最大的 Web 组件之一。根据 HTTP Archive(它监控互联网上排名前一百万的网站的性能特征),图像平均每个页面占用 793 KB(截至 2013 年 1 月)。1 最接近的下一个组件是 JavaScript,为 207 KB。显然,减少页面总大小的最快方法是减少正在使用的图像数量。

CSS3 是 CSS 的最新版本,它提供了多种消除图像的方法。以前需要图像的许多视觉效果现在可以直接在 CSS 中声明式地完成。例如,创建一个具有圆角、阴影和渐变背景的按钮曾经需要多个图像,以及一位图形设计师来创建它们,但今天只需几行 CSS 即可实现相同的效果。

右侧图像中所示的按钮是使用以下 CSS 和常规<button>元素生成的


.button {
    border-top: 1px solid #96d1f8;
    padding: 20px 40px;
    color: white;
    font-size: 24px;
    font-family: Georgia, serif;
    text-decoration: none;
    vertical-align: middle;

    /* 为背景创建渐变 */
    background: linear-gradient(top, #3e779d, #65a9d7);

    /* 圆角 */
    border-radius: 40px;

    /* 整个按钮周围的阴影 */
    box-shadow: rgba(0,0,0,1) 0 1px 0;

    /* 仅文本的阴影 */
    text-shadow: rgba(0,0,0,.4) 0 1px 0;
}

CSS 的关键部分(取代了原本需要图像的部分)是

background: linear-gradient(top, #3e779d, #65a9d7)。这为背景创建了一个 CSS 渐变7。所有主要浏览器的最新版本都不再需要供应商前缀。此行表示创建从顶部开始的线性渐变,颜色从#3e779d开始,到颜色#65a9d7.

结束。border-radius: 40px。这将按钮的角变成圆角,半径为 40 像素。所有主要浏览器的最新版本都支持无前缀版本。

box-shadow: rgba(0,0,0,1) 0 1px 0。这会在整个按钮周围创建一个阴影。框阴影4 可以以多种方式使用,但在本例中,它用作按钮底部的单像素偏移量。颜色后面的数字是 x 偏移、y 偏移和模糊半径。

text-shadow: rgba(0,0,0,.4) 0 1px 0。这将创建一个仅应用于文本的阴影。文本阴影5 与框阴影具有相同的语法。

因此,只需四行 CSS 代码即可替换此按钮可能需要的多个图像。此外,创建此效果所需的字节数比使用图像所需的字节数少得多。尽可能用 CSS 替换图像是一个好主意。它可以减少 HTTP 请求的数量,并最大限度地减少视觉设计所需的总字节数。

避免重定向

高性能网站中的规则 11 是避免重定向。重定向的工作方式类似于电话上的呼叫转移。服务器不是返回实际内容,而是返回一个带有Location标头的响应,指示浏览器应联系哪个 URL 以获取其期望的内容。这可能会持续很长时间,因为一个重定向会导致另一个重定向。每个重定向都会带来完整请求及其所有延迟的开销。在台式机上,后果可能不会立即显现,但在移动设备上,重定向可能会非常缓慢。

许多网站和应用程序都采用了使用www.example.com用于其桌面站点,并使用m.example.com用于其移动站点的约定。他们错误的假设是,用户会根据他们想要的版本输入网站的完整域名。实际上,人们倾向于只输入主机名,例如example.com,这意味着服务器需要弄清楚如何处理该请求。通常,第一步是重定向到域名的 www 版本,这是运行 Web 应用程序的服务器。然后,应用程序查看用户代理字符串并确定设备是移动设备,从而提示第二次重定向到域名的m版本。Bing 就是这样做的——但结果很糟糕。

图 2 中 Web Inspector 窗口的屏幕截图显示了两个重定向:第一个是从bing.comwww.bing.com;第二个是从www.bing.comm.bing.com。Web Inspector 中的延迟值是指浏览器等待接收响应的时间。请注意,每个重定向都与延迟相关联,因此实际页面直到第一个请求发出后 1,448 毫秒才开始下载。这在用户体验启动并运行之前增加了一秒半的时间,而实际上什么也没做。

避免重定向在移动 Web 开发中绝对至关重要。重定向具有任何 HTTP 请求的所有开销,但不会返回任何有用的信息。这就是为什么 Web 应用程序开始基于请求的用户代理字符串从同一域名提供移动版本和桌面版本的原因。域名是以www还是m还是其他任何内容开头都无关紧要;避免重定向并能够从接收请求的域名提供完整的体验,这对网站用户来说是一次性能上的胜利。

移动设备限制

直到最近,Web 开发人员还不太需要担心人们用来访问其应用程序的设备。开发人员可以假设,如果计算机能够运行 Web 浏览器,那么它可能也能够访问他们的应用程序。然而,移动设备非常不同。它们都具有不同的性能特征,但它们有一个共同点:它们不如台式机或笔记本电脑强大。因此,开发人员不仅需要考虑谁在访问应用程序,还需要考虑他们使用什么设备来访问。

缓慢且昂贵的 JavaScript

即使移动设备浏览器相当不错,但其 JavaScript 引擎的性能也比台式电脑慢一个数量级。iOS 中的问题是,有人可能会使用 Safari 或另一个应用程序中的嵌入式 WebView 访问应用程序。虽然 Safari 具有相当快的 JavaScript 引擎,但嵌入式 WebView 没有。因此,根据用户是否使用 Safari,iOS 中存在两种不同的 JavaScript 性能特征。图 3 中的图表显示了几个流行的浏览器的 SunSpider 基准测试结果。12

请注意,iOS 中嵌入式 WebView 的性能实际上比 Internet Explorer 8 的性能更差。然而,即使对于性能更好的浏览器,台式机和移动设备上的 JavaScript 引擎性能之间仍然存在巨大差异。

移动设备上 JavaScript 的另一个方面是相关的性能成本。与台式电脑不同,移动设备有电池,电池可能会因无线电(蜂窝、Wi-Fi、蓝牙)、网络访问以及执行 JavaScript 等代码而耗尽。任何时候执行代码,CPU 都会消耗电量;因此,执行代码花费的时间越多,消耗的电量就越多。运行 JavaScript 会更快地耗尽电池电量。

移动设备上 JavaScript 的这些方面意味着开发人员需要谨慎对待 JavaScript 的使用。尽可能最好避免使用 JavaScript。例如,使用 CSS 动画6 或 CSS 过渡8 创建动画比为此任务使用 JavaScript 更有效。基于 JavaScript 的动画会以频繁的间隔运行大量代码,以创建动画的外观。声明式 CSS 动画和过渡允许浏览器找出创建这些效果的最佳方式,这可能意味着完全绕过 CPU。

移动设备上的 JavaScript 应保持较小的尺寸和执行时间。这些设备上的 JavaScript 环境比台式电脑上的环境要受限得多,因此一个好的经验法则是仅使用完成手头目标绝对必要的 JavaScript。

更少的内存

移动设备的另一个重要限制是内存容量。台式机和笔记本电脑往往有数 GB 的内存,而移动设备的内存要少得多。直到最近,移动设备才达到 1 GB 的内存,例如 iPhone 5 和 Samsung Galaxy S III。较旧的设备内存更少,这需要成为移动 Web 开发的考虑因素——尤其考虑到浏览器实际上无法访问设备上的所有内存。

Web 开发人员不习惯担心内存,因为台式机和笔记本电脑上的内存非常充足。然而,移动设备上的少量内存以及浏览器中使用内存的方式意味着很容易在不知不觉中造成内存问题。即使是常规操作,例如将新节点添加到 DOM(文档对象模型)中,如果操作不当也可能导致内存问题。当内存问题变得太大时,浏览器会变得缓慢或无响应,并最终崩溃。

图像是内存方面最令人担忧的领域之一。加载到 DOM 中的图像,无论它们是否实际在屏幕上可见,都会占用内存。为移动设备开发基于照片的 Web 应用程序的开发人员经常遇到导致浏览器崩溃的问题。照片共享网站 Flickr 在首次尝试在 iOS 中创建幻灯片时遇到了问题。每当加载大约 20 张图像时,浏览器就会崩溃。Flickr 工程师 Stephen Woods 解释说,防止这种情况发生的唯一方法是定期从 DOM 中删除不再需要的元素。14 本质上,Flickr 决定在 DOM 中一次只保留几张照片,并在必须添加另一张照片时始终删除一张。

Flickr 的部分问题是由硬件加速图形引起的,硬件加速图形使用 GPU 来计算需要在屏幕上绘制的内容。GPU 比 CPU 快得多,因此结果是显示器的刷新速度更快。CSS 动画和过渡在移动设备上尽可能地进行硬件加速(始终在 iOS 中,并且在 Android 3+ 中也很常见)。虽然这创造了更流畅的体验,但也需要更多内存。

为了使 GPU 工作,必须合成屏幕的某些部分。合成元素作为图像存储在内存中,并且需要(宽度 x 高度 x 4)字节来存储。因此,100 x 100 的图像实际上占用 40,000 字节(或约 39 KB)的内存。页面上合成元素越多,使用的内存就越多,浏览器崩溃的可能性就越大。

图像不是浏览器中唯一合成的元素。DOM 元素也可以由于某些 CSS 规则而被合成。在移动 Web 开发的早期,开发人员注意到硬件加速图形速度更快,他们试图找出在不需要动画时也强制进行硬件加速的方法。许多博客文章鼓励使用某些 CSS 属性来强制元素进行硬件加速13。一般来说,任何时候使用 CSS 应用 3D 变换,该元素都会被转换为图像,然后像任何其他图像一样被合成。例如,有些人建议使用如下代码来触发硬件加速


.box {
    transform: translateX(0);
}

transform属性包含 3D 变换以平移元素的位置。该元素实际上并没有移动,因为平移为 0,但它仍然会触发硬件加速。

过于热心的开发人员开始在任何地方添加像这样的 3D 变换,认为这会加快移动 Web 体验。不幸的是,它产生了内存过度使用导致浏览器崩溃的意外副作用。即使在浏览器没有崩溃的情况下,体验也会随着内存的耗尽而变慢。

硬件加速是 Web 页面的一项有用功能,但必须负责任地使用它。例如,在整个页面上启用硬件加速肯定会导致内存问题,并可能导致崩溃。开发人员不应过度使用硬件加速,仅在有意义的地方应用它,最好是在页面的小部分上,而将其余部分保留为普通图形。

结论

移动设备 Web 开发是传统上一直相当简单的努力中的一个独特难题。与 10 年前的台式电脑相比,移动设备拥有强大的功能,但它们也存在严重的局限性,而这些局限性在仅为台式机开发网站时不必处理。无线数据传输的延迟自动意味着下载时间较慢,并且需要警惕地将任何给定页面上的请求总数保持在最低限度。较慢的 JavaScript 引擎和较少的内存意味着在台式机上快速流畅运行的同一网页在移动设备上可能会非常缓慢。

简而言之,移动设备迫使 Web 开发人员思考他们以前从未考虑过的事情。Web 应用程序现在必须考虑正在使用的设备类型,以确定用户的最佳体验。具有高延迟连接、较慢的 CPU 和较少内存的移动设备与具有有线连接、快速 CPU 和几乎无限内存的台式机一样需要得到满足。Web 开发人员现在比以往任何时候都更需要密切关注他们如何设计界面,因为存在这些限制。字节数、请求数、内存使用量和执行时间都需要成为移动设备 Web 开发持续发展过程中的考虑因素。

参考文献

1. HTTP Archive。 http://httparchive.org/

2. Hughes-Croucher, T. 2009. An engineer's guide to bandwidth; http://developer.yahoo.com/blogs/ydn/posts/2009/10/a_engineers_gui/

3. modconcat。 http://code.google.com/p/modconcat/

4. Mozilla Developer Network。 2012. box-shadow; https://mdn.org.cn/en-US/docs/CSS/box-shadow

5. Mozilla Developer Network。 2012. text-shadow; https://mdn.org.cn/en-US/docs/CSS/text-shadow

6. Mozilla Developer Network。 2012. Using CSS animations; https://mdn.org.cn/en-US/docs/CSS/Tutorials/Using_CSS_animations

7. Mozilla Developer Network。 2013. Using CSS gradients; https://mdn.org.cn/en-US/docs/CSS/Using_CSS_gradients

8. Mozilla Developer Network。 2013. Using CSS transitions; https://mdn.org.cn/en-US/docs/CSS/Tutorials/Using_CSS_transitions

9. Nir, I. 2012. Latency in mobile networks—the missing link; http://calendar.perfplanet.com/2012/latency-in-mobile-networks-the-missing-link/

10. Robertson, G. 2009. How powerful was the Apollo 11 computer? http://downloadsquad.switched.com/2009/07/20/how-powerful-was-the-apollo-11-computer/

11. Souders, S. 2007 High Performance Web Sites: Essential Knowledge for Front-end Engineers. O'Reilly Media.

12. SunSpider JavaScript Benchmark; http://www.webkit.org/perf/sunspider/sunspider.html

13. Walsh, D. 2012. Force hardware acceleration in WebKit with translate3d; http://davidwalsh.name/translate3d

14. Woods, S. 2011. Lessons learned from the Flickr Touch Lightbox. Code.flickr.com; http://code.flickr.net/2011/07/20/lessons-learned-from-the-flickr-touch-lightbox/

喜欢或讨厌?请告诉我们

[email protected]

Nicholas C. Zakas 是一位 Web 技术专家、作家和演讲者。他目前在 Box 工作,之前曾在 Yahoo! 工作了近五年,在那里他担任 Yahoo! 首页的前端技术主管,并且是 YUI 库的贡献者。他是Maintainable JavaScript (O'Reilly, 2012)、Professional JavaScript for Web Developers (Wrox, 2012)、High Performance JavaScript (O'Reilly, 2010) 和 Professional Ajax (Wrox, 2007) 的作者。Zakas 是开发最佳实践的坚定倡导者,包括渐进增强、可访问性、性能、可扩展性和可维护性。他定期在 http://www.nczonline.net/ 上撰写博客,并且可以通过 Twitter @slicknet 找到他。

© 2013 1542-7730/13/0200 $10.00

acmqueue

最初发表于 Queue vol. 11, no. 2
Digital Library 中评论本文





更多相关文章

Shylaja Nukala, Vivek Rau - 为什么 SRE 文档很重要
SRE(站点可靠性工程)是一种工作职能、一种思维模式,以及一套用于使 Web 产品和服务可靠运行的工程方法。SRE 在软件开发和系统工程的交叉点运作,以解决运营问题,并设计工程解决方案,从而可扩展、可靠且高效地设计、构建和运行大型分布式系统。成熟的 SRE 团队可能拥有与许多 SRE 职能相关的明确定义的文档体系。


Taylor Savage - Web 组件化
在当今的软件工程领域,没有哪项任务能像 Web 开发那样艰巨。一个典型的 Web 应用程序规范可能如下:该应用必须在各种浏览器上运行。它必须以 60 fps 的帧率运行动画。它必须对触摸操作立即响应。它必须符合一套特定的设计原则和规范。它必须在几乎所有可以想象到的屏幕尺寸上工作,从电视和 30 英寸显示器到手机和手表表面。它必须在长期内得到良好的工程设计和可维护性。


Arie van Deursen - 超越页面对象:使用状态对象测试 Web 应用程序
Web 应用程序的端到端测试通常涉及通过 Selenium WebDriver 等框架与 Web 页面进行复杂的交互。隐藏此类 Web 页面复杂性的推荐方法是使用页面对象,但首先需要回答一些问题:在测试 Web 应用程序时应创建哪些页面对象?应在页面对象中包含哪些操作?给定页面对象,应指定哪些测试场景?


Rich Harris - 消除准入壁垒
一场战争正在 Web 开发领域展开。一方是工具制造者和工具用户的先锋,他们热衷于摧毁过时的旧观念(在这个领域中,“旧”意味着任何一个月前在 Hacker News 上首次亮相的东西)以及关于转译器等的激烈辩论。





© 保留所有权利。

© . All rights reserved.