智能手机的普及,已经把高质量的网页浏览带给了移动用户。虽然目前尚有许多新特性未被手机浏览器所支持,但人们已经开始关注如何为智能手机定制页面了。

这里,我们来一起讨论一下,如何以最好的方式,将现有的网站,为智能手机而优化。

本文的所有代码均来自http://www.html5rocks.com/en/mobile/mobifying.html,如果您对其中的任何技术细节存在疑问,请以原文为准。

CSS Media Query

现在的HTML4及CSS2已经能够支持情境CSS,比如:


这样的代码仅仅在打印时才会渲染printer.css。这其中的秘诀在于media属性,具体的可取值可以参考W3C的文献。那么我们该如何利用这一点来针对移动设备做定制呢?考虑如下代码:


由于only的存在,这段代码所指向的CSS只有在手持设备上,当且仅当设备屏宽不超过320px时才会导入,而针对普通的桌面浏览器,这一条就毫无作用。类似的,以下代码就只在屏宽641-800px的设备上加载,而这正是我们需要给iPad所设置的:


CSS的Media Query同时也支持嵌入式的CSS代码,如下:


说到这儿,如果你真正尝试过上述代码,就会发现,实际上Android和iOS都无视了media="handheld"处的代码。这是个奇怪的现象,但是如果你曾经开发过移动设备网页,就不难理解了。因为早期的移动设备性能都比较差,在处理网页上捉襟见肘,因此当提及media="handheld"时,它往往意味着低体验的页面。Android和iOS为了避免与10年前的手机显示出同样的效果,最终还是选择无视这个media="handheld"

而Opera Mini因其所属的设备大多性能不够优越,它并不会无视media="handheld"。而如果想要让Windows Mobile识别media="handheld",一个有趣的技巧是将其它media属性的内容首字母大写,就像这样:




唔……那么我们该怎么最好地利用这一特性呢?在HTML当中,我们这样写:



这样的写法,将使得base.min.css始终被设备加载,而无论何种设备,我们通过这样的做法来加载网站的主体CSS代码;而mobile.min.css,它只在屏宽低于800像素的设备上加载,它携带了我们针对移动设备的优化。这些优化包括:

  • 去除不必要的间隔(padding, margin…),因为移动设备寸土寸金
  • 去除:hover状态下的代码,因为移动设备极少真正用到这一状态(但不是没有。在Android上,长按一个链接即可令其达到hover状态。)
  • 将布局调整为单列
  • 去除所有的box-shadow属性,因为大量的box-shadow将导致设备运行缓慢
  • 使用box-ordinal-group来改变平级块元素的顺序,以使得某些适于移动设备浏览的部分放在前部/li>
  • 去除了opacity属性的使用,这一代价昂贵的特效在移动设备上并不适合

HTML Meta

除了CSS的Media Query用法,Webkit还赋予了移动设备一些其它定制化方案。

Viewport

首先是调整浏览器的视图:


上面的代码为使用Webkit核心浏览器的移动设备,提供了一种对页面视图范围处理的能力。我们知道,在Android或者iOS上,用户通常都可以对页面进行自由缩放,但这样的缩放通常是不加限制的缩放,以至于页面有时会因页面的缩放以及缩放所引起的重新排版而变得难以识别。

通过对meta标签如上的设置,将指定设备在加载页面完毕之后,将页面的宽度初始化为设备的屏宽,并将缩放系数设为1.0,同时允许用户自行缩放。这样的设置对于普通的网页来说是个不错的选择,但对于网页应用来说,开发者也许并不希望用户进行缩放,或者不希望用户进行无限的缩放,因此,我们可以考虑这样的代码:


这段代码只允许用户在0.5-1.0的缩放系数内进行缩放,因此可以在一定程度上对页面的布局进行保护。如果开发者完全不希望用户缩放,则可以写明scalable=no

而在Android上,我们还能够使用代码控制页面所适用的屏幕分辨率,像这样:


这段代码将引导设备使用设备的默认分辨率进行渲染,该属性的其它可选值则为device-dpihigh-dpimedium-dpilow-dpi。详细的内容请参考Android WebView

全屏显示

meta标签另有两个用法,但它们都仅对iOS生效:



这两项分别是用以提示浏览器以全屏模式显示,以及状态栏透明。其属性值的详细可选范围,请参阅 Safari Meta

其它优化

自动隐藏地址栏

在完成了数据的加载之后,实际上我们完全可以通过隐藏地址栏来获取更多的屏幕空间,从而增强了页面的效果。这一点,我们可以使用JavaScript来完成:

window.addEventListener('load', function(e) {
    setTimeout(function() { window.scrollTo(0, 1); }, 1);
  }, false);

当我们判明当前代码的环境是移动设备时,我们就选择在页面加载完毕时自动向下移动,这样在Android浏览器上就可以直接隐藏掉地址栏了。

减少网络请求

减少网络请求是移动设备很重要的一项优化方式。大多数移动设备需要借助无线网络才能连接互联网,特别是借助2G或者3G网络,如果能够减少网络请求,则意味着能够有效缩短网页的载入延迟。以下是一些能够有效减少网络请求的办法:

  • 减少使用iframe。iframe是常有的嵌套网页的方式,除却我们自己使用之外,一些页面小部件也会采用这样的方式来载入信息,比如twitter、facebook等等。
  • 谨慎对待display:none。一个良好的CSS兼容手段是在移动设备的CSS当中对某些元素使用display:none来隐藏,但被隐藏的元素仍旧会被传送到浏览器。因此在这一方面,我们应当作出选择。
  • 如果可能,尽量使用CSS-sprite。CSS-sprite技术将众多零散的图片归并到一起交由CSS来分配,这一点在桌面浏览器上优势并不会太明显,但在移动设备这样带宽紧张的情境下,就能够有效减少网络请求的次数。

应用缓存

应用缓存(Application Cache)是一种允许用户离线阅读内容的方式。当使用应用缓存时,非常重要的一点即是不要缓存manifest文件,否则它将带来很大的麻烦。

因此,我们首先保证应用缓存不会缓存manifest文件:

- url: /(.*\.(appcache|manifest))
  static_files: \1
  mime_type: text/cache-manifest
  upload: (.*\.(appcache|manifest))
  expiration: "0s"

其次,我们需要用一段JS代码来刷新我们的缓存:

window.applicationCache.addEventListener('updateready', function(e) {
  if (window.applicationCache.status == window.applicationCache.UPDATEREADY) {
    window.applicationCache.swapCache();
    if (confirm('A new version of this site is available. Load it?')) {
      window.location.reload();
    }
  }
}, false);

最后,为了尽可能节约网络传输,我们要保证manifest尽可能地简单,也就是说,要有选择性地使用它。

其它

还有一些其它的优化方法:

  • CSS/JS压缩。
  • 离线缓存
  • 减少嵌入式CSS代码。
  • 将所有JS代码挪至页面底部加载。
  • 在JS代码中,缓存遍历DOM。

About liuyanghejerry

富有激情的前端工程师,专注GUI开发。

Comments are closed.

Post Navigation