GitHub 上一份很受欢迎的前端代码优化指南-强烈推荐收藏

简介:

看到一份很受欢迎的前端代码指南,根据自己的理解进行了翻译,但能力有限,对一些JS代码理解不了,如有错误,望斧正。

HTML

语义化标签

HTML5 提供了很多语义化元素,更好地帮助描述内容。希望你能从这些丰富的标签库中受益。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<!-- bad -->
< div  id="main">
   < div  class="article">
     < div  class="header">
       < h1 >Blog post</ h1 >
       < p >Published: < span >21st Feb, 2015</ span ></ p >
     </ div >
     < p >…</ p >
   </ div >
</ div >
 
<!-- good -->
< main >
   < article >
     < header >
       < h1 >Blog post</ h1 >
       < p >Published: < time  datetime="2015-02-21">21st Feb, 2015</ time ></ p >
     </ header >
     < p >…</ p >
   </ article >
</ main >

请确保正确使用语义化的标签,错误的用法甚至不如保守的用法。

1
2
3
4
5
6
7
8
9
10
11
<!-- bad -->
< h1 >
   < figure >
     < img  alt=Company src=logo.png>
   </ figure >
</ h1 >
 
<!-- good -->
< h1 >
   < img  alt=Company src=logo.png>
</ h1 >

简洁

确保代码简洁性,不要再采用XHTML的旧做法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<!-- bad -->
<! doctype  html>
< html  lang=en>
   < head >
     < meta  http-equiv=Content-Type content="text/html; charset=utf-8" />
     < title >Contact</ title >
     < link  rel=stylesheet href=style.css type=text/css />
   </ head >
   < body >
     < h1 >Contact me</ h1 >
     < label >
       Email address:
       < input  type=email placeholder=you@email.com required=required />
     </ label >
     < script  src=main.js type=text/javascript></ script >
   </ body >
</ html >
 
<!-- good -->
<! doctype  html>
< html  lang=en>
   < meta  charset=utf-8>
   < title >Contact</ title >
   < link  rel=stylesheet href=style.css>
 
   < h1 >Contact me</ h1 >
   < label >
     Email address:
     < input  type=email placeholder=you@email.com required>
   </ label >
   < script  src=main.js></ script >
</ html >

可用性

可用性不应该是事后才考虑的事情。你不必成为WCAG专家来改进网站,你可以通过简单的修改做出不错的效果,例如;

  • 正确使用alt属性
  • 确保链接和按钮正确使用(不要用<div class="button">这种粗暴的做法)
  • 不依赖于颜色来传达信息
  • 给表单做好lable标记
1
2
3
4
5
<!-- bad -->
  < h1 >< img  alt="Logo" src="logo.png"></ h1 >
 
  <!-- good -->
  < h1 >< img  alt="My Company, Inc." src="logo.png"></ h1 >

语言

定义语言和字符编码是可选项,建议在文档级别处定义。使用UTF-8编码。

1
2
3
4
5
6
7
8
9
10
<!-- bad -->
<! doctype  html>
< title >Hello, world.</ title >
 
<!-- good -->
<! doctype  html>
< html  lang=en>
   < meta  charset=utf-8>
   < title >Hello, world.</ title >
</ html >

性能

除非有非要在加载内容前加载脚本的必要性由,不然别这样做,这样会阻碍网页渲染。如果你的样式表很大,必须独立放到一个文件里。两次HTTP 请求不会显著降低性能。

1
2
3
4
5
6
7
8
9
10
11
12
13
<!-- bad -->
<! doctype  html>
< meta  charset=utf-8>
< script  src=analytics.js></ script >
< title >Hello, world.</ title >
< p >...</ p >
 
<!-- good -->
<! doctype  html>
< meta  charset=utf-8>
< title >Hello, world.</ title >
< p >...</ p >
< script  src=analytics.js></ script >

CSS

分号

不能漏写分号

1
2
3
4
5
6
7
8
9
/* bad */
div {
   color red
}
 
/* good */
div {
   color red ;
}

盒模型

整个文档的盒模型应该要相同,最好使用global * { box-sizing: border-box; }定义。不要修改某个元素的盒模型。

1
2
3
4
5
6
7
8
9
10
11
/* bad */
div {
   width 100% ;
   padding 10px ;
   box-sizing: border-box;
}
 
/* good */
div {
   padding 10px ;
}

尽量不要改变元素默认行为。保持默认的文本流。比如,移出一个图片下面的一个白块,不影响原本的显示:

1
2
3
4
5
6
7
8
9
/* bad */
img {
   display block ;
}
 
/* good */
img {
   vertical-align middle ;
}

类似的,尽量不要改变浮动方式。

1
2
3
4
5
6
7
8
9
10
11
12
/* bad */
div {
   width 100px ;
   position absolute ;
   right 0 ;
}
 
/* good */
div {
   width 100px ;
   margin-left auto ;
}

定位

有很多CSS定位方法,尽量避免使用以下方法,根据性能排序:

1
2
3
4
5
6
display block ;
display : flex;
position relative ;
position : sticky;
position absolute ;
position fixed ;

选择器

紧密耦合DOM选择器,三个层级以上建议加class:

1
2
3
4
5
/* bad */
div:first-of-type :last-child > p ~ *
 
/* good */
div:first-of-type .info

避免不必要的写法:

1
2
3
4
5
6
7
8
9
/* bad */
img[src$=svg], ul > li:first-child {
   opacity:  0 ;
}
 
/* good */
[src$=svg], ul > :first-child {
   opacity:  0 ;
}

指明

不要让代码难于重写,让选择器更精确,减少ID、避免使用!important

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/* bad */
.bar {
   color green  !important ;
}
.foo {
   color red ;
}
 
/* good */
.foo.bar {
   color green ;
}
.foo {
   color red ;
}

覆盖

覆盖样式会使维护和调试更困难,所以要尽量避免。

1
2
3
4
5
6
7
8
9
10
11
12
/* bad */
li {
   visibility hidden ;
}
li:first-child {
   visibility visible ;
}
 
/* good */
li + li {
   visibility hidden ;
}

继承

不要把可继承的样式重复声明:

1
2
3
4
5
6
7
8
9
/* bad */
div h 1 , div p {
   text-shadow 0  1px  0  #fff ;
}
 
/* good */
div {
   text-shadow 0  1px  0  #fff ;
}

简洁

保持代码的简洁。使用属性缩写。不必要的值不用写。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/* bad */
div {
   transition:  all  1 s;
   top 50% ;
   margin-top -10px ;
   padding-top 5px ;
   padding-right 10px ;
   padding-bottom 20px ;
   padding-left 10px ;
}
 
/* good */
div {
   transition:  1 s;
   top : calc( 50%  10px );
   padding 5px  10px  20px ;
}

语言

能用英文的时候不用数字。

1
2
3
4
5
6
7
8
9
/* bad */
:nth-child( 2 n +  1 ) {
   transform: rotate( 360 deg);
}
 
/* good */
:nth-child(odd) {
   transform: rotate( 1 turn);
}

供应商的前缀

砍掉过时的供应商前缀。必须使用时,需要放在标准属性前:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/* bad */
div {
   transform: scale( 2 );
   -webkit-transform: scale( 2 );
   -moz-transform: scale( 2 );
   -ms-transform: scale( 2 );
   transition:  1 s;
   -webkit-transition:  1 s;
   -moz-transition:  1 s;
   -ms-transition:  1 s;
}
 
/* good */
div {
   -webkit-transform: scale( 2 );
   transform: scale( 2 );
   transition:  1 s;
}

动画

除了变形和改变透明度用animation,其他尽量使用transition

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/* bad */
div:hover {
   animation:  move  1 s forwards;
}
@keyframes  move  {
   100%  {
     margin-left 100px ;
   }
}
 
/* good */
div:hover {
   transition:  1 s;
   transform: translateX( 100px );
}

单位

可以不用单位时就不用。建议用rem。时间单位用sms好。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/* bad */
div {
   margin 0px ;
   font-size : . 9em ;
   line-height 22px ;
   transition:  500 ms;
}
 
/* good */
div {
   margin 0 ;
   font-size : . 9 rem;
   line-height 1.5 ;
   transition: . 5 s;
}

颜色

需要做透明效果是用rgba,否则都用16进制表示:

1
2
3
4
5
6
7
8
9
/* bad */
div {
   color : hsl( 103 54% 43% );
}
 
/* good */
div {
   color #5a3 ;
}

绘图

减少HTTPS请求,尽量用CSS绘图替代图片:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/* bad */
div::before {
   content url (white- circle .svg);
}
 
/* good */
div::before {
   content "" ;
   display block ;
   width 20px ;
   height 20px ;
   border-radius:  50% ;
   background #fff ;
}

注释

1
2
3
4
5
6
7
8
9
10
11
/* bad */
div {
   //  position relative ;
   transform: translateZ( 0 );
}
 
/* good */
div {
   /* position: relative; */
   will-change: transform;
}

JavaScript

性能

有可读性、正确性和好的表达比性能更重要。JavaScript基本上不会是你的性能瓶颈。有些可优化细节例如:图片压缩、网络接入、DOM文本流。如果你只能记住本指南的一条规则,那就记住这条吧。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// bad (albeit way faster)
const arr = [1, 2, 3, 4];
const len = arr.length;
var  i = -1;
var  result = [];
while  (++i < len) {
   var  n = arr[i];
   if  (n % 2 > 0)  continue ;
   result.push(n * n);
}
 
// good
const arr = [1, 2, 3, 4];
const isEven = n => n % 2 == 0;
const square = n => n * n;
 
const result = arr.filter(isEven).map(square);

Statelessness

尽量保持代码功能简单化,每个方法都对其他其他代码没有负影响。不使用外部数据。返回一个新对象而不是覆盖原有的对象。

1
2
3
4
5
6
7
// bad
const merge = (target, ...sources) => Object.assign(target, ...sources);
merge({ foo:  "foo"  }, { bar:  "bar"  });  // => { foo: "foo", bar: "bar" }
 
// good
const merge = (...sources) => Object.assign({}, ...sources);
merge({ foo:  "foo"  }, { bar:  "bar"  });  // => { foo: "foo", bar: "bar" }

尽量使用内置方法

1
2
3
4
5
6
7
// bad
const toArray = obj => [].slice.call(obj);
 
// good
const toArray = (() =>
   Array.from ? Array.from : obj => [].slice.call(obj)
)();

严格条件

在非必要严格条件的情况不要使用。

1
2
3
4
5
// bad
if  (x === undefined || x ===  null ) { ... }
 
// good
if  (x == undefined) { ... }

对象

不要在循环里强制改变对象的值,,可以利用array.prototype方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
// bad
const sum = arr => {
   var  sum = 0;
   var  i = -1;
   for  (;arr[++i];) {
     sum += arr[i];
   }
   return  sum;
};
 
sum([1, 2, 3]);  // => 6
 
// good
const sum = arr =>
   arr.reduce((x, y) => x + y);
 
sum([1, 2, 3]);  // => 6
If you can't, or  if  using array.prototype methods is arguably abusive, use recursion.
 
// bad
const createDivs = howMany => {
   while  (howMany--) {
     document.body.insertAdjacentHTML( "beforeend" "<div></div>" );
   }
};
createDivs(5);
 
// bad
const createDivs = howMany =>
   [...Array(howMany)].forEach(() =>
     document.body.insertAdjacentHTML( "beforeend" "<div></div>" )
   );
createDivs(5);
 
// good
const createDivs = howMany => {
   if  (!howMany)  return ;
   document.body.insertAdjacentHTML( "beforeend" "<div></div>" );
   return  createDivs(howMany - 1);
};
createDivs(5);

Arguments

忘记arguments对象吧,其他参数是更好的选择,因为:

  • 它已经被定义
  • 它是一个真的数组,很方便使用

    1
    2
    3
    4
    5
    6
    // bad
    const sortNumbers = () =>
       Array.prototype.slice.call(arguments).sort();
     
    // good
    const sortNumbers = (...numbers) => numbers.sort();

Apply

忘记apply(),改用运算操作。

1
2
3
4
5
6
7
8
const greet = (first, last) => `Hi ${first} ${last}`;
const person = [ "John" "Doe" ];
 
// bad
greet.apply( null , person);
 
// good
greet(...person);

Bind

不用bind()方法,这有更好的选择:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// bad
[ "foo" "bar" ].forEach(func.bind( this ));
 
// good
[ "foo" "bar" ].forEach(func,  this );
// bad
const person = {
   first:  "John" ,
   last:  "Doe" ,
   greet() {
     const full =  function () {
       return  `${ this .first} ${ this .last}`;
     }.bind( this );
     return  `Hello ${full()}`;
   }
}
 
// good
const person = {
   first:  "John" ,
   last:  "Doe" ,
   greet() {
     const full = () => `${ this .first} ${ this .last}`;
     return  `Hello ${full()}`;
   }
}

更好的排序

避免多重嵌套:

1
2
3
4
5
// bad
[1, 2, 3].map(num => String(num));
 
// good
[1, 2, 3].map(String);

Composition

避免方法嵌套调用,改用composition

1
2
3
4
5
6
7
8
9
10
const plus1 = a => a + 1;
const mult2 = a => a * 2;
 
// bad
mult2(plus1(5));  // => 12
 
// good
const pipeline = (...funcs) => val => funcs.reduce((a, b) => b(a), val);
const addThenMult = pipeline(plus1, mult2);
addThenMult(5);  // => 12

缓存

缓存性能测试,大数据结构和任何高代价的操作。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// bad
const contains = (arr, value) =>
   Array.prototype.includes
     ? arr.includes(value)
     : arr.some(el => el === value);
contains([ "foo" "bar" ],  "baz" );  // => false
 
// good
const contains = (() =>
   Array.prototype.includes
     ? (arr, value) => arr.includes(value)
     : (arr, value) => arr.some(el => el === value)
)();
contains([ "foo" "bar" ],  "baz" );  // => false

变量

const 优于 let, let 优于 var

1
2
3
4
5
6
7
8
// bad
var  obj = {};
obj[ "foo"  "bar" ] =  "baz" ;
 
// good
const obj = {
   [ "foo"  "bar" ]:  "baz"
};

条件判断

用多个if,优于 if 、else ifelse 和switch

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// bad
var  grade;
if  (result < 50)
   grade =  "bad" ;
else  if  (result < 90)
   grade =  "good" ;
else
   grade =  "excellent" ;
 
// good
const grade = (() => {
   if  (result < 50)
     return  "bad" ;
   if  (result < 90)
     return  "good" ;
   return  "excellent" ;
})();

对象的操作

避免使用for...in

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const shared = { foo:  "foo"  };
const obj = Object.create(shared, {
   bar: {
     value:  "bar" ,
     enumerable:  true
   }
});
 
// bad
for  ( var  prop  in  obj) {
   if  (obj.hasOwnProperty(prop))
     console.log(prop);
}
 
// good
Object.keys(obj).forEach(prop => console.log(prop));

使用map

合理使用的情况下,map更强大:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// bad
const me = {
   name:  "Ben" ,
   age: 30
};
var  meSize = Object.keys(me).length;
meSize;  // => 2
me.country =  "Belgium" ;
meSize++;
meSize;  // => 3
 
// good
const me = Map();
me.set( "name" "Ben" );
me.set( "age" , 30);
me.size;  // => 2
me.set( "country" "Belgium" );
me.size;  // => 3

Curry

在别的语言里有Curry的一席之地,但在JS里避免使用。不然会是代码阅读困难。

1
2
3
4
5
6
7
// bad
const sum = a => b => a + b;
sum(5)(3);  // => 8
 
// good
const sum = (a, b) => a + b;
sum(5, 3);  // => 8

可读性

不要使用自以为是的技巧:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// bad
foo || doSomething();
 
// good
if  (!foo) doSomething();
 
// bad
void  function () {  /* IIFE */  }();
 
// good
( function () {  /* IIFE */  }());
 
// bad
const n = ~~3.14;
 
// good
const n = Math.floor(3.14);

代码重用

对写些小型、组件化、可重用的方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// bad
arr[arr.length - 1];
 
// good
const first = arr => arr[0];
const last = arr => first(arr.slice(-1));
last(arr);
 
// bad
const product = (a, b) => a * b;
const triple = n => n * 3;
 
// good
const product = (a, b) => a * b;
const triple = product.bind( null , 3);

依赖

减少第三方库的使用。当你无法完成某项工作时可以使用,但不要为了一些能自己实现的小功能就加载一个很大的库。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// bad
var  _ = require( "underscore" );
_.compact([ "foo" , 0]));
_.unique([ "foo" "foo" ]);
_.union([ "foo" ], [ "bar" ], [ "foo" ]);
 
// good
const compact = arr => arr.filter(el => el);
const unique = arr => [...Set(arr)];
const union = (...arr) => unique([].concat(...arr));
 
compact([ "foo" , 0]);
unique([ "foo" "foo" ]);
union([ "foo" ], [ "bar" ], [ "foo" ]);

  

本文转自yonghu86博客园博客,原文链接:http://www.cnblogs.com/huyong/p/5018380.html,如需转载请自行联系原作者
相关文章
|
4月前
|
前端开发 Java C++
每个前端都应该掌握的7个代码优化的小技巧
每个前端都应该掌握的7个代码优化的小技巧
|
4月前
|
前端开发
Github项目分享——免费的画图工具drow,最新前端面试题整理
Github项目分享——免费的画图工具drow,最新前端面试题整理
|
4月前
|
SQL Oracle 前端开发
Oracle效率分析,Github标星25K+超火的前端实战项目
Oracle效率分析,Github标星25K+超火的前端实战项目
|
11月前
|
前端开发 vr&ar
【前端验证】fork-join_none线程立即执行的一次代码优化记录
【前端验证】fork-join_none线程立即执行的一次代码优化记录
|
前端开发 jenkins Linux
前端项目自动化部署——超详细教程(Jenkins、Github Actions)(二)
前端项目自动化部署——超详细教程(Jenkins、Github Actions)(二)
1321 0
|
前端开发 Ubuntu jenkins
前端项目自动化部署——超详细教程(Jenkins、Github Actions)(三)
前端项目自动化部署——超详细教程(Jenkins、Github Actions)(三)
615 0
|
前端开发 JavaScript jenkins
前端项目自动化部署——超详细教程(Jenkins、Github Actions)(一)
前端项目自动化部署——超详细教程(Jenkins、Github Actions)
460 0
|
前端开发
前端项目实战拾玖-github提交代码Could not read from remote repository重新生成公钥
前端项目实战拾玖-github提交代码Could not read from remote repository重新生成公钥
42 0
|
前端开发
前端项目实战拾捌-github提交代码的公钥需要设置在全局
前端项目实战拾捌-github提交代码的公钥需要设置在全局
52 0
|
前端开发
项目实战14—前端代码优化
项目实战14—前端代码优化
65 0