翻译自:https://samdutton.wordpress.com/2015/04/02/high-performance-html/
大部分开发者对于Web优化都会想到JavaScript和图片优化,服务器配置优化,文件管理优化,甚至是Css优化,但是很少有人考虑HTML的优化,尽管HTML才是Web开发的核心语言。
HTML承载的信息越来越大,前100的网站每一个页面都需要大约40KB的大小,比如Amazon和Yahoo在每一个HTML页面中达到了上千行代码。Youtube的首页甚至有3500个HTML元素。
尽管减少HTML复杂度和在每一页中HTML元素的数量不会降低多少页面解析的时间,但是良好的HTML编码习惯是在不同尺寸设备上构建快速页面加载和布局的基础。
分工明确: 使用HTML仅仅构建结构,不要包含css 内容 保持语法正确:使用代码验证工具保证代码没有任何语法和逻辑上的错误,比如Sublime 的HTML插件 保持页面整洁:使用代码格式化工具管理代码结构一致性和格式化,比如checkStyle,Sonar等 学习语言:应熟悉所有HTML元素,并在代码中多使用HTML语义化的标记元素 考虑特殊人群使用: 设计过程中一定要考虑到所有的情况,可使用ARIA Attribute(Accessible Rich Internet Applications)来专门为特殊人群正常访问,以保证你的网站可以通过屏幕阅读器或者纯文本浏览器来展示; 测试:尝试在不同设备和屏幕尺寸上访问你的网站
HTML,CSS and JavaScript
HTML 不应该包含样式内容,不要为了仅仅使文字变大而使用
,
…等heading标签,也不要仅仅为了缩进而使用标签,应该使用css来控制元素的显示和布局。
默认的HTML元素的显示是由浏览器默认样式定义的: Chrome,Firefox,Internet Explorer 和 Opera都有自己的默认样式
页面开发三原则:
用HTML构建结构,CSS控制显示, JavaScript控制行为
首先完成HTML的设计,在考虑CSS设计,最后考虑JavaScript开发。
将Css和JavaScript写在文件中与HTML文件隔离,这样有助于文件的缓存和调试。cass和JavaScript文件可以链接到HTML文件中
文档结构
- 使用HTML5 文档类型标记<!DOCTYPE html>
<!DOCTYPE html> <!-- Here -->
<html>
<head>
<title>Recipes: pesto</title>
</head>
<body>
<h1>Pesto</h1>
<p>Pesto is good!</p>
</body>
</html>
- 在页面头部引入Css文件,在元素里面:
<head>
<title>My pesto recipe</title>
<link rel="stylesheet" href="/css/global.css">
<link rel="stylesheet" href="css/local.css">
</head>
这样的话,浏览器会在解析HTML文件之前就加载CSS文件
- 把JavaScript文件的引入放在页面的底部,在标签之前。这样能提高页面加载速度 - 因为浏览器在解析JavaScript之前先渲染HTML页面,同时有助于JavaScript对页面元素进行操作。
<body>
...
<script src="/js/global.js"></script>
<script src="js/local.js"></script>
</body>
- 可选:使用defer和async attributes - 但是小心他们的行为:异步脚本元素不保证他们能被顺序的执行。同时注意:async 只在Internet Exporer 10 及以上被实现,defer 在Internet Explorer10 之前部分被支持
- 在JavaScript文件中添加元素事件处理handler,不要直接在HTML页面中编写handler。 下面是错误的用法并且很难管理:
<head>
...
<script src="js/local.js"></script>
</head>
<body onload="init()">
...
<button onclick="handleFoo()">Foo</button>
...
</body>
下面的方式更好:
index.html
<head>
...
</head>
<body>
...
<button id="foo">Foo</button>
...
<script src="js/local.js"></script>
</body>
js/local.js
init();
var fooButton =
document.querySelector('#foo');
fooButton.onclick = handleFoo();
验证
Web能如此成功主要归功于浏览器能处理无效HTML代码的能力,甚至有一套浏览器渲染无效代码的标准规则(standardised rules for how browsers should render invalid code), 但是这不表示我们就可以随便写无效的代码。 有效的HTML更容易被调试,文件更小,运行更快,页面解析和渲染是消耗的资源更少。无效的HTML会使响应式设计更难实现。
当与模板一起工作时,编写有效的HTML就显得更重要: 往往一个页面单独运行的时候很正常,一旦和其他内容整合起来是就不会出现预期的效果。
在你的IDE中使用验证工具:比如HTMLHint 和 SublimeLinter。你也可以使用在线检查工具比如W3CHTML validator;
使用HTML5 docType;
管理HTML层级结构:保证嵌套的元素正确,所有元素有闭合标签。在包含大量复杂内容的尾标签处添加一个注释(comment)更有助于页面的调试, 尤其是在使用JS模板时更有用;
<div id="foobar">
...
</div>
<!-- foobar ends -->
- 在所有不能自动结束的元素末尾添加结束标签;
比如以下是能工作的:
<p>Pesto is good to eat...
<p>...and pesto is easy to make.
但是容易出错,因为每一个p标签需要有显式的结尾标签:
<p>Pesto is good to eat...</p>
<p>...and pesto is easy to make.</p>
标签不是必须的并且一些聪明的开发者更喜欢不适用它们,但是不管怎样,
,这样的标签一定要有结尾标签
<ul>
<li>Basil
<li>Pine nuts
<li>Garlic
</ul>
- video 和 audio元素一定要有结尾标签,因为它们不是自关闭的”self closing”:
<!-- wrong: liable to cause layout grief -->
<video src="foo.webm" />
<!-- better -->
<video src="foo.webm">
<p>Video element not supported.</p>
</video>
- 元素是自关闭的, 但是script元素一定要有关闭标签,即使它只包含外部JavaScript文件的引用:
<link rel="stylesheet" href="css/local.css">
...
<script src="/js/global.js"></script>
另一方面,要去掉冗余的代码:
像
, 这样的标签可以不加 “/“
Boolean属性可以不赋值:只要该属性出现,值就是true. 下面的例子,video元素不会自动播放,没有控制按钮(因为autoplay和controls 没有出现,默认是false)
<video src="foo.webm">
下面的例子video将没有效果,因为autoplay和controls属性被设成了false
<video src="foo.webm" autoplay="false" controls="false">
下面的例子:video可以工作
<video src="foo.webm" autoplay="true" controls="true">
下面的代码更容易阅读
<video src="foo.webm" autoplay controls>
stylesheets 和 script文件不需要 type 属性:CSS 和 JavaScript 是默认的
当链接外部资源时可省略协议信息(protocol),比如:
<a href="//en.wikipedia.org/wiki/Tag_soup">Tag soup</a>
语义标记
HTML 语义标记是通过一些浅显易懂的元素和属性名来实现语义化。
HTML5 又加了一些新的语义元素,比如<header>
,<footer>
和<nav>
针对内容使用正确的元素是你的代码更容易理解:
标题使用<h1>
(
,
…),列表使用<ul>
或者<ol>
<article>
里面的内容应该以<h1>
开头
在适当的地方使用HTML5语义元素,比如
, 正文中的文本要用<p>
标签,内容的结构化可使用HTML5语义元素
修改文字样式时,使用<em>
和<strong>
而不是<i>
,<b>
:因为前者语义更加明显
不要把文字和元素混在一起,这样容易导致布局出错
<div>Name: <input type="text" id="name"></div>
这样更好:
<div>
<label for="name">Name:</label>
<input type="text" id="name">
</div>
这里有个小窍门:属性 for
表示当点击label
标签时,鼠标自动定位到input
文本框中。这个功能对于checkboxes和radio button很有用
布局
重申: 样式在css文件中控制就行了,不要再HTML页面中定义样式内容
<p>
元素用来显示文本,不是用来布局的。默认情况下,浏览器给
元素内置了margin和其他样式
避免使用<br>
来换行:使用<block>
或者 css 中display:block
属性来替代。文字内容中的换行可以使用<br>
避免使用<hr>
来添加水平线,CSS中的border-bottom
是一个更好的选择
不要滥用<div>
:W3C对<div>
的描述是这样的:当没有其他元素可用时才能使用<div>
,如果想让<link>,<img>
这类元素能够在结尾换行,可以在样式中添加display:block
,这样要比把它们放在div
或使用<br>
好的多。
需要知道哪些是块级元素,这样可以避免把块级元素放到<div>
里面,比如
就不需要放在div中
不要用
来布局,仅使用table来显示数据理解盒模型(box model)
使用margin规则:通常情况下,margin都是添加在元素的bottom和right,有时也可以在top或者left,无论如何,尽量避免同时用在bottom和top,或者right和left。可以使用last-of-type选择器来去掉最后一个子元素的margin。
CSS
- 避免内联css, 为了性能优化,可以在HTML文件中内联CSS文件
<!DOCTYPE html>
<html lang="zh">
<head>
<link rel="stylesheet" href="css/style.css"> <!-- use this way -->
<style type="text/css"> <!-- not use this way -->
.overlay {
position: fixed;
display: none;
width: 100%;
height: 100%;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.4);
z-index: 1;
}
</style>
</head>
<body>
</body>
</html>
保证id
的唯一性
当你想要引用多个元素时,可以使用class属性, class的命名方式可以采用BEM规则,如下可在父元素上定义class属性,而不是在子元素上每一个都定义class:
<!-- verbose :( -->
<ul>
<li class="ingredient">Basil</li>
<li class="ingredient">Pine nuts</li>
<li class="ingredient">Garlic</li>
</ul>
<!-- better -->
<ul class="ingredients">
<li>Basil</li>
<li>Pine nuts</li>
<li>Garlic</li>
</ul>
默认的HTML元素的显示是由浏览器默认样式定义的: Chrome,Firefox,Internet Explorer 和 Opera都有自己的默认样式
页面开发三原则:
用HTML构建结构,CSS控制显示, JavaScript控制行为
首先完成HTML的设计,在考虑CSS设计,最后考虑JavaScript开发。
将Css和JavaScript写在文件中与HTML文件隔离,这样有助于文件的缓存和调试。cass和JavaScript文件可以链接到HTML文件中
文档结构
- 使用HTML5 文档类型标记<!DOCTYPE html>
<!DOCTYPE html> <!-- Here -->
<html>
<head>
<title>Recipes: pesto</title>
</head>
<body>
<h1>Pesto</h1>
<p>Pesto is good!</p>
</body>
</html>
- 在页面头部引入Css文件,在元素里面:
<head>
<title>My pesto recipe</title>
<link rel="stylesheet" href="/css/global.css">
<link rel="stylesheet" href="css/local.css">
</head>
这样的话,浏览器会在解析HTML文件之前就加载CSS文件
- 把JavaScript文件的引入放在页面的底部,在标签之前。这样能提高页面加载速度 - 因为浏览器在解析JavaScript之前先渲染HTML页面,同时有助于JavaScript对页面元素进行操作。
<body>
...
<script src="/js/global.js"></script>
<script src="js/local.js"></script>
</body>
- 可选:使用defer和async attributes - 但是小心他们的行为:异步脚本元素不保证他们能被顺序的执行。同时注意:async 只在Internet Exporer 10 及以上被实现,defer 在Internet Explorer10 之前部分被支持
- 在JavaScript文件中添加元素事件处理handler,不要直接在HTML页面中编写handler。 下面是错误的用法并且很难管理:
<head>
...
<script src="js/local.js"></script>
</head>
<body onload="init()">
...
<button onclick="handleFoo()">Foo</button>
...
</body>
下面的方式更好:
index.html
<head>
...
</head>
<body>
...
<button id="foo">Foo</button>
...
<script src="js/local.js"></script>
</body>
js/local.js
init();
var fooButton =
document.querySelector('#foo');
fooButton.onclick = handleFoo();
验证
Web能如此成功主要归功于浏览器能处理无效HTML代码的能力,甚至有一套浏览器渲染无效代码的标准规则(standardised rules for how browsers should render invalid code), 但是这不表示我们就可以随便写无效的代码。 有效的HTML更容易被调试,文件更小,运行更快,页面解析和渲染是消耗的资源更少。无效的HTML会使响应式设计更难实现。
当与模板一起工作时,编写有效的HTML就显得更重要: 往往一个页面单独运行的时候很正常,一旦和其他内容整合起来是就不会出现预期的效果。
在你的IDE中使用验证工具:比如HTMLHint 和 SublimeLinter。你也可以使用在线检查工具比如W3CHTML validator;
使用HTML5 docType;
管理HTML层级结构:保证嵌套的元素正确,所有元素有闭合标签。在包含大量复杂内容的尾标签处添加一个注释(comment)更有助于页面的调试, 尤其是在使用JS模板时更有用;
<div id="foobar">
...
</div>
<!-- foobar ends -->
- 在所有不能自动结束的元素末尾添加结束标签;
比如以下是能工作的:
<p>Pesto is good to eat...
<p>...and pesto is easy to make.
但是容易出错,因为每一个p标签需要有显式的结尾标签:
<p>Pesto is good to eat...</p>
<p>...and pesto is easy to make.</p>
-
标签不是必须的并且一些聪明的开发者更喜欢不适用它们,但是不管怎样,
<ul>
<li>Basil
<li>Pine nuts
<li>Garlic
</ul>
- video 和 audio元素一定要有结尾标签,因为它们不是自关闭的”self closing”:
<!-- wrong: liable to cause layout grief -->
<video src="foo.webm" />
<!-- better -->
<video src="foo.webm">
<p>Video element not supported.</p>
</video>
- 元素是自关闭的, 但是script元素一定要有关闭标签,即使它只包含外部JavaScript文件的引用:
<link rel="stylesheet" href="css/local.css">
...
<script src="/js/global.js"></script>
另一方面,要去掉冗余的代码:
像
, 这样的标签可以不加 “/“
Boolean属性可以不赋值:只要该属性出现,值就是true. 下面的例子,video元素不会自动播放,没有控制按钮(因为autoplay和controls 没有出现,默认是false)
<video src="foo.webm">
下面的例子video将没有效果,因为autoplay和controls属性被设成了false
<video src="foo.webm" autoplay="false" controls="false">
下面的例子:video可以工作
<video src="foo.webm" autoplay="true" controls="true">
下面的代码更容易阅读
<video src="foo.webm" autoplay controls>
stylesheets 和 script文件不需要 type 属性:CSS 和 JavaScript 是默认的
当链接外部资源时可省略协议信息(protocol),比如:
<a href="//en.wikipedia.org/wiki/Tag_soup">Tag soup</a>
语义标记
HTML 语义标记是通过一些浅显易懂的元素和属性名来实现语义化。
HTML5 又加了一些新的语义元素,比如<header>
,<footer>
和<nav>
针对内容使用正确的元素是你的代码更容易理解:
标题使用
<h1>
(,
…),列表使用
<ul>
或者<ol>
<article>
里面的内容应该以<h1>
开头在适当的地方使用HTML5语义元素,比如
, 正文中的文本要用
<p>
标签,内容的结构化可使用HTML5语义元素修改文字样式时,使用
<em>
和<strong>
而不是<i>
,<b>
:因为前者语义更加明显不要把文字和元素混在一起,这样容易导致布局出错
<div>Name: <input type="text" id="name"></div>
这样更好:
<div>
<label for="name">Name:</label>
<input type="text" id="name">
</div>
这里有个小窍门:属性 for
表示当点击label
标签时,鼠标自动定位到input
文本框中。这个功能对于checkboxes和radio button很有用
布局
重申: 样式在css文件中控制就行了,不要再HTML页面中定义样式内容
<p>
元素用来显示文本,不是用来布局的。默认情况下,浏览器给元素内置了margin和其他样式
避免使用
<br>
来换行:使用<block>
或者 css 中display:block
属性来替代。文字内容中的换行可以使用<br>
避免使用
<hr>
来添加水平线,CSS中的border-bottom
是一个更好的选择不要滥用<
div>
:W3C对<div>
的描述是这样的:当没有其他元素可用时才能使用<div>
,如果想让<link>,<img>
这类元素能够在结尾换行,可以在样式中添加display:block
,这样要比把它们放在div
或使用<br>
好的多。需要知道哪些是块级元素,这样可以避免把块级元素放到
<div>
里面,比如- 就不需要放在div中
不要用
来布局,仅使用table来显示数据理解盒模型(box model)
使用margin规则:通常情况下,margin都是添加在元素的bottom和right,有时也可以在top或者left,无论如何,尽量避免同时用在bottom和top,或者right和left。可以使用last-of-type选择器来去掉最后一个子元素的margin。
- 避免内联css, 为了性能优化,可以在HTML文件中内联CSS文件
CSS
<!DOCTYPE html> <html lang="zh"> <head> <link rel="stylesheet" href="css/style.css"> <!-- use this way --> <style type="text/css"> <!-- not use this way --> .overlay { position: fixed; display: none; width: 100%; height: 100%; top: 0; left: 0; right: 0; bottom: 0; background-color: rgba(0, 0, 0, 0.4); z-index: 1; } </style> </head> <body> </body> </html>
保证
id
的唯一性当你想要引用多个元素时,可以使用class属性, class的命名方式可以采用BEM规则,如下可在父元素上定义class属性,而不是在子元素上每一个都定义class:
<!-- verbose :( --> <ul> <li class="ingredient">Basil</li> <li class="ingredient">Pine nuts</li> <li class="ingredient">Garlic</li> </ul> <!-- better --> <ul class="ingredients"> <li>Basil</li> <li>Pine nuts</li> <li>Garlic</li> </ul>