web移动开发最佳实践之html篇

时间:2023-12-22 11:56:38

一、前言

  在目前的移动应用开发大潮下,使用web技术进行移动应用开发正变得越来越流行,它主要使用html5、css3、js等技术,在跨平台性、可移植性方面具有无可比拟的优势,特别适合开发对性能要求不太高、项目不太庞大的应用。这对于有过web经验刚入门移动应用的同学来说,绝对是福音。

  接下来的几篇文章主要介绍使用web技术进行移动应用开发时,应遵循的一些‘最佳实践’。这里所说的最佳实践其实就是一些建议,它可以让你的程序更加高效,涉及到代码风格、标准等,例如缩进、空格、行宽、命名、代码样式、变量声明和使用……随着开发经验的丰富,我会逐步更新这些文章。

  使用‘最佳实践’的好处:

  1. 提高性能(使用更少的CPU和带宽)
  2. 提高跨浏览器的兼容性
  3. 提高代码的可维护性(这对于较大的项目和团队尤其重要)
  4. 提高代码可读性,以利于日后的审查和重构
  5. 有利于自动化任务实施,如构建脚本,自动化测试
  6. 更容易调试,节省时间,减少成本

二、html概述

  html即超文本标记语言(Hyper Text Markup Language),它并不是一种编程语言,而是使用一套标记标签来描述网页。它的主要功能是展现网页内容

  在经历了几代的标准的进化后,html5是目前的最新标准,而且正往这个方向大力推进。下面几个章节中,将重点介绍使用html过程中的最佳实践方案。这里主要参考了黑莓10的开发指南W3C标准

三、从模板开始

  这个,做很多事情都是差不多的。把自己常用的代码片段保存为一个模板,随时调用,不仅节省时间而且能加快开发进度。写重复的代码是没有意义的,因此当你创建了一个可以重用的基本结构时,就把它保存下来,供日后复用,这样你的效率就越来越高。一个html模板应该包括web页面的典型元素。比如:

web移动开发最佳实践之html篇
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,
initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0,
user-scalable=no">
<title>Heading</title>
<link href="favicon.ico" rel="icon" type="image/x-icon">
<link rel="stylesheet" href="css/app.css">
<style type="text/css">
</style>
</head>
<body>
<h1>Heading</h1>
<p>The quick brown fox jumps over the lazy dog.</p>
<script src="js/app.js"></script>
</body>
</html>
web移动开发最佳实践之html篇

这个模板中,有几个注意点:

  1. 这个应用会设置为全屏显示,因为它包含了以下meta标签:
    initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0
  2. Zooming函数被关闭了,因为设置了:
    user-scalable=no
  3. 为了提高性能,js脚本部分被放在了body元素的底部,关于这点会在以后的js篇中介绍。

四、指定文档类型(document type)

  文档开头的 DOCTYPE 声明位于文档中的最前面的位置,处于<html>标签之前。它会告诉浏览器书写文档的html版本,这会影响到浏览器对内容的渲染。还有就是当你进行html标准校验时,校验器也会根据这个 DOCTYPE 来选择相应的html版本,以确定所写代码是否符合规范。

  如果你没有包括 DOCTYPE 的声明,那么不同的浏览器就可能出现不同的渲染结果。使用这个声明会要求浏览器使用相应的标准来解析页面内容。

  web移动开发最佳实践之html篇h5是目前的标准,包含了大量的新特性,声明是很简单的:

<!DOCTYPE html>

  对于一些较老的设备和浏览器,可能需要声明为其他的类型(HTML 4.01 Strict or XHTML 1.0 Strict):

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "
http://www.w3.org/TR/html4/strict.dtd">
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

五、把程序设计为离线下仍然可以使用

  能随时随地地使用手机设备上应用程序的需求正越来越强,即使在离线状况下。对于web应用,你可以使用h5的缓存功能W3C HTML5 application cache来:

  1. 离线下仍然可以使用
  2. 把资源缓存在本地以提高速度
  3. 仅下载更新的或改变的资源以减少加载次数和数据使用

  程序缓存(即AppCache)可以让你指定缓存的文件,这样即使离线仍然可以访问。当然你还可以利用开发平台提供的API来获取本地存取文件的权限。

  1.创建一个缓存清单(manifest)

    为了使用AppCache,你的web应用必须为浏览器提供一个"manifest",这个清单要列举出在离线情况下你的应用需要的所有资源。页面第一次加载后,"manifest"中列举的资源就会从程序缓存中加载,而不是web服务器。"manifest"其实就是一个以".appcache"为后缀的文本文件(配置文件)。例如:

web移动开发最佳实践之html篇
CACHE MANIFEST
# 2012-03-08:v1 # Explicitly cached resources
index.html
css/app.css
js/app.js # offline.html displays if the user is offline
FALLBACK:
/ /offline.html # All other resources require an online connection
NETWORK:
* # Additional cached resources
CACHE:
img/logo.png
web移动开发最佳实践之html篇

    你的manifest文件的mime-type必须是"text/cache-manifest",因此你需要在web服务器添加一行配置。例如,在Apache的httpd.conf文件添加一行:

AddType text/cache-manifest .appcache

    为了访问manifest文件,你必须在html文档中声明(通过添加html标记的manifest属性,如下),manifest属性指向相应的manifest文件。如果你的应用有多个页面,那么每个页面都要包含manifest属性,否则这些页面就不会成为AppCache,离线下也就不会工作了。

<html manifest="html5.appcache">

  2.更新appcache

    一旦你的应用被缓存了,它会一直被缓存直到满足以下任何一个条件:

  • 用户清除了缓存
  • manifest文件被改变了。注意:更新服务器上的资源不会触发缓存的更新,你必须修改manifest文件本身
  • 程序的缓存被程序自动更新了

  3.相关资源

六、使用正确的viewport语法

  viewpoint是用户在手机设备上可以看到的矩形区域。你可以再meta标记中重写viewpoint。但是记住,viewpoint在meta标记中的语法和在CSS中的语法并不一样,你必须用逗号(commas)分隔不同的值,而不是分号(semicolons)。例如:

<meta name="viewport" content="width=device-width,
initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">

七、创建一个站点的图标(icon)

  每一个浏览器都会把名为favicon.ico的文件作为该站点的icon。比如你经常会在地址栏、tab栏、书签栏或者收藏夹看见这些小图标:

web移动开发最佳实践之html篇

  浏览器在加载web页面时,也会发送一个获取favicon.ico的请求,如果没有这个文件,你会在服务器日志中看到404的错误。为了避免错误,也为了页面的美观,你应该在web应用中包含一个这样的文件。例如:

<link href="favicon.ico" rel="icon" type="image/x-icon">

八、使用外部文件

  使用外部的js和css文件有很多好处,最主要的好处是让页面响应更快,原因如下:

  • 外部文件会被浏览器缓存,这会减少http请求次数,另外,内联的js和css会在每次加载主文档的时候被下载
  • 减少主文档大小

  当然,这并不是对每种情况都适用的,当满足如下两种情况时,就可以考虑将资源放在外部:

  • 在多个html文档中都有用到
  • 并不经常改变

  关于使用外部文件,这里有一些建议:

  • 把资源转移到一些知名的站点,这样可以减少DNS查询的次数
  • 使用另一个域名的资源,对于特定的域名,浏览器有链接次数的限制,使用其他域名的资源,浏览器就可以并行地发送请求
  • 对于常用的js库,使用CDN(Content Delivery Network)托管的文件。这样就可以减少延迟,提高缓存利用率和程序性能。例如使用google的CDN-hosted jQuery:
  • <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js">
    </script>
  • 使用Web Inspector分析web应用的性能。

九、把css文件放在顶部

  另一种提高页面加载速度的办法是把css文件放在文档的顶部。把css文件放在head节点内,页面就会逐步渲染,这样就会感觉加载速度变快,而且能给用户提供视觉上的反馈。但是如果放在文档底部,浏览器就会阻塞渲染过程避免样式改变后的重绘过程,用户在此时就会看到白屏。还有一种好处就是提高并行化,不像脚本,css并不需要同步处理。例如:

web移动开发最佳实践之html篇
<!DOCTYPE html>
<html>
<head>
...
<link rel="stylesheet" href="styles1.css">
</head>
<body>
...
</body>
</html>
web移动开发最佳实践之html篇

十、css中避免使用import

  在html文档中使用外部css文件时,要避免使用 @import规则,而是使用<link>标签。因为在一些浏览器中,它的效果就像是该css文件处在html文档底部一样,这会阻塞页面的加载。

<!--Not recommended: Using @import-->
<style>
@import url("styles2.css");
</style>
<!--Recommended: Using a LINK tag-->
<link rel="stylesheet" href="styles1.css">

  另外,@import规则还可以嵌套到css文件里,这阻塞了css文件的并行加载,例如:如果style1.css包含了以下

<!--Not recommended: Using @import-->
@import url(styles2.css)

十一、把脚本放在底部

  尽管W3C spec允许你可以把脚本放在head或body的任意地方,但是位置不同会影响到页面的渲染,因为浏览器会停下来执行js代码,而后面的内容渲染就会被阻塞。放在body底部就会有更多的内容被渲染,同样有利于并行下载,你还不必担心DOM是否加载完成,因为所有的东西都已经加载完了。

  除非你使用不赞成使用的document.write来产生body元素,你的脚本通常都可以移到html文档的底部。

web移动开发最佳实践之html篇
<!--Recommended: Placing the script near the bottom of the BODY-->
<html lang="en">
<body>
...
<script src="js/app.js"></script>
</body>
</html>
web移动开发最佳实践之html篇
web移动开发最佳实践之html篇
<!--Not recommended: Placing the script in the HEAD-->
<html lang="en">
<head>
<script src="js/app.js"></script>
</head>
<body onload="init();">
...
</body>
</html>
web移动开发最佳实践之html篇

十二、推迟脚本加载(defer)

  如果不想把脚本放在文档底部,可以使用defer属性延迟脚本的加载。该属性告诉浏览器在页面加载完成后才执行脚本

<script src="js/app.js" defer></script>

  但是,defer属性在浏览器之间表现并不一致。为了避免跨浏览器的差异,可以使用 "lazy loading"的方法,即直到用到该脚本时才加载。例如:

web移动开发最佳实践之html篇
function lazyload() {
var elem = document.createElement("script");
elem.type = "text/javascript";
elem.async = true;
elem.src = "app.js"; // contains more than 25 uncalled functions
document.body.appendChild(elem);
} if (window.addEventListener) {
window.addEventListener("load", lazyload, false);
} else if (window.attachEvent) {
window.attachEvent("onload", lazyload);
} else {
window.onload = lazyload;
}
web移动开发最佳实践之html篇