Eric Bidelman
简介
针对移动网站进行开发是当今的热门话题。今年,智能手机的销量首次超过了个人电脑。越来越多的用户使用移动设备浏览网页,这意味着,对于开发者来说,针对移动浏览器优化网站变得越来越重要。
对于许多开发者来说,“移动”战场仍然是一片未知的领域。
许多用户都有现有的旧版网站,完全忽略了移动用户。相反,该网站主要针对桌面浏览进行了设计,在移动浏览器中表现不佳。本网站 (html5rocks.com) 也不例外。在发布之初,我们在移动版网站上投入的资源很少。
创建适合移动设备的 html5rocks.com
作为一项练习,我认为将 html5rocks(一个现有的 HTML5 网站)改造成适合移动设备的版本会很有趣。我主要关心的是,针对智能手机进行开发所需的工作量是否最少。我的练习目标不是创建一个全新的移动网站并维护两个代码库。这将需要很长时间,而且会浪费大量时间。我们已经定义了网站的结构(标记)。我们查看了外观和风格 (CSS)。核心功能 (JS) 已到位。我的意思是,很多网站都面临着同样的问题。
本文将介绍我们如何创建针对 Android 和 iOS 设备进行了优化的 html5rocks 移动版。只需在支持其中一种操作系统的设备上加载 html5rocks.com,即可看到差异。没有重定向到 m.html5rocks.com 或其他此类恶意网站。您可以直接使用 html5rocks,还可以获得额外的好处:在移动设备上呈现效果出色且运行良好。
桌面版 (html5rocks.com)(左)和移动版 (html5rocks.com)
CSS 媒体查询
HTML4 和 CSS2 已经支持与媒体相关的样式表一段时间了。例如:
会定位到打印设备,并在页面内容打印时为其提供特定样式。
CSS3 更进一步地扩展了媒体类型的概念,并通过媒体查询增强了其功能。媒体查询允许更精确地标记样式表,从而扩大了媒体类型的实用性。这样,您就可以针对特定范围的输出设备自定义内容的呈现方式,而无需更改内容本身。这非常适合需要修改的现有布局!
您可以在外部样式表的 media 属性中使用媒体查询来定位屏幕宽度、设备宽度、屏幕方向等。如需查看完整列表,请参阅 W3C 媒体查询规范。
定位屏幕尺寸
在以下示例中,phone.css 适用于浏览器认为的“手持设备”或屏幕宽度小于等于 320 像素的设备。
media='handheld, only screen and (max-device-width: 320px)' href='phone.css'>
在媒体查询前面加上“only”关键字会导致不符合 CSS3 标准的浏览器忽略该规则。
以下代码会定位到 641 像素到 800 像素之间的屏幕尺寸:
media='only screen and (min-width: 641px) and (max-width: 800px)' href='ipad.css'>
媒体查询还可出现在内嵌
media="handheld"
我们需要暂停一下,讨论一下 media="handheld"。
事实上,Android 和 iOS 会忽略 media="handheld"。该声明声称,用户将错过以 media="screen" 为目标平台的样式表提供的高端内容,并且开发者不太可能维护质量较低的 media="handheld" 版本。因此,为了践行“完整 Web”的口号,大多数新型智能手机浏览器会直接忽略手持设备样式表。
理想情况下,应使用此功能定位移动设备,但各种浏览器实现此功能的方式有所不同:
有些设备只读取手持设备样式表。
有些设备只读取手持设备样式表(如果有),否则默认使用屏幕样式表。
有些设备会同时读取手持设备样式表和屏幕样式表。
有些只读取屏幕样式表。
Opera Mini 不会忽略 media="handheld"。让 Windows Mobile 识别 media="handheld" 的诀窍是将屏幕样式表的媒体属性值转换为大写形式:
html5rocks 如何使用媒体查询
在移动版 html5rocks 中,大量使用了媒体查询。借助这些工具,我们无需对 Django 模板标记进行重大更改,即可调整布局… 真是太棒了!此外,他们对各种浏览器的支持也非常出色。
在每个网页的
中,您会看到以下样式表:
media='all' href='/static/css/base.min.css' />
media='only screen and (max-width: 800px)' href='/static/css/mobile.min.css' />
base.css 一直是 html5rocks.com 的主要外观和风格,但现在,我们将针对屏幕宽度小于 800 像素的设备应用新样式 (mobile.css)。其媒体查询涵盖智能手机(~320 像素)和 iPad(~768 像素)。
效果:我们会逐步替换 base.css 中的样式(仅在必要时),以便在移动设备上获得更好的外观。
mobile.css 强制执行的一些样式更改:
减少网站上的额外空白/内边距。屏幕较小,因此空间非常宝贵!
移除了 :hover 状态。它们从未在触控设备上出现过。
将布局调整为单列。我们稍后会对此进行详细介绍。
移除了网站主容器 div 周围的 box-shadow。较大的边框阴影会降低页面性能。
使用 CSS 弹性盒模型 box-ordinal-group 更改了首页上各个版块的排序。
您会发现,“按主要 HTML5 功能组学习”位于网页版首页上的“教程”部分之前,但位于移动版首页上的“教程”部分之后。这种排序方式更适合移动设备,并且无需更改标记。CSS flexbox 真棒!
移除了 opacity 更改。更改 Alpha 值会降低移动设备上的性能。
移动元标记
Mobile WebKit 支持一些实用功能,可让用户在某些设备上获得更好的浏览体验。
视口设置
第一个元设置(也是您最常用的设置)是视口属性。设置视口可告知浏览器内容应如何适应设备屏幕,并告知浏览器网站已针对移动设备进行优化。例如:
指示浏览器将视口设置为设备的宽度,初始缩放比例为 1。此示例还支持缩放,这对于网站来说可能很有用,但对于 Web 应用来说却不太实用。我们可以使用 user-scalable=no 阻止缩放,或将缩放限制在一定水平:
content="width=device-width, initial-scale=1.0, minimum-scale=0.5 maximum-scale=1.0">
注意: width 也可以采用像素值。在 iPhone 和一些其他智能手机上,设置 width=320 会产生与 width=device-width 相同的结果。请注意,并非所有手机的宽度都完全相同,因此最好使用 device-width,让浏览器自行确定其余内容。
Android 扩展了视口元标记,允许开发者指定网站是针对哪种屏幕分辨率开发的:
target-densitydpi 的可能值包括 device-dpi、high-dpi、medium-dpi、low-dpi。
如果您想针对不同的屏幕密度修改网页,请使用 -webkit-device-pixel-ratio CSS 媒体查询和/或 JavaScript 中的 window.devicePixelRatio 属性,然后将 target-densitydpi 元属性设置为 device-dpi。这样,Android 便不会在网页中执行缩放,您可以通过 CSS 和 JavaScript 为每种密度进行必要的调整。
如需详细了解如何定位设备分辨率,请参阅 Android 的 WebView 文档。
全屏浏览
还有两个元数据值是 iOS-sfic。apple-mobile-web-app-capable 和 apple-mobile-web-app-status-bar-style 将以类似应用的全屏模式渲染页面内容,并使状态栏半透明:
如需详细了解所有可用元选项,请参阅 Safari 参考文档。
主屏幕图标
iOS 和 Android 设备还接受 rel="apple-touch-icon"(iOS)和 rel="apple-touch-icon-precomposed"(Android)作为链接。当用户将您的网站添加为书签时,这些图标会在用户的主屏幕上显示一个类似应用的醒目图标:
href="/static/images/identity/HTML5_Badge_64.png" />
href="/static/images/identity/HTML5_Badge_64.png" />
html5rocks 如何使用移动设备元标记
将所有内容整合在一起,下面是 html5rocks 的
部分的代码段:...
content="width=device-width, initial-scale=1.0, minimum-scale=1.0" />
href="/static/images/identity/HTML5_Badge_64.png" />
href="/static/images/identity/HTML5_Badge_64.png" />
...
垂直布局
在小屏幕上,垂直滚动比水平滚动更方便。
对于移动设备,最好将内容保持单列竖屏布局。
对于 html5rocks,我们使用了 CSS3 媒体查询来创建此类布局。同样,无需更改标记。
整个网站采用单列垂直布局。
移动优化
我们进行的大多数优化都是一开始就应该完成的。例如减少网络请求数量、JS/CSS 压缩、gzip 压缩(App Engine 上免费提供)和尽量减少 DOM 操作。这些技巧是常见的最佳实践,但在仓促发布网站时,有时会被忽略。
自动隐藏地址栏
移动浏览器的屏幕空间不如桌面浏览器。
更糟糕的是,在不同的平台上,您有时会在屏幕顶部看到一个巨大的地址栏,即使网页加载完毕也是如此。
解决此问题的一个简单方法是使用 JavaScript 滚动页面。即使只向下移动一个像素,也能解决恼人的地址栏问题。为了在 html5rocks 上强制隐藏地址栏,我将 onload 事件处理脚本附加到 window 对象,并将页面垂直滚动了 1 像素:
丑陋的地址栏占据了屏幕空间。
// Hides mobile browser's address bar when page is done loading.
window.addEventListener('load', function(e) {
setTimeout(function() { window.scrollTo(0, 1); }, 1);
}, false);
由于桌面设备不需要此监听器,因此我们还将其封装在 is_mobile 模板变量中。
减少网络请求,节省带宽
众所周知,减少 HTTP 请求数量可以显著提升性能。移动设备进一步限制了浏览器可以建立的并发连接数量,因此,减少这些多余请求对移动网站的益处会更大。此外,由于手机的带宽通常有限,因此尽可能减少每个字节的大小至关重要。您可能在让用户付费!
以下是我们为最大限度地减少网络请求并降低 html5rocks 的带宽所采取的一些方法:
移除 iframe - iframe 速度缓慢!大量延迟来自教程页面上的第三方分享 widget(Buzz、Google Friend Connect、Twitter、Facebook)。这些 API 是通过
我们的代码美化打印程序和 Modernizr 会包含在每个网页中,即使它们从未使用过也是如此。Modernizr 非常棒,但它会在每次加载时运行一系列测试。其中一些测试会对 DOM 进行耗时的修改,并会减慢页面加载速度。现在,我们只会在实际需要这些库的页面上添加这些库。-2 个请求 :)
其他性能调整:
将所有 JS 移至页面底部(如有可能)。
移除了内嵌