杨二

Machine repeats, Human creates

无规矩不成方圆--前端编码规范

![code style jpg]/images-guide/code.jpg)

代码是写给人读的,只是机器偶尔执行一下。

#写在前面的话

  • 规范的初衷是为了代码的可维护性,让多人写出的代码像出自同一人之手
  • 该规范具有演化性,会随着实际情况做出相应的调整。开源地址:fe.code.guide
  • 该规范适用于开发阶段,最后上线的代码不一定符合该规范,因为上线代码可能会经过打包、混淆和压缩

#通则

  • KISS 原则:坚持简约,避免不必要的复杂化
  • 所有代码小写(常量命名、特殊名词、纯字符串除外)
//不推荐

<a href="/">Home</a>

//推荐

<img src="img.png" alt="Image" />
//不推荐

color: #e5e5e5;

//推荐

color: #e5e5e5;
  • 命名规则(项目,目录,HTML、CSS、JS、图片等静态文件)

小写,以下划线分割,例:my_project_name

  • 注释(建议以下情况使用注释)
    • 难于理解的代码段
    • 可能存在错误的代码段
    • 浏览器特殊的 HACK 代码
    • 业务逻辑强相关的代码

代码是人写的,也是由人维护,所以尽可能确保代码具备描述性,做到不注自释。
好注释能表达出代码的上下文和目的,不要只是复述从代码就能读出的信息。

#HTML

##文档骨架

PC:

<!DOCTYPE html>

<html>
  <head>
    <meta charset="utf-8" />

    <title>Page title</title>

    <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
  </head>

  <body></body>
</html>

强制浏览器使用标准模式渲染,保证页面效果统一。IE 浏览器使用最新版本,即Edge Mode

Mobile:

<!DOCTYPE html>

<html>
  <head>
    <meta charset="utf-8" />

    <title>Page title</title>

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

  <body></body>
</html>

强制浏览器使用标准模式渲染,保证页面效果统一

##语法

  • 使用双空格短缩进
  • 在属性中始终书写双引号
  • 自关闭元素不要使用斜杠结尾(参考此处

常见的自关闭元素:

<br />
<hr />
<img /> <input /> <link /> <meta />

不常见的自关闭元素:

<area /> <base />
<col />
<command>
  <embed />
  <keygen>
    <param />
    <source />
    <track />
    <wbr /></keygen
></command>

##引用 CSS 和 JavaScript 文件

按照 HTML5 规范,一般来说,当 CSS 和 JS 文件被引用时,都会默认以 text/csstext/javascript 的方式,没必要特意为其指定 type 类型。例如:

<!-- 外部 CSS -->

<link rel="stylesheet" href="demo.css" />

<!-- 文档内CSS -->

<style>
  /* ... */
</style>

<!-- Javascript -->

<script src="demo.js"></script>

##精简标签

书写 HTML 时尽可能减少冗余的标签。比如:

<!-- 不推荐 -->

<span class="avatar">
  <img src="..." />
</span>

<!--推荐 -->

<img class="avatar" src="..." />

另外,尽量不要在 HTML 写行内 style、JS 代码,遵守结构和样式、行为分离的原则。

##实用为王

尽量遵循 HTML 标准和语义,但是不要以牺牲实用性为代价。任何时候都要尽量使用最少的标签并保持最小的复杂度。

##属性顺序

<a class="..." id="..." data-toggle="modal" href="#">
  Demo link
</a>

<input class="form-control" type="text" />

<img src="..." alt="..." />
  • class
  • id,name
  • data-*
  • src,for,type,href,value
  • title,alt
  • role,aria-*

class能更好地重用组件,所以打头阵;id更加特定和专属,尽量控制使用。

##布尔属性

某一元素如果调用了布尔属性,则代表该值为真,否则为假。

简言之:不要赋值。

<input type="text" disabled />

<input type="checkbox" value="1" checked />

<select>
  <option value="1" selected>1</option>
</select>

#CSS

##语法

/* 不推荐 */ .selector, .selector-secondary, .selector[type=text] {
padding:15px; margin:0px 0px 15px; background-color:rgba(0, 0, 0, 0.5);
box-shadow:0px 1px 2px #CCC,inset 0 1px 0 #FFFFFF } /* 推荐 */ .selector,
.selector-secondary, .selector[type="text"] { padding: 15px; margin-bottom:
15px; background-color: rgba(0,0,0,.5); box-shadow: 0 1px 2px #ccc, inset 0 1px
0 #fff; }
  • 多个选择器,请换行
  • 区块结束符}独占一行
  • 不要忘记最后一个声明语句的;
  • 省略小数点前的00.5=>.5
  • 零值省略单位:margin: 0px;=>margin: 0
  • 只有一条声明可以写在一行

##声明顺序

.declaration-order {
  /* 定位 */

  position: absolute;

  top: 0;

  right: 0;

  bottom: 0;

  left: 0;

  z-index: 100;

  /* 盒模型 */

  display: block;

  float: right;

  width: 100px;

  height: 100px;

  /* 排版 */

  font: normal 13px "Helvetica Neue", sans-serif;

  line-height: 1.5;

  color: #333;

  text-align: center;

  /* 视觉 */

  background-color: #f5f5f5;

  border: 1px solid #e5e5e5;

  border-radius: 3px;

  /* 其它 */

  opacity: 1;
}

相关属性的声明按组以以下顺序排列:

  1. 定位(Positioning)
  2. 盒模型(Box model)
  3. 排版(Typographic)
  4. 视觉(Visual)

定位排首位是因为它可能会让元素脱离文档流并重写盒模型的相关样式

##禁止使用@import

原因:参考此文

##正确放置媒体查询语句

.element {
  ...;
}

.element-avatar {
  ...;
}

.element-selected {
  ...;
}

@media (min-width: 480px) {
  .element {
    ...;
  }

  .element-avatar {
    ...;
  }

  .element-selected {
    ...;
  }
}

尽可能把媒体查询语句放在相关的规则集后面,不要单独存放到某个文件,也不要放到样式表最后。这样做是为了以后同步修改更方便,相信我,这样做能让后来维护代码的人少骂你几句。

##简写虽好,但不要滥用

/* 不推荐 */

.element {
  margin: 0 0 10px;

  background: red;

  background: url("image.jpg");

  border-radius: 3px 3px 0 0;
}

/* 推荐 */

.element {
  margin-bottom: 10px;

  background-color: red;

  background-image: url("image.jpg");

  border-top-left-radius: 3px;

  border-top-right-radius: 3px;
}

一些属性可以合并简写,比如:

  • padding
  • margin
  • font
  • background
  • border
  • border-radius

属性简写需要非常清楚属性值的正确顺序,而且在大多数情况下并不需要设置属性简写中包含的所有值,所以建议尽量分开声明会更加清晰。使用简写前,想一想有没有必要,少于三个合并属性建议不要简写。

这里有一篇关于简写的好文章

##选择器命名采用-分隔

/* 不推荐 */

.hotelTitle {
  font-weight: bold;
}

/* 推荐 */

.hotel-title {
  font-weight: bold;
}
  • 比使用驼峰更加清晰。
  • 产品线-产品-模块-子模块

#Javascript

  • JS 换行缩进:采用 4 空格
  • 结束行添加分号;
  • 避免使用 eval()
  • JS 调试使用console.log()console.dir(),避免使用alert(),线上版需要注释或删掉所有调试代码

##引号

最外层统一使用单引号:

// 不推荐

var x = "test";

// 推荐

var y = "foo",
  z = '<div id="test"></div>';

##变量命名

var thisIsMyName;

var goodID;

var reportURL;

var AndroidVersion;

var iOSVersion;

var MAX_COUNT = 10;

function Person(name) {
  this.name = name;
}

// 不推荐

var body = $("body");

// 推荐

var $body = $("body");
  • 标准变量采用驼峰式命名
  • 常量全大写,用下划线连接
  • 特殊处理:ID,URL,Android,iOS
  • 构造函数,大写第一个字母
  • jQuery 变量首字符为 $, 私有变量:首字符为_

##变量声明

function doSomethingWithItems(items) {
  // 使用一个var声明

  var value = 10,
    result = value + 10,
    i,
    len;

  for (i = 0, len = items.length; i < len; i++) {
    result += 10;
  }
}

一个函数作用域中所有的变量声明尽量提到函数首部,用一个 var 声明,不允许出现两个连续的 var 声明。

#Smarty 模板

##划清 PHP 与 Smarty 的界限

PHP 只是负责输出数据,并保持干净。切勿将业务逻辑代码放入 Smarty 中。

##组合大于继承

尽量不使用继承,即使使用,继承关系不要超过两层。

##逻辑尽可能简洁,判断不要超过三层

Smarty 模板只是负责展示数据,尽量不要掺入逻辑判断,但判断过多时,就应该思考是否应该把这部分判断逻辑放入 PHP 端?或者,产品的业务逻辑如此复杂,是否已经是走入了错误的方向?如果你有更好的解决方式,奔向 PM 理论一番吧,少年,如果能想到这一步,你已经在成长。

Smarty 官方最佳实践

#性能清单

##常规

  • 是否启用 HTTP2?
  • 静态文件是否使用 CDN?独立域名?
  • 静态文件域名是否做到无 Cookie?
  • DNS 预取功能是否开启?

##资源

  • JavaScript/CSS/HTML 文件是否合并、压缩?
  • 是否存在行内样式和 JS?
  • CSS 有没有使用@import
  • 静态文本文件有没有开启 Gzip?
  • 是否做到科学使用图片格式?(PNG,JPG,GIF…适用场景及尺寸合适)
  • 图片有没有压缩处理?
  • 图片资源有没有开启浏览器缓存?
  • SVG 文件有没有压缩处理?
  • 浏览器缓存是否做到高效利用?
  • 对于非关键资源有没有做到异步或者延迟处理?

##度量标准

通常,页面的性能通过以下数据大体感知出:

  • 所有文件的数量
  • 所有文件的大小
  • DomReady 时间
  • 页面下载时间

##渲染性能

  • CSS 在头部加载
  • JS 文件在文档底部加载
  • script标签开启defer特性
  • 假如 JS 文件在头部加载,放在 CSS 之后
  • 60fps 情况下页面依然可以滚动浏览
  • 禁用document.write
  • 防止 CSS 动画的滥用

#硬件性能

  • CPU 使用率
  • 内存使用率
  • GPU 使用率

#安全

  • 全站 HTTPS
  • 站外资源的引用开启 HTTPS
  • 启用 Robots.txt
  • XSS 成为不可能
  • 开启Content-Security-Policy,并且只允许特指的几个域名

#其它

  • html标签内正确设置语言
  • 指定charset
  • HTML 通过验证
  • 指定 404 页面
  • 指定页面打印样式

#上线检查清单

  • 设计稿高度还原(移动端:750)
  • 对业务的理解(有些问题不一定需要靠技术手段解决,锻炼伪需求的辨别能力)
  • html 标签的简洁性,语义性
  • 功能实现优先级:html>CSS>img&JS
  • 渐进增强,优雅降级(PC:>=IE9,Mobile:>=Android 4.0)
  • 交互是否完备
  • 模板和静态页的易用性(把交付,当做产品来做,换位思考,考虑后端开发的感受)e.g.链接的设置
  • 模块化(把代码,当做积木来做,为将来的维护少挖坑)
  • 广告区块有个占位就行,统一占位和样式
  • readme.txt(命名命的好,代码结构清晰,不 readme 也行)
  • 知己知彼(smarty 模板语言,php better)
  • 新技术的应用(语言、工具)
  • 雅虎军规