翻译自: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>
  1. <!DOCTYPE html> <!-- Here -->
  2. <html>
  3. <head>
  4. <title>Recipes: pesto</title>
  5. </head>
  6. <body>
  7. <h1>Pesto</h1>
  8. <p>Pesto is good!</p>
  9. </body>
  10. </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>

另一方面,要去掉冗余的代码:

  • 如何编写高性能HTML - 图1, 这样的标签可以不加 “/“

  • 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>