V1.3 @Suming Lv
[TOC]目录
0.0 总体原则
0.1 核心思想
表现、内容和行为的分离。
标记应该是结构良好、语义正确 以及 普遍合法。
渐进增强,提高用户体验。
0.2 基本原则
代码一致性:
通过保持代码风格和传统的一致性,我们可以减少遗留系统维护的负担,并降低未来系统崩溃的风险。
最佳实践:
通过遵照最佳实践,我们能确保优化的页面加载、性能以及可维护的代码。
0.3 适用原则
本规范中条目如无特殊说明的,需参照执行。其中:
*为建议
**为必须
1.0 命名规则
1.1 项目命名
- 全部采用小写方式,以中划线分隔。其中不得包含汉字、空格和特殊字符
- 避免单字母命名。命名应具备描述性
例:my-project-name
1.2 目录命名
参照项目命名规则;
有复数结构时,要采用复数命名法。
例:scripts, styles, images, data-models
1.3 文件命名
动态语言文件命名原则,以性质_描述,描述可以有多个单词,用“_”隔开,性质一般是该页面的概要。
例:
HTML文件命名:error-report.html
JS文件命名:account-model.js
CSS, LESS文件命名:retina-sprites.less
- 引用文件统一使用index.html index.htm index.asp文件名(依此顺序)
- 如果名称多而复杂并不好以英文单词命名,统一使用该名称拼音或拼音的首字母表示
- 不要随意采用单词缩写,约定俗成的除外
1.4 HTML命名
参照项目命名与文件命名规则。
1.5 JS命名
参照项目命名与文件命名规则。
1.5.1 函数命名
- 使用小驼峰式命名对象、函数和实例。
- 使用下划线 _ 开头命名私有属性。
1) 获取单个对象的方法用 get 做前缀。
2) 获取多个对象的方法用 list 做前缀。
3) 获取统计值的方法用 count 做前缀。
4) 插入的方法用 save(推荐)或 insert 做前缀。
5) 删除的方法用 remove(推荐)或 delete 做前缀。
6) 修改的方法用 set(推荐)或 update 做前缀。
1.5.2 分页命名
1) 传参值:current(当前页,默认1)、size(分页数,默认10)
2) 响应值:total(总页数,默认0)
1.5.3 其他
说明:任何类、方法、参数、变量,严控访问范围。过宽泛的访问范围,不利于模块解耦。
1.6 CSS, LESS命名
参照项目命名与文件命名规则。
2.0 HTML
2.1 语法
尽量使用语义化标签
用四个空格来代替制表符(tab)。
嵌套元素应当缩进一次(即四个空格)。
对于属性的定义,确保全部使用双引号,而不要使用单引号。
不要在自闭合(self-closing)元素的尾部添加斜线。
IMG元素加alt注释。
为超过12行的元素块或关键逻辑添加注释,全部采用如下格式。
<!-- comment Begin -->
...
<!-- comment Begin -->
HTML里插入JS时,前后需要增加空格
段落分隔符要使用实际对应的<p>元素,而不是用多个<br>标签。
在合适的条件下,充分利用<dl>(定义列表)和<blockquote>标签。
列表中的条目必须总是放置于<ul>、<ol>或<dl>中,永远不要用一组 <div>或<p>来表示。
给每个表单里的字段加上<label>标签,其中的 for 属性必须和对应的输入字段对应,这样用户就可以点击标签。同理,给标签也加上 cursor:pointer; 。
不用使用输入字段中的 size 属性。该属性是和输入字段里文本的 font-size 相关的。应该使用CSS宽度。
在某些闭合的</div> 标签旁边加上一段html注释,说明这里闭合的是什么元素。这在有大量嵌套和缩进的情况下会很有用。
不要把表格用于页面布局。
在合适的条件下,利用 microformats 和/或者 Microdata ,具体说是 hCard 和 adr。
在合适的条件下,利用<thead>、<tbody>和<th>标签 (以及Scope属性)。
避免使用过时的标签,如:<b>、<u>、<i>,而用<strong>、<em>等代替。
使用data-xxx来添加自定义数据,如:<input data-xxx="yyy"/>。
其他字符实体请参照:字符实体
2.2 HTML5 Doctype
HTML5下默认使用:<!DOCTYPE HTML>
2.3 lang属性
html标签应加上lang属性。
2.4 meta
meta的使用需要根据具体需求按需选择,具体可参照:cool-head
Demo:
<meta charset="utf-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta http-equiv="Cache-Control" content="max-age=7200" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="shortcut icon" href="favicon.ico">
<link rel="apple-touch-icon" href="/apple-touch-icon.png">
2.5 IE兼容模式
用<meta>标签可以指定页面应该用什么版本的IE来渲染;
2.6 引入 CSS 和 JavaScript 文件
根据 HTML5 规范,在引入 CSS 和 JavaScript 文件时一般不需要指定 type 属性,因为 text/css 和 text/javascript 分别是它们的默认值。
2.7 属性顺序*
属性应该按照特定的顺序出现以保证易读性;
class
id
name
data-*
src, for, type, href, value , max-length, max, min, pattern
placeholder, title, alt
aria-*, role
required, readonly, disabled
[//]: # class是为高可复用组件设计的,所以应处在第一位;
[//]: # id更加具体且应该尽量少使用,所以将它放在第二位。
2.8 boolean属性
boolean属性指不需要声明取值的属性,XHTML需要每个属性声明取值,但是HTML5并不需要;
<input type="text" disabled>
<input type="checkbox" value="1" checked>
<select>
<option value="1" selected>1</option>
</select>
2.9 JS生成标签
在JS文件中生成标签让内容变得更难查找,更难编辑,性能更差。应该尽量避免这种情况的出现。
2.10 减少标签数量
在编写HTML代码时,需要尽量避免多余的父节点;
很多时候,需要通过迭代和重构来使HTML变得更少。
2.11 实用高于完美
尽量遵循HTML标准和语义,但是不应该以浪费实用性作为代价;
任何时候都要用尽量小的复杂度和尽量少的标签来解决问题。
3.0 CSS, SCSS, LESS
使用 normalize.css 让渲染效果在不同浏览器中更一致
3.1 缩进
使用4个空格。
3.2 分号
每个属性声明末尾都要加分号。
3.3 空格
以下几种情况不需要空格:
属性名后
多个规则的分隔符','前
!important '!'后
属性值中'('后和')'前
行末不要有多余的空格
以下几种情况需要空格:
属性值前
选择器'>', '+', '~'前后
'{'前
!important '!'前
@else 前后
属性值中的','后
注释'/'后和'/'前
3.4 空行
以下几种情况需要空行:
文件最后保留一个空行
'}'后最好跟一个空行,包括less中嵌套的规则
属性之间需要适当的空行,具体见属性声明顺序
3.5 换行
以下几种情况不需要换行:
'{'前
以下几种情况需要换行:
'{'后和'}'前
每个属性独占一行
多个规则的分隔符','后
3.6 注释
注释统一用'/* */'(less或scss中也不要用'//')。
缩进与下一行代码保持一致;
可位于一个代码行的末尾,与代码间隔一个空格。
3.7 引号
最外层统一使用双引号;
url的内容要用引号;
属性选择器中的属性值需要引号。
3.8 命名
类名使用小写字母,以中划线分隔
id采用驼峰式命名
less或scss中的变量、函数、混合、placeholder采用驼峰式命名
3.9 属性声明顺序*
相关的属性声明按以下顺序做分组处理,组之间需要有一个空行。
布局定位属性–>自身属性–>文本属性–>其他属性
布局定位属性主要包括:margin、padding、float(clear)、position( top,right,bottom,left)、display、visibility、overflow等;
自身属性主要包括:width & height & background & border;
文本属性主要包括:font、color、text-align、text-decoration、text-indent等;
其他属性包括:list-style、vertical-vlign、cursor、z-index、zoom等
css详细说明参照:推荐的css属性顺序
3.10 颜色
颜色16进制用小写字母;
颜色16进制尽量用简写。
半透明效果使用rgba格式。
3.11 属性简写
属性简写需要你非常清楚属性值的正确顺序,而且在大多数情况下并不需要设置属性简写中包含的所有值,所以建议尽量分开声明会更加清晰;
margin 和 padding 相反,需要使用简写;
常见的属性简写包括:
font
background
transition
animation
3.12 媒体查询
尽量将媒体查询的规则靠近与他们相关的规则,不要将他们一起放到一个独立的样式文件中,或者丢在文档的最底部,这样做只会让大家以后更容易忘记他们。
.element {
...
}
.element-avatar{
...
}
@media (min-width: 480px) {
.element {
...
}
.element-avatar {
...
}
}
3.13 LESS或SCSS相关
声明顺序:
@extend
不包含 @content 的 @include
包含 @content 的 @include
自身属性
嵌套规则
@import 引入的文件不需要开头的'_'和结尾的'.scss';
@extend 中使用placeholder选择器;
发布的代码中不要有 @import和@debug;
去掉不必要的父级引用符号'&'。
3.14 其他
不允许有空的规则;
元素选择器用小写字母;
去掉小数点前面的0;
去掉数字中不必要的小数点和末尾的0;
属性值'0'后面不要加单位;
同个属性不同前缀的写法需要在垂直方向保持对齐,具体参照右边的写法;
无前缀的标准属性应该写在有前缀的属性后面;
不要在同个规则里出现重复的属性,如果重复的属性是连续的则没关系;
不要在一个文件里出现两个相同的规则;
用 border: 0; 代替 border: none;;
选择器不要超过4层(在scss中如果超过4层应该考虑用嵌套的方式来写);
尽量少用'*'选择器;
css的中文字符(如字体名称)务必转码成unicode码;
必须为大区块样式添加注释, 小区块适量注释。
4.0 JavaScript
4.1 缩进
- 使用4个空格
- 不要混用tab和space;
- 不要在一处使用多个tab或space;
4.2 单行长度
- 不要超过80,使用字符串连接号连接(word wrap可不考虑单行长度)。
- 程序化生成字符串时,使用模板字符串替代字符串连接。
// good
function sayHi(name){
return `How are you ${name}?`
}
4.3 分号
每行逻辑后面需要以分号结尾
4.4 空格
以下几种情况不需要空格:
对象的属性名后
前缀一元运算符后
后缀一元运算符前
函数调用括号前
无论是函数声明还是函数表达式,'('前不要空格
数组的'['后和']'前
对象的'{'后和'}'前
运算符'('后和')'前
以下几种情况需要空格:
二元运算符前后
三元运算符'?:'前后
代码块'{'前
下列关键字前:else, while, catch, finally
下列关键字后:if, else, for, while, do, switch, case, try, catch, finally, with, return, typeof
单行注释'//'后(若单行注释和代码同行,则'//'前也需要),多行注释'*'后
对象的属性值前
for循环,分号后留有一个空格,前置条件如果有多个,逗号后留一个空格
无论是函数声明还是函数表达式,'{'前一定要有空格
函数的参数之间
// not good
var a = {
b :1
}
// good
var a = {
b: 1
}
// not good
++ x
y ++
z = x?1:2
// good
++x
y++
z = x ? 1 : 2
// not good
var a = [ 1, 2 ]
// good
var a = [1, 2]
// not good
var a = ( 1+2 )*3
// good
var a = (1 + 2) * 3
// no space before '(', one space before '{', one space between function parameters
var doSomething = function(a, b, c) {
// do something
}
// no space before '('
doSomething(item)
// not good
for(i=0;i<6;i++){
x++
}
// good
for (i = 0; i < 6; i++) {
x++
}
4.5 空行
以下几种情况需要空行:
- 变量声明后(当变量声明在代码块的最后一行时,则无需空行)
- 注释前(当注释在代码块的第一行时,则无需空行)
- 代码块后(在函数调用、数组、对象中则无需空行)
- 文件最后保留一个空行
4.6 换行
以下几种情况不需要换行:
- 下列关键字后:else, catch, finally
- 代码块'{'前
以下几种情况需要换行:
- 代码块'{'后和'}'前
- 变量赋值后
- 在逗号后
- 表达式超出或即将超出规定的列宽(代码列宽控制在110或120字符左右),第二行相对第一行缩进 4 个空格,从第三行开始,不再继续缩进
- 在操作符前换行,运算符与下文一起换行,方法调用的点符号与下文一起换行
// not good
var a = {
b: 1
, c: 2
};
x = y
? 1 : 2;
// good
var a = {
b: 1,
c: 2
};
x = y ? 1 : 2;
x = y ?
1 : 2;
// no need line break with 'else', 'catch', 'finally'
if (condition) {
...
} else {
...
}
try {
...
} catch (e) {
...
} finally {
...
}
// not good
function test()
{
...
}
// good
function test() {
...
}
// not good
var a, foo = 7, b,
c, bar = 8
// good
var a,
foo = 7,
b, c, bar = 8
4.7 单行注释
双斜线后,必须跟一个空格;
缩进与下一行代码保持一致;
可位于一个代码行的末尾,与代码间隔一个空格。
4.8 多行注释
最少三行, '*'后跟一个空格,具体参照右边的写法;
建议在以下情况下使用:
难于理解的代码段
可能存在错误的代码段
浏览器特殊的HACK代码
业务逻辑强相关的代码
/*
* one space after '*'
*/
var x = 1
4.9 文档注释
各类标签@param, @method等请参考 JSDoc中文、usejsdoc和JSDoc Guide;
建议在以下情况下使用:
所有常量
所有函数
所有类
/**
* @func
* @desc 一个带参数的函数
* @param {string} a - 参数a
* @param {number} b=1 - 参数b默认值为1
* @param {string} c=1 - 参数c有两种支持的取值 1—表示x 2—表示xx
* @param {object} d - 参数d为一个对象
* @param {string} d.e - 参数d的e属性
* @param {string} d.f - 参数d的f属性
* @param {object[]} g - 参数g为一个对象数组
* @param {string} g.h - 参数g数组中一项的h属性
* @param {string} g.i - 参数g数组中一项的i属性
* @param {string} [j] - 参数j是一个可选参数
*/
function foo(a, b, c, d, g, j) { ... }
4.10 引号
最外层统一使用单引号。
4.11 变量命名
标准变量采用驼峰式命名(除了对象的属性外,主要是考虑到cgi返回的数据)
'ID'在变量名中全大写
'URL'在变量名中全大写
'Android'在变量名中大写第一个字母
'iOS'在变量名中小写第一个,大写后两个字母
常量全大写,用下划线连接
构造函数,大写第一个字母
jquery对象必须以'$'开头命名
var thisIsMyName;
var goodID;
var reportURL;
var AndroidVersion;
var iOSVersion;
var MAX_COUNT = 10;
function Person(name) {
this.name = name;
}
// not good
var body = $('body');
// good
var $body = $('body');
4.12 变量声明
- 使用函数声明代替函数表达式。
- 一个函数作用域中所有的变量声明尽量提到函数首部,用一个var或let声明,不允许出现两个连续的var或let声明。
- 使用对象属性值的简写,并把简写的属性分组。
const name = 'name';
const age = 'age';
// bad
const obj = function(){
}
// good
const obj = {
name,
age,
sex: '男',
height: '170'
}
- 使用解构存取和使用多属性对象。因为解构能减少临时引用属性。
// bad
function getFullName(user){
const fileName = user.firstName;
const lastName = user.lastName;
return `${firstName} ${lastName}`
}
// good
function getFullName(user){
const { firstName, lastName } = user;
return `${firstName} ${lastName}`
}
// best
function getFullName({ firstName, lastName }){
return `${firstName} ${lastName}`
}
4.13 函数
对上下文this的引用只能使用'_this', 'that', 'self'其中一个来命名;
不要给inline function命名;
参数之间用', '分隔,注意逗号后有一个空格。
直接给函数的参数指定默认值,不要使用一个变化的函数参数。
// bad
function handleThings(opts){
opts = opts || {};
}
// good
function handleThings(opts = {}){
}
4.14 箭头函数
- 当你必须使用函数表达式(或传递一个匿名函数)时,使用箭头函数符号。
因为箭头函数创造了新的 this 执行环境,通常情况下都能满足你的需求,而且这样的写法更为简洁。
// bad
[1, 2, 3].map(function (x) {
return x * x;
})
// good
[1, 2, 3].map(x => {
return x * x;
})
- 如果一个函数适合用一行写出并且只有一个参数,那就把花括号、圆括号和 return 都省略掉。如果不是,那就不要省略。
// good
[1, 2, 3].map(x => x * x);
// good
[1, 2, 3].map((total, x) => {
return total + x;
})
4.15 构造函数
- 总是使用class,避免直接操作prototype。
// bad
function Queue(contents = []){
this._queue = [...contents];
}
Queue.prototype.pop = function(){
const value = this._queue[0];
this._queue.splice(0, 1);
return value;
}
// good
class Queue {
constructor(contents = []){
this._queue = [...contents];
}
pop(){
const value = this._queue[0];
this._queue.splice(0, 1);
return value;
}
}
- 使用 extends 继承。extends 是一个内建的原型继承方法并且不会破坏 instanceof 。
// bad
const inherits = require('inherits');
function PeekableQueue(contents) {
Queue.apply(this, contents);
}
inherits(PeekableQueue, Queue);
PeekableQueue.prototype.peek = function() {
return this._queue[0];
}
// good
class PeekableQueue extends Queue {
peek() {
return this._queue[0];
}
}
- 方法可以返回 this 来帮助链式调用。
// bad
Jedi.prototype.jump = function() {
this.jumping = true;
return true;
};
Jedi.prototype.setHeight = function(height) {
this.height = height;
};
const luke = new Jedi();
luke.jump(); // => true
luke.setHeight(20); // => undefined
// good
class Jedi {
jump() {
this.jumping = true;
return this;
}
setHeight(height) {
this.height = height;
return this;
}
}
const luke = new Jedi();
luke.jump().setHeight(20);
4.16 数组、对象
对象属性名不需要加引号;
对象以缩进的形式书写,不要写在一行;
数组、对象最后不要有逗号。
4.17 括号
下列关键字后必须有大括号(即使代码块的内容只有一行):
if, else, for, while, do, switch, try, catch, finally, with。
4.18 null
适用场景:
初始化一个将来可能被赋值为对象的变量
与已经初始化的变量做比较
作为一个参数为对象的函数的调用传参
作为一个返回对象的函数的返回值
不适用场景:
不要用null来判断函数调用时有无传参
不要与未初始化的变量做比较
4.19 undefined
永远不要直接使用undefined进行变量判断;
使用typeof和字符串'undefined'对变量进行判断。
4.20 jshint
用'===', '!=='代替'==', '!=';
for-in里一定要有hasOwnProperty的判断;
不要在内置对象的原型上添加方法,如Array, Date;
不要在内层作用域的代码里声明了变量,之后却访问到了外层作用域的同名变量;
变量不要先使用后声明;
不要在一句代码中单单使用构造函数,记得将其赋值给某个变量;
不要在同个作用域下声明同名变量;
不要在一些不需要的地方加括号,例:delete(a.b);
不要使用未声明的变量(全局变量需要加到.jshintrc文件的globals属性里面);
不要声明了变量却不使用;
不要在应该做比较的地方做赋值;
debugger不要出现在提交的代码里;
数组中不要存在空元素;
不要在循环内部声明函数;
不要像这样使用构造函数,例:new function () { ... }, new Object;
5.0 图片及第三方资源
5.1 存放目录
- 静态类资源置于项目根目录下static文件夹
- 配置类资源置于项目根目录下assets文件夹
- 第三方库类资源置于项目根目录下components文件夹
5.2 格式
图片格式仅限于gif || png || jpg,尽可能使用 PNG 格式的图片;
在保证视觉效果的情况下选择最小的图片格式与图片质量, 以减少加载时间;
5.3 命名
命名全部用小写英文字母、数字或 _ 的组合,其中不得包含汉字、空格、特殊字符;
图片的名称分为头尾两部分,用下划线隔开,头部分表示此图片的大类性质,具体规则如下:
放置在页面顶部的广告、装饰图案等长方形的图片取名: banner
标志性的图片取名: logo
在页面上位置不固定并且带有链接的小图片取名: btn
在页面上某一个位置连续出现,性质相同的链接栏目的图片取名: menu
装饰用的图片取名: pic
不带链接表示标题的图片取名: title
无意义仅做标识用的图标取名: icon
切换效果图片命名规范为"图片名_on/off"。 例如:menu1_on.gif menu1_off.gif 尽量用易懂的词汇, 便于团队其他成员理解;
5.4 其他
运用css sprite技术集中小的背景图或图标, 减小页面http请求, 但注意, 请务必在对应的sprite psd源图中划参考线, 并保存至img目录下。
6.0 JS框架&UI库
6.1 JS通用库
6.1.1 UI
6.1.2 JS Plugin
- 时间格式化 Day.js、Momentjs
- 报表设计器 activereportsjs
6.1 jquery
6.1.1 jQuery-ui库
6.1.2 jQuery Plugin
- IE对HTML5标签支持,以及浏览器特性检测:Modernizr & html5shiv
- 定制&统一 浏览器的滚动条样式:jquery-scroll & Lionbars
- hover提示效果文字:bootstrap-tooltips & tipsy
- 滚动条跟随nav效果:bootstrap-scrollspy
- 提示冒泡文字:grumble.js
- 导航栏过渡效果:lavalamp
- 移动设备的滚动效果:iscroll 4
- Mac OS Lion 风格的滚动条:Lionbars
- 弹性SlideShow:kwicks for jQuery
- 瀑布流:isotope
- 抖动效果:jQ shake
- LightBox:fancyBox
- KenDo UI:KenDo UI
- textarea自适应高度:elastic
- 提示区域 & 提示层:noty
- 浮动话题泡:jQuery grumble
- 旋转进度:jQuery Knob
6.2 Vue 注意点
- 组件命名:
- 连字符:字母全小写且必须包含一个连字符(推荐,当直接在 DOM 中使用一个组件时)
Vue.component('my-component-name', { /* ... */ });
- 大驼峰: 注意:当使用的不是字符串模板时,camelCase (驼峰式命名) 的 props属性需要转换为相对应的 kebab-case (连字符命名)
(1)、HTML模板:
Vue.component('child', {
// 在 JavaScript 中使用 camelCase
props: ['myMessage'],
template: '<span>{{ myMessage }}</span>'
})
(2)、字符串模板:
<!-- 在 HTML 中使用kebab-case -->
<child my-message="hello!"></child>
6.2.1 Vue-ui库
移动端:
PC端:
- element UI (饿了么)
- iview
- ant-design-vue
- vuetify
- Zent (有赞)
6.2.2 Vue Plugin
- 自定义滚动条 happy-scroll & Vuescroll
- 虚拟滚动列表 vue-virtual-scroll-list
- 拖拽交换位置 Draggable
- 自定义动态表格 vxe-table 文档
6.2.3 Vue
6.3 React
6.3.1 React-ui库
移动端:
- Ant Design Mobile (Alibaba)
- Bee Mobile
- Material-UI (Google 响应式)
- Onsen UI (Angular1、Angular2+、React、Vue)
PC端:
- Ant-design (Alibaba)
- Material-UI (Google 响应式)
- Semantic-UI-React
- React-Bootstrap
- React-Desktop (MacOS & windows)
6.3.2 React Plugin
6.4 Angular
6.4.1 Angular-ui库
移动端:
- Ant Design Mobile of Angular
- Ionic
- Onsen UI (Angular1、Angular2+、React、Vue)
PC端:
- Ant Design of Angular
- Angular Material
- Kendo UI for Angular
- agGrid (js、Angular1、Angular2+、React、Vue)
- PrimeNG
- Clarity
6.4.2 Angular Plugin
6.5 小程序、公众号
6.5.1 小程序、公众号ui库
-
WeUI WXSS (微信)
-
iView WeApp (微信)
-
Vant Weapp (微信)
-
mpvue (微信、vue)
-
wepy (微信)
-
MinUI (微信)
-
Wux WeApp (微信)
-
uni-app (微信、支付宝、Android、iOS、H5)
-
Taro (微信、支付宝、H5、Native)
6.5.2 小程序、公众号Plugin
- 富文本 wxParse
6.6 Webpack & NodeJs
6.6.1 Webpack Plugin
- svg图标 svg-sprite-loader 自动加载打包,方便维护
6.6.2 npm Plugin
7.0 缓存
8.0 HTTP及接口请求
9.0 性能优化
9.1 前端优化
- 尽量减少HTTP请求:把多个css文件合并成一个。
- 使用Minify压缩精简Javascript和Css代码文件。
- 把CSS文件放到HTML代码页面头部,这么做可以避免浏览器在解释一次之后,使用css进行第二次解释,因为用户对css裸奔的效果根本就不感兴趣。
- 避免 CSS 表达式,凡是只有IE能用的东西,都不是好东西。
- 从页面中剥离 JavaScript 与 CSS放到外部文件中引用,剥离后,能够有针对性的对其进行单独的处理策略,比如压缩或者缓存策略。
- 使用 <link> 而不是 @import,在 IE 中 @import 指令等同于把 link 标记写在 HTML 的底部,这与第一条相违背。
- JS尽量放到页面最下端,当一个脚本在下载的时候,浏览器会卡住,无法响应其他请求。所以,可以将功能性的JS放到最后端去处理。
- 如果是移动端,单个数据对象小于25KB。
- 注意控制Cookie大小和污染,因为Cookie是本地的磁盘文件,每次浏览器都会去读取相应的Cookie,所以建议去除不必要的Coockie,使Coockie体积尽量小以减少对用户响应的影响。
9.2 图片优化
- 压缩图片并使用 CSS Sprites 对图片优化,简单的说就是"利用 CSS background 相关元素进行背景图绝对定位",把多次HTTP 调用变为一次调用,减少HTTP请求。
- 尽可能的使用 PNG 格式的图片,因为和GIF相比,PNG有更多的功能和更小的体积。
- 用更小的并且可缓存的 favicon.ico,原因是没有favicon.ico,服务器会返回一个404,与可以长时间缓存的文件相比,大量的404会增加服务器的响应数量。
9.3 服务端优化
- 使用CDN加速,静态资源做CDN部署。(使用前端CDN增加网页的并行载入速度,减少本地服务器的负担,节省流量。一个浏览器对与同一域名的并行下载的个数默认是2个, HTTP.1.0中规定的是4个。这样,我们可以使用不同的域名来提升下载的速度)
- 开启静态文件压缩,使用Gzip压缩内容,以减少宽带需求,让页面更快加载出来。
- 对Ajax请求使用GET方法,XMLHttpRequest POST 要两步,而 GET 只需要一步。
- 尽量使用JSON格式来进行数据交换。(与XML序列化相比,JSON序列化后产生的数据一般要比XML序列化后数据体积小)
- 前后端做数据分离,让搜索服务解耦,在高并发情况下更灵活做负载均衡。(前端使用Vue.js、AngularJs等,数据来源可以不限编程语言)
- 后端数据大部分来自缓存,加载快,给用户更快的体验。(商品详情、商品库存等,可以放在缓存(redis集群),避免频繁去数据库取数据,提高商品信息的读能力)
参考文章:
CDN公共库、前端开发常用插件一览表
网站前端性能优化总结
前端各种优化
Web前端优化
提高网页效率的14条准则
9.4 前端性能检测工具
浏览器插件
Google Page Speed: 谷歌网页速度测试是一个开源的Firefox / Firebug插件。 网站管理员和Web开发人员可以使用该工具来评估其网页的性能并获取有关如何改进它们的建议。
YSlow: YSlow用来分析网页性能,并在高性能网页规则基础上建议如何改善。
PageTest: Internet Explorer的插件,常用来显示浏览器加载内容时发出的请求并提供了该进页面性能的建议。
Pylot: 开源的测试工具,可以测试网站的性能和可扩展性。 它运行HTTP负载测试,这是有用的容量规划,基准,分析和系统调整。
在线测试网站
Pingdom: 测试网站所有对象的加载时间(HTML,images,JavaScript,CSS,嵌入式框架等)。 您还可以检查网站每个元素的加载速度并改善加载缓慢的项目。 在测试结果中,可以看到网站每个元素的加载时间报告,元素的大小和元素的总数量。
测试地址:www.pingdom.com/
GTmetrix: 结合了最流行的Firefox性能组件YSlow的和谷歌网页速度测试工具。 Gtmetrix给你提供改进网站速度的建议,虽然YSlow的和谷歌网页的速度测试的建议是针对Firefox的,也可以适用于其他浏览器。
测试地址:gtmetrix.com/
Site-Perf: 它模拟浏览器下载图片,CSS,JS和其他文件,在报告中你可以看到先加载网站的哪些页以及加载时间。 这是十分有用的性能报告,可以用来查找到提高你的网站的载入速度需要改善的元素。 测试地址:gtmetrix.com/
参考文章:
18个常用的网站性能测试工具
10.0 终端兼容
10.1 分辨率兼容
10.1.1 移动端兼容
-
不同的dpr下,加载不同的尺寸的图片
如果有图片服务器,通过url获取参数,然后可以控制图片质量,也可以将图片裁剪成不同的尺寸。只需上传大图(@2x),其余小图都交给图片服务器处理,我们只要负责拼接url即可。
如果没有图片服务器,准备多份不同尺寸的图片@1x@2x@3x -
不同的dpr下,1px宽的直线需要缩放0.5
//方案一:缩小0.5倍来达到0.5px的效果 border-bottom: 1px solid #ddd; -webkit-transform:scaleY(.5); -webkit-transform-origin:0 0; //方案二:添加如下的meta标签,设置viewport(scale 0.5) <meta name="viewport" content="width=640,initial-scale=0.5,maximum-scale=0.5, minimum-scale=0.5,user-scalable=no">
10.2 浏览器版本兼容
一、标识区别: 区别IE6,IE7,IE8,FF。
-
IE都能识别* ; 标准浏览器(如FF)不能识别*;
-
IE6能识别*,但不能识别 !important; IE6在样式前面加_
-
IE7能识别*,也能识别!important;
-
IE8能识别\ 9 例如:background:red \9;
-
firefox不能识别*,但能识别!important;
-
IE6和firefox的区别: background:orange;*background:blue; 意思就是火狐浏览器的背景颜色是橙色,而IE浏览器的背景色是蓝色.
-
IE6和IE7的区别: background:green !important;background:blue; 意思指的是:IE7的背景颜色是绿色,IE6的背景颜色是蓝色
-
IE7和FF的区别: background:orange; *background:green; 意思指的是:火狐浏览器的背景颜色是橙色,而IE7的背景颜色是绿色
-
FF,IE7,IE6的区别: background:orange; *background:green !important; *background:blue; 意思是火狐浏览器的的背景橙色,IE7浏览器的背景颜色是绿色,而IE6浏览器的颜色是蓝色.