编写出色CSS代码的13个建议

2011/12/02 · CSS · 1
评论 · 来源:
维奇     ·
CSS

来源: 维奇

CSS学起来并不难,但在大型项目中,就变得难以管理,特别是不同的人在CSS书写风格上稍有不同,团队上就更加难以沟通,为此总结了一些如何实现高效整洁的CSS代码原则:

1. 使用Reset但并非全局Reset

不同浏览器元素的默认属性有所不同,使用Reset可重置浏览器元素的一些默认属性,以达到浏览器的兼容。但需要注意的是,请不要使用全局Reset:

CSS

*{ margin:0; padding:0; }

1
*{ margin:0; padding:0; }

这不仅仅因为它是缓慢和低效率的方法,而且还会导致一些不必要的元素也重置了外边距和内边距。在此建议参考YUI
Reset和Eric
Meyer的做法。我跟Eric
Meyer的观点相同,Reset并不是一成不变的,具体还需要根据项目的不同需求做适当的修改,以达到浏览器的兼容和操作上的便利性。我使用的Reset如下:

CSS

/** 清除内外边距 **/ body, h1, h2, h3, h4, h5, h6, hr, p,
blockquote, /* structural elements 结构元素 */ dl, dt, dd, ul, ol, li,
/* list elements 列表元素 */ pre, /* text formatting elements
文本格式元素 */ form, fieldset, legend, button, input, textarea, /*
form elements 表单元素 */ th, td, /* table elements 表格元素 */
img/* img elements 图片元素 */{ border:medium none; margin: 0;
padding: 0; } /** 设置默认字体 **/ body,button, input, select,
textarea { font: 12px/1.5 ‘宋体’,tahoma, Srial, helvetica, sans-serif; }
h1, h2, h3, h4, h5, h6 { font-size: 100%; } em{font-style:normal;} /**
重置列表元素 **/ ul, ol { list-style: none; } /** 重置超链接元素
**/ a { text-decoration: none; color:#333;} a:hover {
text-decoration: underline; color:#F40; } /** 重置图片元素 **/ img{
border:0px;} /** 重置表格元素 **/ table { border-collapse: collapse;
border-spacing: 0; }

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
/** 清除内外边距 **/
body, h1, h2, h3, h4, h5, h6, hr, p,
blockquote, /* structural elements 结构元素 */
dl, dt, dd, ul, ol, li, /* list elements 列表元素 */
pre, /* text formatting elements 文本格式元素 */
form, fieldset, legend, button, input, textarea, /* form elements 表单元素 */
th, td, /* table elements 表格元素 */
img/* img elements 图片元素 */{
border:medium none;
margin: 0;
padding: 0;
}
/** 设置默认字体 **/
body,button, input, select, textarea {
font: 12px/1.5 ‘宋体’,tahoma, Srial, helvetica, sans-serif;
}
h1, h2, h3, h4, h5, h6 { font-size: 100%; }
em{font-style:normal;}
/** 重置列表元素 **/
ul, ol { list-style: none; }
/** 重置超链接元素 **/
a { text-decoration: none; color:#333;}
a:hover { text-decoration: underline; color:#F40; }
/** 重置图片元素 **/
img{ border:0px;}
/** 重置表格元素 **/
table { border-collapse: collapse; border-spacing: 0; }

2. 良好的命名习惯

无疑乱七八糟或者无语义命名的代码,谁看了都会抓狂。就像这样的代码:

CSS

.aaabb{margin:2px;color:red;}

1
.aaabb{margin:2px;color:red;}

我想即使是初学者,也不至于会在实际项目中如此命名一个class,但有没有想过这样的代码同样是很有问题的:

XHTML

<h1>My name is <span>Wiky</span></h1>

1
<h1>My name is <span>Wiky</span></h1>

问题在于如果你需要把所有原本红色的字体改成蓝色,那修改后就样式就会变成:

CSS

.red{color:bule;}

1
.red{color:bule;}

这样的命名就会很让人费解,同样的命名为.leftBar的侧边栏如果需要修改成右侧边栏也会很麻烦。所以,请不要使用元素的特性(颜色,位置,大小等)来命名一个class或id,您可以选择意义的命名如:#navigation{…},.sidebar{…},.postwrap{…}

这样,无论你如何修改定义这些class或id的样式,都不影响它跟HTML元素间的联系。

另外还有一种情况,一些固定的样式,定义后就不会修改的了,那你命名时就不用担忧刚刚说的那种情况,如

CSS

.alignleft{float:left;margin-right:20px;}
.alignright{float:right;text-align:right;margin-left:20px;}
.clear{clear:both;text-indent:-9999px;}

1
2
3
.alignleft{float:left;margin-right:20px;}
.alignright{float:right;text-align:right;margin-left:20px;}
.clear{clear:both;text-indent:-9999px;}

那么对于这样一个段落

XHTML

<p class=”alignleft”>我是一个段落!</p>

1
<p class="alignleft">我是一个段落!</p>

如果需要把这个段落由原先的左对齐修改为右对齐,那么只需要修改它的className就为alignright就可以了。

3. 代码缩写

CSS代码缩写可以提高你写代码的速度,精简你的代码量。在CSS里面有不少可以缩写的属性,包括margin,padding,border,font,background和颜色值等,如果您学会了代码缩写,原本这样的代码:

CSS

li{ font-family:Arial, Helvetica, sans-serif; font-size: 1.2em;
line-height: 1.4em; padding-top:5px; padding-bottom:10px;
padding-left:5px; }

1
2
3
4
5
6
7
8
li{
font-family:Arial, Helvetica, sans-serif;
font-size: 1.2em;
line-height: 1.4em;
padding-top:5px;
padding-bottom:10px;
padding-left:5px;
}

就可以缩写为:

JavaScript

li{ font: 1.2em/1.4em Arial, Helvetica, sans-serif; padding:5px 0 10px
5px; }

1
2
3
4
li{
font: 1.2em/1.4em Arial, Helvetica, sans-serif;
padding:5px 0 10px 5px;
}

如果您想更了解这些属性要怎么缩写,可以参考《常用CSS缩写语法总结》或者下载CSS-Shorthand-Cheat-Sheet.pdf

4. 利用CSS继承

如果页面中父元素的多个子元素使用相同的样式,那最好把他们相同的样式定义在其父元素上,让它们继承这些CSS样式。这样你可以很好的维护你的代码,并且还可以减少代码量。那么本来这样的代码:

CSS

#container li{ font-family:Georgia, serif; } #container p{
font-family:Georgia, serif; } #container h1{font-family:Georgia, serif;
}

1
2
3
#container li{ font-family:Georgia, serif; }
#container p{ font-family:Georgia, serif; }
#container h1{font-family:Georgia, serif; }

就可以简写成:

CSS

#container{ font-family:Georgia, serif; }

1
#container{ font-family:Georgia, serif; }

5. 使用多重选择器

你可以合并多个CSS选择器为一个,如果他们有共同的样式的话。这样做不但代码简洁且可为你节省时间和空间。如:

CSS

h1{ font-family:Arial, Helvetica, sans-serif; font-weight:normal; } h2{
font-family:Arial, Helvetica, sans-serif; font-weight:normal; } h3{
font-family:Arial, Helvetica, sans-serif; font-weight:normal; }

1
2
3
h1{ font-family:Arial, Helvetica, sans-serif; font-weight:normal; }
h2{ font-family:Arial, Helvetica, sans-serif; font-weight:normal; }
h3{ font-family:Arial, Helvetica, sans-serif; font-weight:normal; }

可以合并为

CSS

h1, h2, h3{ font-family:Arial, Helvetica, sans-serif;
font-weight:normal; }

1
h1, h2, h3{ font-family:Arial, Helvetica, sans-serif; font-weight:normal; }

(相关阅读:《30个最常用CSS选择器解析》)

6. 适当的代码注释

代码注释可以让别人更容易读懂你的代码,且合理的组织代码注释,可使得结构更加清晰。你可以选择做的样式表的开始添加目录:

CSS

/*———————————— 1. Reset 2. Header 3. Content 4.
SideBar 5. Footer ———————————– */

1
2
3
4
5
6
7
/*————————————
1. Reset
2. Header
3. Content
4. SideBar
5. Footer
———————————– */

如此你代码的结构就一目了然,你可以容易的查找和修改代码。

而对于代码的主内容,也应适当的加以划分,甚至在有必要的地方在对代码加以注释说明,这样也有利于团队开发:

CSS

/*** Header ***/ #header{ height:145px; position:relative; }
#header h1{ width:324px; margin:45px 0 0 20px; float:left;
height:72px;} /*** Content ***/ #content{ background:#fff;
width:650px; float:left; min-height:600px; overflow:hidden;} #content
h1{color:#F00}/* 设置字体颜色 */ #content .posts{ overflow:hidden; }
#content .recent{ margin-bottom:20px; border-bottom:1px solid #f3f3f3;
position:relative; overflow:hidden; } /*** Footer ***/ #footer{
clear:both; padding:50px 5px 0; overflow:hidden;} #footer h4{
color:#b99d7f; font-family:Arial, Helvetica, sans-serif;
font-size:1.1em; }

1
2
3
4
5
6
7
8
9
10
11
/*** Header ***/
#header{ height:145px; position:relative; }
#header h1{ width:324px; margin:45px 0 0 20px; float:left; height:72px;}
/*** Content ***/
#content{ background:#fff; width:650px; float:left; min-height:600px; overflow:hidden;}
#content h1{color:#F00}/* 设置字体颜色 */
#content .posts{ overflow:hidden; }
#content .recent{ margin-bottom:20px; border-bottom:1px solid #f3f3f3; position:relative; overflow:hidden; }
/*** Footer ***/
#footer{ clear:both; padding:50px 5px 0; overflow:hidden;}
#footer h4{ color:#b99d7f; font-family:Arial, Helvetica, sans-serif; font-size:1.1em; }

 

7. 给你的CSS代码排序

如果代码中的属性都能按照字母排序,那查找修改的时候就能更加快速:

CSS

/*** 样式属性按字母排序 ***/ div{ background-color:#3399cc;
color:#666; font:1.2em/1.4em Arial, Helvetica, sans-serif;
height:300px; margin:10px 5px; padding:5px 0 10px 5px; width:30%;
z-index:10; }

1
2
3
4
5
6
7
8
9
10
11
/*** 样式属性按字母排序 ***/
div{
background-color:#3399cc;
color:#666;
font:1.2em/1.4em Arial, Helvetica, sans-serif;
height:300px;
margin:10px 5px;
padding:5px 0 10px 5px;
width:30%;
z-index:10;
}

8. 保持CSS的可读性

书写可读的CSS将会使得更容易查找和修改样式。对于以下两种情况,哪种可读性更高,我想不言而明。

CSS

/*** 每个样式属性写一行 ***/ div{ background-color:#3399cc;
color:#666; font: 1.2em/1.4em Arial, Helvetica, sans-serif;
height:300px; margin:10px 5px; padding:5px 0 10px 5px; width:30%;
z-index:10; } /*** 所有的样式属性写在同一行 ***/ div{
background-color:#3399cc; color:#666; font: 1.2em/1.4em Arial,
Helvetica, sans-serif; height:300px; margin:10px 5px; padding:5px 0 10px
5px; width:30%; z-index:10; }

1
2
3
4
5
6
7
8
9
10
11
12
13
/*** 每个样式属性写一行 ***/
div{
background-color:#3399cc;
color:#666;
font: 1.2em/1.4em Arial, Helvetica, sans-serif;
height:300px;
margin:10px 5px;
padding:5px 0 10px 5px;
width:30%;
z-index:10;
}
/*** 所有的样式属性写在同一行 ***/
div{ background-color:#3399cc; color:#666; font: 1.2em/1.4em Arial, Helvetica, sans-serif; height:300px; margin:10px 5px; padding:5px 0 10px 5px; width:30%; z-index:10; }

当对于一些样式属性较少的选择器,我会写到一行:

CSS

/*** 选择器属性少的写在同一行 ***/ div{ background-color:#3399cc;
color:#666;}

1
2
/*** 选择器属性少的写在同一行 ***/
div{ background-color:#3399cc; color:#666;}

对于这个规则并非硬性规定,但无论您采用哪种写法,我的建议是始终保持代码一致。属性多的分行写,属性少于3个可以写一行。

9. 选择更优的样式属性值

CSS中有些属性采用不同的属性值,虽然达到的效果差不多,当性能上却存在着差异,如

区别在于border:0把border设为0px,虽然在页面上看不见,但按border默认值理解,浏览器依然对border-width/border-color进行了渲染,即已经占用了内存值。

而border:none把border设为“none”即没有,浏览器解析“none”时将不作出渲染动作,即不会消耗内存值。所以建议使用border:none;

同样的,display:none隐藏对象浏览器不作渲染,不占用内存。而visibility:hidden则会。

10. 使用代替@import

首先,@import不属于XHTML标签,也不是Web标准的一部分,它对于较早期的浏览器兼容也不高,并且对于网站的性能有某些负面的影响。具体可以参考《高性能网站设计:不要使用@import》。所以,请避免使用@import

11. 使用外部样式表

这个原则始终是一个很好的设计实践。不单可以更易于维护修改,更重要的是使用外部文件可以提高页面速度,因为CSS文件都能在浏览器中产生缓存。内置在HTML文档中的CSS则会在每次请求中随HTML文档重新下载。所以,在实际应用中,没有必要把CSS代码内置在HTML文档中:

CSS

<style type=”text/css” >     #container{ .. }     #sidebar{ .. }
</style>

1
2
3
4
<style type="text/css" >
    #container{ .. }
    #sidebar{ .. }
</style>

XHTML

<li style=”font-family:Arial, helvetica, sans-serif; color:#666; ”
>

1
<li style="font-family:Arial, helvetica, sans-serif; color:#666; " >

而是使用<link>导入外部样式表:

CSS

<link rel=”stylesheet” type=”text/css” href=”css/styles.css” />

1
<link rel="stylesheet" type="text/css" href="css/styles.css" />

12. 避免使用CSS表达式(Expression)

CSS表达式是动态设置CSS属性的强大(但危险)方法。Internet
Explorer从第5个版本开始支持CSS表达式。下面的例子中,使用CSS表达式可以实现隔一个小时切换一次背景颜色:

CSS

background-color: expression( (new Date()).getHours()%2 ? “#B8D4FF” :
“#F08A00” );

1
background-color: expression( (new Date()).getHours()%2 ? "#B8D4FF" : "#F08A00" );

如上所示,expression中使用了JavaScript表达式。CSS属性根据JavaScript表达式的计算结果来设置。

表达式的问题就在于它的计算频率要比我们想象的多。不仅仅是在页面显示和缩放时,就是在页面滚动、乃至移动鼠标时都会要重新计算一次。给CSS表达式增加一个计数器可以跟踪表达式的计算频率。在页面中随便移动鼠标都可以轻松达到10000次以上的计算量。

如果必须使用CSS表达式,一定要记住它们要计算成千上万次并且可能会对你页面的性能产生影响。所以,在非不得已,请避免使用CSS表达式。

  13. 代码压缩

当你决定把网站项目部署到网络上,那你就要考虑对CSS进行压缩,出去注释和空格,以使得网页加载得更快。压缩您的代码,可以采用一些工具,如YUI
Compressor

利用它可精简CSS代码,减少文件大小,以获得更高的加载速度。

14. 总结

在本文中,我力图更详尽的总结书写更高效的CSS代码的原则,但鉴于本人见识和精力有限,我还是希望这些原则能帮助您更好的书写和管理您的CSS代码,不知您又是如何书写CSS的,是否也有一些想要分享的技巧?给我留言吧谢谢~

 

赞 5 收藏 1
评论

图片 1

再谈Yahoo关于性能优化的N条规则

2011/07/20 · CSS,
JavaScript ·
CSS,
Javascript

本来这是个老生常谈的问题,上周自成又分享了一些性能优化的建议,我这里再做一个全面的Tips整理,谨作为查阅型的文档,不妥之处,还请指正;

一、 Yahoo的规则条例:

谨记:80%-90%的终端响应时间是花费在下载页面中的图片,样式表,脚本,flash等;

详细的解释来这里查:

也可以直接firebug上一项项比对,如下图:

图片 2

简单翻译解释下:

1、尽量减少HTTP请求个数——须权衡
合并图片(如css
sprites,内置图片使用数据)、合并CSS、JS,这一点很重要,但是要考虑合并后的文件体积。

2、使用CDN(内容分发网络)
这里可以关注CDN的三类实现:镜像、高速缓存、专线,以及智能路由器和负载均衡;

3、为文件头指定Expires或Cache-Control,使内容具有缓存性。
区分静态内容和动态内容,避免以后页面访问中不必要的HTTP请求。

4、避免空的src和href
留意具有这两个属性的标签如link,script,img,iframe等;

5、使用gzip压缩内容
Gzip压缩所有可能的文件类型以来减少文件体积

6、把CSS放到顶部
实现页面有秩序地加载,这对于拥有较多内容的页面和网速较慢的用户来说更为重要,同时,HTML规范清楚指出样式表要放包含在页面的区域内;

7、把JS放到底部
HTTP/1.1
规范建议,浏览器每个主机名的并行下载内容不超过两个,而问题在于脚本阻止了页面的平行下载,即便是主机名不相同

8、避免使用CSS表达式
页面显示和缩放,滚动、乃至移动鼠标时,CSS表达式的计算频率是我们要关注的。可以考虑一次性的表达式或者使用事件句柄来代替CSS表达式。

9、将CSS和JS放到外部文件中
我们需要权衡内置代码带来的HTTP请求减少与通过使用外部文件进行缓存带来的好处的折中点。

10、减少DNS查找次数
我们需要权衡减少 DNS查找次数和保持较高程度并行下载两者之间的关系。

11、精简CSS和JS
目的就是减少下载的文件体积,可考虑压缩工具JSMin和YUI Compressor。

12、避免跳转
为了确保“后退”按钮可以正确地使用,使用标准的
3XXHTTP状态代码;同域中注意避免反斜杠 “/” 的跳转;

跨域使用 Alias或者 mod_rewirte建立
CNAME(保存一个域名和另外一个域名之间关系的DNS记录)

13、剔除重复的JS和CSS
重复调用脚本,除了增加额外的HTTP请求外,多次运算也会浪费时间。在IE和Firefox中不管脚本是否可缓存,它们都存在重复运算JavaScript的问题。

14、配置ETags
Entity
tags(ETags)(实体标签)是web服务器和浏览器用于判断浏览器缓存中的内容和服务器中的原始内容是否匹配的一种机制(“实体”就是所说的“内
容”,包括图片、脚本、样式表等),是比last-modified
date更更加灵活的机制,单位时间内文件被修过多次,Etag可以综合Inode(文件的索引节点(inode)数),MTime(修改时间)和
Size来精准的进行判断,避开UNIX记录MTime只能精确到秒的问题。
服务器集群使用,可取后两个参数。使用ETags减少Web应用带宽和负载。

15、使AJAX可缓存
利用时间戳,更精巧的实现响应可缓存与服务器数据同步更新。

16、尽早刷新输出缓冲
尤其对于css,js文件的并行下载更有意义

17、使用GET来完成AJAX请求
当使用XMLHttpRequest时,浏览器中的POST方法是一个“两步走”的过程:首先发送文件头,然后才发送数据。在url小于2K时使用GET获取数据时更加有意义。

18、延迟加载
确定页面运行正常后,再加载脚本来实现如拖放和动画,或者是隐藏部分的内容以及折叠内容等。

19、预加载
关注下无条件加载,有条件加载和有预期的加载。

20、减少DOM元素个数
使用更适合或者在语意是更贴切的标签,要考虑大量DOM元素中循环的性能开销。

21、根据域名划分页面内容
很显然, 是最大限度地实现平行下载

22、尽量减少iframe的个数
考虑即使内容为空,加载也需要时间,会阻止页面加载,没有语意,注意iframe相对于其他DOM元素高出1-2个数量级的开销,它会在典型方式下阻塞onload事件,IE和Firefox中主页面样式表会阻塞它的下载。

23、避免404
HTTP请求时间消耗是很大的,有些站点把404错误响应页面改为“你是不是要找***”,这虽然改进了用户体验但是同样也会浪费服务器资源(如数
据库等)。最糟糕的情况是指向外部
JavaScript的链接出现问题并返回404代码。首先,这种加载会破坏并行加载;其次浏览器会把试图在返回的404响应内容中找到可能有用的部分当
作JavaScript代码来执行。

24、减少Cookie的大小

  • 去除不必要的coockie
  • 使coockie体积尽量小以减少对用户响应的影响
  • 注意在适应级别的域名上设置coockie以便使子域名不受影响
  • 设置合理的过期时间。较早地Expire时间和不要过早去清除coockie,都会改善用户的响应时间。

25、使用无cookie的域
确定对于静态内容的请求是无coockie的请求。创建一个子域名并用他来存放所有静态内容。

26、减少DOM访问

  • 缓存已经访问过的有关元素
  • 线下更新完节点之后再将它们添加到文档树中
  • 避免使用JavaScript来修改页面布局

27、开发智能事件处理程序
有时候我们会感觉到页面反应迟钝,这是因为DOM树元素中附加了过多的事件句柄并且些事件句病被频繁地触发。这就是为什么说使用event
delegation(事件代理)是一种好方法了。如果你在一个div中有10个按钮,你只需要在div上附加一次事件句柄就可以了,而不用去为每一个按
钮增加一个句柄。事件冒泡时你可以捕捉到事件并判断出是哪个事件发出的。

你同样也不用为了操作DOM树而等待onload事件的发生。你需要做的就是等待树结构中你要访问的元素出现。你也不用等待所有图像都加载完毕。

你可能会希望用DOMContentLoaded事件来代替
事件应用程序中的onAvailable方法。

28、用 代替@import
在IE中,页面底部@import和使用作用是一样的,因此最好不要使用它。

29、避免使用滤镜
完全避免使用AlphaImageLoader的最好方法就是使用PNG8格式来代替,这种格式能在IE中很好地工作。如果你确实需要使用
AlphaImageLoader,请使用下划线_filter又使之对IE7以上版本的用户无效。

30、优化图像
尝试把GIF格式转换成PNG格式,看看是否节省空间。在所有的PNG图片上运行pngcrush(或者其它PNG优化工具)

31、优化CSS Spirite
在Spirite中水平排列你的图片,垂直排列会稍稍增加文件大小;
Spirite中把颜色较近的组合在一起可以降低颜色数,理想状况是低于256色以便适用PNG8格式;

便于移动,不要在Spirite的图像中间留有较大空隙。这虽然不大会增加文件大小但对于用户代理来说它需要更少的内存来把图片解压为像素地图。
100×100的图片为1万像素,而1000×1000就是100万像素。

32、不要在HTML中缩放图像——须权衡
不要为了在HTML中设置长宽而使用比实际需要大的图片。如果你需要:

XHTML

<img width=”100″ height=”100″ src=”mycat.jpg” alt=”My Cat” />

1
<img width=”100″ height=”100″ src=”mycat.jpg” alt=”My Cat” />

那么你的图片(mycat.jpg)就应该是100×100像素而不是把一个500×500像素的图片缩小使用。这里在下文有更有趣的分析。

33、favicon.ico要小而且可缓存
favicon.ico是位于服务器根目录下的一个图片文件。它是必定存在的,因为即使你不关心它是否有用,浏览器也会对它发出请求,因此最好不要
返回一 个404 Not
Found的响应。由于是在同一台服务器上,它每被请求一次coockie就会被发送一次。这个图片文件还会影响下载顺序,例如在IE中当你在
onload中请求额外的文件时,favicon会在这些额外内容被加载前下载。

因此,为了减少favicon.ico带来的弊端,要做到:

文件尽量地小,最好小于1K

在适当的时候(也就是你不要打算再换favicon.ico的时候,因为更换新文件时不能对它进行重命名)为它设置Expires文件头。你可以很安全地
把Expires文件头设置为未来的几个月。你可以通过核对当前favicon.ico的上次编辑时间来作出判断。

Imagemagick可以帮你创建小巧的favicon。

34、保持单个内容小于25K
因为iPhone不能缓存大于25K的文件。注意这里指的是解压缩后的大小。由于单纯gizp压缩可能达不要求,因此精简文件就显得十分重要。

35、打包组件成复合文本
页面内容打包成复合文本就如同带有多附件的Email,它能够使你在一个HTTP请求中取得多个组件(切记:HTTP请求是很奢侈的)。当你使用这条规
则时,首先要确定用户代理是否支持(iPhone就不支持)。

二、Yahoo军规之外的场景?

1、 使用json作为数据的交换格式
Json在浏览器解析的效率至少高于XML一个数量级,高级浏览器中内置的有生成和解析json的方法,IE6中要用额外的方法(
),不要用eval,容易引发性能和安全问题。

2、 尽可能对images和table设定宽高值
针对Yslow的不要在HTML中缩放图像——第33条,有人会误解为不要对图片加宽高值,其实这条建议本身的意思是不要为了获取一个特定大小的图片,而去强行通过设置宽高值拉伸或者压缩一个既有的图片。建议是另存一张符合尺寸的图片替代。

对图片和table是设定宽高,是考虑到如果浏览器能立刻知道图片或者tables的宽高,它就能够直接呈现页面而不需要通过计算元素大小后重绘,而且即便是图片损毁而没有展现,也不会进而破坏了页面本来的布局。

有一些应用场景需要注意:

  • a、批量图片,图片源可控同时页面图片宽高值不可变,比如数据库有100张100*100的图片要在页面中全部展示,那么建议是都写上
XHTML

&lt;img width=”100″ height=”120″ src=”" alt=”" /&gt;

<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<tbody>
<tr class="odd">
<td><div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;">
<div class="crayon-num" data-line="crayon-5b8f6b5570624569493787-1">
1
</div>
</div></td>
<td><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;">
<div id="crayon-5b8f6b5570624569493787-1" class="crayon-line">
&lt;img width=”100″ height=”120″ src=”&quot; alt=”&quot; /&gt;
</div>
</div></td>
</tr>
</tbody>
</table>
  • b、批量图片,图片源不可控同时页面图片宽高值不可变,比如数据库有100张图片,而已知图片有的尺寸是97*100,有的100*105,而又
    不可能去一张张修改另存。这里视情况而定,根据图片尺寸与要求尺寸的偏离度,在保证图片不拉伸变形同时不影响页面布局的情况下,可以对图片单独设定宽度
    100,同时对其包裹的容器设定100*100的宽高来隐藏多出来的部分,注意不能同时设置宽高以防止变形。
  • c、批量图片,图片源不可控,页面图片宽高值不定,比如数据库有100张各种尺寸偏差较大的,此时可不对图片设置宽高;
    其他情况不一一罗列,原则是在最大程度保证图片不变形与图片最大面积展现的前提下,尽可能为图片设置宽高值,总之就是权衡。
    Tables的宽高值同图片,尽可能设置。

3、 拆离内容块
尽量用div取代tables,或者将tables打破成嵌套层次深的结构;
避免用这样的嵌套

XHTML

<table> <table> <table> … </table>
</table> </table>

1
2
3
4
5
6
7
<table>
<table>
<table>
</table>
</table>
</table>

采用下面的或者div重构:

XHTML

<table></table> <table></table>
<table></table>

1
2
3
<table></table>
<table></table>
<table></table>

4、 高效的CSS书写规则
众所周知,CSS选择符是从右向左进行匹配的。
通常一个图片列表的的小模块

XHTML

<div id=”box”> <div class=”hd”>
<h3>我的旅途</h3> </div> <div class=”bd”>
<h4>旅途1</h4> <ul id=”pics”> <li> <a
href=”#pic” title=””><img src=”” alt=”” /> </a>
<p>这是在<strong>图片1</strong></p> </li>
</ul> </div> </div>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<div id="box">
<div class="hd">
<h3>我的旅途</h3>
</div>
<div class="bd">
<h4>旅途1</h4>
<ul id="pics">
<li>
<a href="#pic" title=""><img src="" alt="" /> </a>
<p>这是在<strong>图片1</strong></p>
</li>
</ul>
</div>
</div>
1
 

JavaScript

<span class="Apple-style-span" style="font-family:
Georgia, 'Times New Roman', 'Bitstream Charter',
Times, serif; font-size: 13px; line-height: 19px; white-space:
normal;">为了代码上缩进后内层的整洁性,我们html有可能这样写之外,更喜欢看这样的css写法:</span>

1
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Georgia, &#039;Times New Roman&#039;, &#039;Bitstream Charter&#039;, Times, serif; font-size: 13px; line-height: 19px; white-space: normal;&quot;&gt;为了代码上缩进后内层的整洁性,我们html有可能这样写之外,更喜欢看这样的css写法:&lt;/span&gt;

CSS

.box{border:1px solid #ccc } .box .hd{border-bottom:1px solid #ccc }
.box .hd h3{color:#515151} .box .bd{color:#404040 } .box .bd
ul{margin-left:10px} .box .bd ul li{border-bottom:1px dashed #f1f1f1}
.box .bd ul li a{text-decoration:none} .box .bd ul li
a:hover{text-decoration:underline} .box .bd ul li a img{border:1px solid
#ccc} .box .bd ul li p{text-align:left;} .box .bd ul li p
strong{color:#ff6600}

1
2
3
4
5
6
7
8
9
10
11
.box{border:1px solid #ccc }
.box .hd{border-bottom:1px solid #ccc }
.box .hd h3{color:#515151}
.box .bd{color:#404040 }
.box .bd ul{margin-left:10px}
.box .bd ul li{border-bottom:1px dashed #f1f1f1}
.box .bd ul li a{text-decoration:none}
.box .bd ul li a:hover{text-decoration:underline}
.box .bd ul li a img{border:1px solid #ccc}
.box .bd ul li p{text-align:left;}
.box .bd ul li p strong{color:#ff6600}
1
 

JavaScript

<span class="Apple-style-span" style="font-family:
Georgia, 'Times New Roman', 'Bitstream Charter',
Times, serif; font-size: 13px; line-height: 19px; white-space:
normal;">其实写到这里,问题已经显而易见了。深达五层抑或六层的嵌套,同时右边的选择符都是采用标签,在满足我们视觉平整与代码结构系统化的时候,付出的是性能的代价。</span>

1
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Georgia, &#039;Times New Roman&#039;, &#039;Bitstream Charter&#039;, Times, serif; font-size: 13px; line-height: 19px; white-space: normal;&quot;&gt;其实写到这里,问题已经显而易见了。深达五层抑或六层的嵌套,同时右边的选择符都是采用标签,在满足我们视觉平整与代码结构系统化的时候,付出的是性能的代价。&lt;/span&gt;

不做进一步的代码书写方式的探讨,受个人习惯与应用场景影响。这里对css选择符按照开销从小到大的顺序梳理一下:

  • ID选择符 #box
  • 类选择符 .box
  • 类型选择符 div
  • 相邻兄弟选择符 h4 + #pics
  • 子选择符 #pics li
  • 后代选择符 .box a{}
  • 通配选择符 *
  • 属性选择符 [href=”#pic”]
  • 伪类和伪元素 a:hover

参考《高性能网站建设-进阶指南》,有如下建议:

  • 避免使用统配规则;
  • 不要限定ID选择符;
  • 不要限定类选择符;
  • 让规则越具体越好;
  • 避免使用后代选择符;
  • 避免使用标签-子选择符;
  • 质疑子选择符的所有用途;
  • 依靠继承;

还要注意到,即便是页面加载后,当页面被触发引起回流(reflow)的时候,低效的选择符依然会引发更高的开销,显然这对于用户是不佳的体验。

4、Javascript 的性能优化点

  • a、慎用Eval 谨记:有“eval”的代码比没有“eval”的代码要慢上 100
    倍以上。主要原因是:JavaScript
    代码在执行前会进行类似“预编译”的操作:首先会创建一个当前执行环境下的活动对象,并将那些用
    var 申明的变量设置为活动对象的属性,但是此时这些变量的赋值都是
    undefined,并将那些以 function
    定义的函数也添加为活动对象的属性,而且它们的值正是函数的定义。但是,如果你使用了“eval”,则“eval”中的代码(实际上为字符串)无法预先识
    别其上下文,无法被提前解析和优化,即无法进行预编译的操作。所以,其性能也会大幅度降低。
  • b、推荐尽量使用局部变量 JavaScript
    代码解释执行,在进入函数内部时,它会预先分析当前的变量,并将这些变量归入不同的层级(level),一般情况下:
    局部变量放入层级 1(浅),全局变量放入层级
    2(深)。如果进入“with”或“try –
    catch”代码块,则会增加新的层级,即将“with”或“catch”里的变量放入最浅层(层
    1),并将之前的层级依次加深。变量所在的层越浅,访问(读取或修改)速度越快,尤其是对于大量使用全局变量的函数里面。
  • c、字符串数组方式拼接避免在IE6下的开销
JavaScript

var tips = 'tip1'+'tip2';

<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<tbody>
<tr class="odd">
<td><div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;">
<div class="crayon-num" data-line="crayon-5b8f6b5570644959353734-1">
1
</div>
</div></td>
<td><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;">
<div id="crayon-5b8f6b5570644959353734-1" class="crayon-line">
var tips = 'tip1'+'tip2';
</div>
</div></td>
</tr>
</tbody>
</table>


这是我们拼接字符串常用的方式,但是这种方式会有一些临时变量的创建和销毁,影响性能,尤其是在IE6下,所以推荐使用如下方式拼接:  


JavaScript

var tip\_array = \[\],tips; tip\_array.push('tip1');
tip\_array.push('tip2'); tips = tip\_array.join('');

<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<tbody>
<tr class="odd">
<td><div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;">
<div class="crayon-num" data-line="crayon-5b8f6b5570647556252586-1">
1
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6b5570647556252586-2">
2
</div>
<div class="crayon-num" data-line="crayon-5b8f6b5570647556252586-3">
3
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6b5570647556252586-4">
4
</div>
</div></td>
<td><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;">
<div id="crayon-5b8f6b5570647556252586-1" class="crayon-line">
var tip_array = [],tips;
</div>
<div id="crayon-5b8f6b5570647556252586-2" class="crayon-line crayon-striped-line">
tip_array.push('tip1');
</div>
<div id="crayon-5b8f6b5570647556252586-3" class="crayon-line">
tip_array.push('tip2');
</div>
<div id="crayon-5b8f6b5570647556252586-4" class="crayon-line crayon-striped-line">
tips = tip_array.join('');
</div>
</div></td>
</tr>
</tbody>
</table>


当然,最新的浏览器(如火狐 Firefox3+,IE8+
等等)对字符串的拼接做了优化,性能略快于数组的“join”方法。
  • 以上仅列出三种常见的优化方法,仅抛砖以引玉石,更多的javascript优化点,比如避免隐式类型转换,
    缩小对象访问层级,利用变量优化字符串匹配等大家可以继续深入挖掘;


5、DOM 操作优化

首先澄清两个概念——Repaint 和 Reflow:Repaint 也叫
Redraw,它指的是一种不会影响当前 DOM
的结构和布局的一种重绘动作。如下动作会产生 Repaint 动作:

  • 不可见到可见(visibility 样式属性);
  • 颜色或图片变化(background, border-color, color 样式属性);
  • 不改变页面元素大小,形状和位置,但改变其外观的变化

Reflow 比起 Repaint 来讲就是一种更加显著的变化了。它主要发生在 DOM
树被操作的时候,任何改变 DOM 的结构和布局都会产生 Reflow。但一个元素的
Reflow 操作发生时,它的所有父元素和子元素都会放生 Reflow,最后 Reflow
必然会导致 Repaint 的产生。举例说明,如下动作会产生 Reflow 动作:

  • 浏览器窗口的变化;
  • DOM 节点的添加删除操作
  • 一些改变页面元素大小,形状和位置的操作的触发通过 Reflow 和 Repaint
    的介绍可知,每次 Reflow 比其 Repaint
    会带来更多的资源消耗,因此,我们应该尽量减少 Reflow
    的发生,或者将其转化为只会触发 Repaint 操作的代码。
JavaScript

var tipBox = document.createElement('div');
document.body.appendChild('tipBox');//reflow var tip1 =
document.createElement('div'); var tip2 =
document.createElement('div'); tipBox.appendChild(tip1);//reflow
tipBox.appendChild(tip2);//reflow

<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<tbody>
<tr class="odd">
<td><div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;">
<div class="crayon-num" data-line="crayon-5b8f6b557064b437771854-1">
1
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6b557064b437771854-2">
2
</div>
<div class="crayon-num" data-line="crayon-5b8f6b557064b437771854-3">
3
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6b557064b437771854-4">
4
</div>
<div class="crayon-num" data-line="crayon-5b8f6b557064b437771854-5">
5
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6b557064b437771854-6">
6
</div>
</div></td>
<td><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;">
<div id="crayon-5b8f6b557064b437771854-1" class="crayon-line">
var tipBox = document.createElement('div');
</div>
<div id="crayon-5b8f6b557064b437771854-2" class="crayon-line crayon-striped-line">
document.body.appendChild('tipBox');//reflow
</div>
<div id="crayon-5b8f6b557064b437771854-3" class="crayon-line">
var tip1 = document.createElement('div');
</div>
<div id="crayon-5b8f6b557064b437771854-4" class="crayon-line crayon-striped-line">
var tip2 = document.createElement('div');
</div>
<div id="crayon-5b8f6b557064b437771854-5" class="crayon-line">
tipBox.appendChild(tip1);//reflow
</div>
<div id="crayon-5b8f6b557064b437771854-6" class="crayon-line crayon-striped-line">
tipBox.appendChild(tip2);//reflow
</div>
</div></td>
</tr>
</tbody>
</table>




<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<tbody>
<tr class="odd">
<td><div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;">
<div class="crayon-num" data-line="crayon-5b8f6b557064e883862683-1">
1
</div>
</div></td>
<td><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;">
<div id="crayon-5b8f6b557064e883862683-1" class="crayon-line">
 
</div>
</div></td>
</tr>
</tbody>
</table>




JavaScript

&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family:
Georgia, &\#039;Times New Roman&\#039;, &\#039;Bitstream
Charter&\#039;, Times, serif; font-size: 13px; line-height: 19px;
white-space:
normal;&quot;&gt;如上的代码,会产生三次reflow,优化后的代码如下:&lt;/span&gt;

<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<tbody>
<tr class="odd">
<td><div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;">
<div class="crayon-num" data-line="crayon-5b8f6b5570651919483413-1">
1
</div>
</div></td>
<td><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;">
<div id="crayon-5b8f6b5570651919483413-1" class="crayon-line">
&amp;lt;span class=&amp;quot;Apple-style-span&amp;quot; style=&amp;quot;font-family: Georgia, &amp;#039;Times New Roman&amp;#039;, &amp;#039;Bitstream Charter&amp;#039;, Times, serif; font-size: 13px; line-height: 19px; white-space: normal;&amp;quot;&amp;gt;如上的代码,会产生三次reflow,优化后的代码如下:&amp;lt;/span&amp;gt;
</div>
</div></td>
</tr>
</tbody>
</table>




JavaScript

var tipBox = document.createElement('div'); tip1 =
document.createElement('div'); tip2 = document.createElement('div');
tipBox.appendChild(tip1); tipBox.appendChild(tip2);
document.body.appendChild('tipBox');//reflow

<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<tbody>
<tr class="odd">
<td><div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;">
<div class="crayon-num" data-line="crayon-5b8f6b5570654544835570-1">
1
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6b5570654544835570-2">
2
</div>
<div class="crayon-num" data-line="crayon-5b8f6b5570654544835570-3">
3
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6b5570654544835570-4">
4
</div>
<div class="crayon-num" data-line="crayon-5b8f6b5570654544835570-5">
5
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6b5570654544835570-6">
6
</div>
</div></td>
<td><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;">
<div id="crayon-5b8f6b5570654544835570-1" class="crayon-line">
var tipBox = document.createElement('div');
</div>
<div id="crayon-5b8f6b5570654544835570-2" class="crayon-line crayon-striped-line">
   tip1 = document.createElement('div');
</div>
<div id="crayon-5b8f6b5570654544835570-3" class="crayon-line">
   tip2 = document.createElement('div');
</div>
<div id="crayon-5b8f6b5570654544835570-4" class="crayon-line crayon-striped-line">
tipBox.appendChild(tip1);
</div>
<div id="crayon-5b8f6b5570654544835570-5" class="crayon-line">
tipBox.appendChild(tip2);
</div>
<div id="crayon-5b8f6b5570654544835570-6" class="crayon-line crayon-striped-line">
document.body.appendChild('tipBox');//reflow
</div>
</div></td>
</tr>
</tbody>
</table>




<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<tbody>
<tr class="odd">
<td><div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;">
<div class="crayon-num" data-line="crayon-5b8f6b5570657133822882-1">
1
</div>
</div></td>
<td><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;">
<div id="crayon-5b8f6b5570657133822882-1" class="crayon-line">
 
</div>
</div></td>
</tr>
</tbody>
</table>




JavaScript

&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family:
Georgia, &\#039;Times New Roman&\#039;, &\#039;Bitstream
Charter&\#039;, Times, serif; font-size: 13px; line-height: 19px;
white-space: normal;&quot;&gt;当然还可以利用 display
来减少reflow次数&lt;/span&gt;

<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<tbody>
<tr class="odd">
<td><div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;">
<div class="crayon-num" data-line="crayon-5b8f6b557065a869252374-1">
1
</div>
</div></td>
<td><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;">
<div id="crayon-5b8f6b557065a869252374-1" class="crayon-line">
&amp;lt;span class=&amp;quot;Apple-style-span&amp;quot; style=&amp;quot;font-family: Georgia, &amp;#039;Times New Roman&amp;#039;, &amp;#039;Bitstream Charter&amp;#039;, Times, serif; font-size: 13px; line-height: 19px; white-space: normal;&amp;quot;&amp;gt;当然还可以利用 display 来减少reflow次数&amp;lt;/span&amp;gt;
</div>
</div></td>
</tr>
</tbody>
</table>




JavaScript

var tipBox = document.getElementById('tipBox'); tipBox.style.display
= 'none';//reflow tipBox.appendChild(tip1);
tipBox.appendChild(tip2); tipBox.appendChild(tip3);
tipBox.appendChild(tip4); tipBox.appendChild(tip5);
tipBox.style.width = 120; tipBox.style.height = 60;
tipBox.style.display = 'block';//reflow

<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<tbody>
<tr class="odd">
<td><div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;">
<div class="crayon-num" data-line="crayon-5b8f6b557065d718314580-1">
1
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6b557065d718314580-2">
2
</div>
<div class="crayon-num" data-line="crayon-5b8f6b557065d718314580-3">
3
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6b557065d718314580-4">
4
</div>
<div class="crayon-num" data-line="crayon-5b8f6b557065d718314580-5">
5
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6b557065d718314580-6">
6
</div>
<div class="crayon-num" data-line="crayon-5b8f6b557065d718314580-7">
7
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6b557065d718314580-8">
8
</div>
<div class="crayon-num" data-line="crayon-5b8f6b557065d718314580-9">
9
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6b557065d718314580-10">
10
</div>
</div></td>
<td><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;">
<div id="crayon-5b8f6b557065d718314580-1" class="crayon-line">
var tipBox = document.getElementById('tipBox');
</div>
<div id="crayon-5b8f6b557065d718314580-2" class="crayon-line crayon-striped-line">
tipBox.style.display = 'none';//reflow
</div>
<div id="crayon-5b8f6b557065d718314580-3" class="crayon-line">
tipBox.appendChild(tip1);
</div>
<div id="crayon-5b8f6b557065d718314580-4" class="crayon-line crayon-striped-line">
tipBox.appendChild(tip2);
</div>
<div id="crayon-5b8f6b557065d718314580-5" class="crayon-line">
tipBox.appendChild(tip3);
</div>
<div id="crayon-5b8f6b557065d718314580-6" class="crayon-line crayon-striped-line">
tipBox.appendChild(tip4);
</div>
<div id="crayon-5b8f6b557065d718314580-7" class="crayon-line">
tipBox.appendChild(tip5);
</div>
<div id="crayon-5b8f6b557065d718314580-8" class="crayon-line crayon-striped-line">
tipBox.style.width = 120;
</div>
<div id="crayon-5b8f6b557065d718314580-9" class="crayon-line">
tipBox.style.height = 60;
</div>
<div id="crayon-5b8f6b557065d718314580-10" class="crayon-line crayon-striped-line">
tipBox.style.display = 'block';//reflow
</div>
</div></td>
</tr>
</tbody>
</table>




<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<tbody>
<tr class="odd">
<td><div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;">
<div class="crayon-num" data-line="crayon-5b8f6b5570661719166811-1">
1
</div>
</div></td>
<td><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;">
<div id="crayon-5b8f6b5570661719166811-1" class="crayon-line">
 
</div>
</div></td>
</tr>
</tbody>
</table>




JavaScript

&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family:
Georgia, &\#039;Times New Roman&\#039;, &\#039;Bitstream
Charter&\#039;, Times, serif; font-size: 13px; line-height: 19px;
white-space:
normal;&quot;&gt;DOM元素测量属性和方法也会触发reflow,如下:&lt;/span&gt;

<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<tbody>
<tr class="odd">
<td><div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;">
<div class="crayon-num" data-line="crayon-5b8f6b5570663988380983-1">
1
</div>
</div></td>
<td><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;">
<div id="crayon-5b8f6b5570663988380983-1" class="crayon-line">
&amp;lt;span class=&amp;quot;Apple-style-span&amp;quot; style=&amp;quot;font-family: Georgia, &amp;#039;Times New Roman&amp;#039;, &amp;#039;Bitstream Charter&amp;#039;, Times, serif; font-size: 13px; line-height: 19px; white-space: normal;&amp;quot;&amp;gt;DOM元素测量属性和方法也会触发reflow,如下:&amp;lt;/span&amp;gt;
</div>
</div></td>
</tr>
</tbody>
</table>




JavaScript

var tipWidth = tipBox.offsetWidth;//reflow tipScrollLeft =
tipBox.scrollLeft;//reflow display =
window.getComputedStyle(div,'').getPropertyValue('display');//reflow

<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<tbody>
<tr class="odd">
<td><div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;">
<div class="crayon-num" data-line="crayon-5b8f6b5570667700269120-1">
1
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6b5570667700269120-2">
2
</div>
<div class="crayon-num" data-line="crayon-5b8f6b5570667700269120-3">
3
</div>
</div></td>
<td><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;">
<div id="crayon-5b8f6b5570667700269120-1" class="crayon-line">
var tipWidth = tipBox.offsetWidth;//reflow
</div>
<div id="crayon-5b8f6b5570667700269120-2" class="crayon-line crayon-striped-line">
   tipScrollLeft = tipBox.scrollLeft;//reflow
</div>
<div id="crayon-5b8f6b5570667700269120-3" class="crayon-line">
   display = window.getComputedStyle(div,'').getPropertyValue('display');//reflow
</div>
</div></td>
</tr>
</tbody>
</table>




<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<tbody>
<tr class="odd">
<td><div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;">
<div class="crayon-num" data-line="crayon-5b8f6b557066a598016091-1">
1
</div>
</div></td>
<td><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;">
<div id="crayon-5b8f6b557066a598016091-1" class="crayon-line">
 
</div>
</div></td>
</tr>
</tbody>
</table>




JavaScript

&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family:
Georgia, &\#039;Times New Roman&\#039;, &\#039;Bitstream
Charter&\#039;, Times, serif; font-size: 13px; line-height: 19px;
white-space:
normal;&quot;&gt;触发reflow的属性和方法大概有这些:&lt;/span&gt;

<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<tbody>
<tr class="odd">
<td><div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;">
<div class="crayon-num" data-line="crayon-5b8f6b557066c455882724-1">
1
</div>
</div></td>
<td><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;">
<div id="crayon-5b8f6b557066c455882724-1" class="crayon-line">
&amp;lt;span class=&amp;quot;Apple-style-span&amp;quot; style=&amp;quot;font-family: Georgia, &amp;#039;Times New Roman&amp;#039;, &amp;#039;Bitstream Charter&amp;#039;, Times, serif; font-size: 13px; line-height: 19px; white-space: normal;&amp;quot;&amp;gt;触发reflow的属性和方法大概有这些:&amp;lt;/span&amp;gt;
</div>
</div></td>
</tr>
</tbody>
</table>
  • offsetLeft
  • offsetTop
  • offsetHeight
  • offsetWidth
  • scrollTop/Left/Width/Height
  • clientTop/Left/Width/Height
  • getComputedStyle()
  • currentStyle(in IE))

我们可以用临时变量将“offsetWidth”的值缓存起来,这样就不用每次访问“offsetWidth”属性。这种方式在循环里面非常适用,可以极大地提高性能。
如果有批量的样式属性需要修改,建议通过替换className的方式来降低reflow的次数,曾经有这样一个场景:有三个intput,分别对
应下面三个图片和三个内容区域,第二input选中的时候,第二图片显示,其他图片隐藏,第二块内容显示,其他内容隐藏,直接操作DOM节点的代码如下

JavaScript

var input = []; pics = []; contents = []; ……
inputFrame.onclick =function(e){ var _e,_target; _e = e ?
window.event : null; if(!_e){ return; }else{ _target = _e.srcElement
|| _e.target ; _index = getIndex(_target);//reflow两次
show(_target,_index);//reflow两次 } } function show(target,j){ for(var
i = 0,i<3;i++){ target[i].style.display = ‘none’;//reflow }
target[j].style.display = ‘block’;//reflow } function
getIndex(targer){ if(target){ …..//获取当前的元素索引 return index; }
}

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
var input = [];
  pics = [];
  contents = [];
……
inputFrame.onclick =function(e){
    var _e,_target;
    _e = e ? window.event : null;
    if(!_e){
      return;
   }else{
     _target = _e.srcElement || _e.target ;
     _index = getIndex(_target);//reflow两次
    show(_target,_index);//reflow两次
   }
 
}
function show(target,j){
for(var i = 0,i<3;i++){
target[i].style.display = ‘none’;//reflow
}
target[j].style.display = ‘block’;//reflow
}
function getIndex(targer){
    if(target){
    …..//获取当前的元素索引
    return index;
    }
}
1
 

JavaScript

<span class="Apple-style-span" style="font-family:
Georgia, 'Times New Roman', 'Bitstream Charter',
Times, serif; font-size: 13px; line-height: 19px; white-space:
normal;">如果是通过css预先定义元素的隐藏和显示,通过对父级的className进行操纵,将会把reflow的次数减少到1次</span>

1
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Georgia, &#039;Times New Roman&#039;, &#039;Bitstream Charter&#039;, Times, serif; font-size: 13px; line-height: 19px; white-space: normal;&quot;&gt;如果是通过css预先定义元素的隐藏和显示,通过对父级的className进行操纵,将会把reflow的次数减少到1次&lt;/span&gt;

CSS

.pbox .pic,.pbox content{display:none} .J_pbox_0 .pic0,.J_pbox_0
.content0{diplay:block} .J_pbox_1 .pic1,.J_pbox_1
.content1{diplay:block} .J_pbox_2 .pic2,.J_pbox_2
.content2{diplay:block}

1
2
3
4
.pbox .pic,.pbox content{display:none}
.J_pbox_0 .pic0,.J_pbox_0 .content0{diplay:block}
.J_pbox_1 .pic1,.J_pbox_1 .content1{diplay:block}
.J_pbox_2 .pic2,.J_pbox_2 .content2{diplay:block}

JavaScript

<strong style="font-family: Georgia, 'Times New
Roman', 'Bitstream Charter', Times, serif; font-size:
13px; line-height: 19px; white-space: normal;"></strong>

1
&lt;strong style=&quot;font-family: Georgia, &#039;Times New Roman&#039;, &#039;Bitstream Charter&#039;, Times, serif; font-size: 13px; line-height: 19px; white-space: normal;&quot;&gt;&lt;/strong&gt;

JavaScript

var input = [], parentBox = document.getELementById(‘J_Pbox’); ……
inputFrame.onclick =function(e){ var _e,_target; if(){ … }else{ …
parentBox.className = ‘pbox J_pbox_’+_infex;//reflow一次 } }

1
2
3
4
5
6
7
8
9
10
11
12
var input = [],
  parentBox = document.getELementById(‘J_Pbox’);
……
inputFrame.onclick =function(e){
    var _e,_target;
    if(){
     …
    }else{
     …
      parentBox.className = ‘pbox J_pbox_’+_infex;//reflow一次
    }
}

JavaScript

<strong style="font-family: Georgia, 'Times New
Roman', 'Bitstream Charter', Times, serif; font-size:
13px; line-height: 19px; white-space: normal;"> </strong>

1
&lt;strong style=&quot;font-family: Georgia, &#039;Times New Roman&#039;, &#039;Bitstream Charter&#039;, Times, serif; font-size: 13px; line-height: 19px; white-space: normal;&quot;&gt; &lt;/strong&gt;

JavaScript

<strong style="font-family: Georgia, 'Times New
Roman', 'Bitstream Charter', Times, serif; font-size:
13px; line-height: 19px; white-space: normal;"> </strong>

1
&lt;strong style=&quot;font-family: Georgia, &#039;Times New Roman&#039;, &#039;Bitstream Charter&#039;, Times, serif; font-size: 13px; line-height: 19px; white-space: normal;&quot;&gt; &lt;/strong&gt;

JavaScript

<strong style="font-family: Georgia, 'Times New
Roman', 'Bitstream Charter', Times, serif; font-size:
13px; line-height: 19px; white-space:
normal;">三、Yahoo军规再度挖掘会怎样?</strong>

1
&lt;strong style=&quot;font-family: Georgia, &#039;Times New Roman&#039;, &#039;Bitstream Charter&#039;, Times, serif; font-size: 13px; line-height: 19px; white-space: normal;&quot;&gt;三、Yahoo军规再度挖掘会怎样?&lt;/strong&gt;

在网站性能优化的路上,是不会有终点的,这也是前端工程师永不会妥协的地方。
想看到更牛P的优化建议么,请移步这里来关注李牧童鞋的分享:

  • 使用combo合并静态资源
  • Bigpipe技术合并动态数据
  • Comet:基于http的服务端推技术
  • 使用DataURI减少图片请求
  • 使用良好的JS,CSS版本管理方案
  • 尝试仅作必要的JS更新
  • 利用本地存储做缓存
  • 关于最小化HTML
  • 进一步讨论Gzip
  • 进一步讨论域名划分
  • 打开keep-alive,重用HTTP连接
  • 使用JSON进行数据交换
  • 保障页面可交互性
  • 缩短最快可交互时间
  • 异步无阻脚本下载
  • 优化内存使用,防止内存泄露
  • 高效的JavaScript
  • 第三方代码性能问题
  • Inline脚本不要与CSS穿插使用
  • 使用高效的CSS选择器
  • 进一步讨论及早Flush
  • 关于视觉和心理学

 
原文:alimama
ued

 

赞 2 收藏
评论

图片 1

前端是否应该将CSS和JS分开设置两个不同岗位

2012/03/06 · CSS,
JavaScript · 来源:
阿当    
· CSS,
Javascript

来源:阿当

这事从Franky的一则招聘说起。昨天Franky发了一则招聘前端的微博,招聘条件写得比较实在,不是那种一看就是从别的地方复制过来的那种:

招聘条件写得看似很低,所以一下子引起了很多关注,微博和QQ群里很多人在讨论。关于这则招聘,我也有些话想说。

在新浪和腾讯,前端都是分 CSS 方向和 JS
方向的。在淘宝和百度是不分的。不同的公司岗位设置不同,都有各自的道理。

图片 4

我在淘宝时觉得 CSS 和 JS 应该一个人来做,因为这两样是紧密合作的, CSS
如何设置和 JS
是关联很大的,这个分开两个人做,在对接的时候一定有很多隐患。当时我认为设置
CSS 工程师这个岗位,是因为合格的前端(既精 CSS 又精 JS
)很少,但市场需求大,所以拉了些只会 CSS 的工程师回来设一个 CSS
工程师的职位来凑数,其实是为了起一个过渡作用,等到合格的前端多起来的时候,这些
CSS
工程师岗位一定会给撤掉的。但当时我在淘宝大部分时间都在做一些毫无技术含量的专题页,一两个小时出一个页面的那种,占了我工作时间80%以上,其实对我本人来说很痛苦,没什么可提高的。

后来去了新浪,我是专职做 JS ,不用切页面的,后来我发现 CSS 和 JS
分开来其实比我想像中隐患小很得多——如果 CSS 工程师靠谱的话(事实上 CSS
工程师们也在学一些 JS
,大部分人都会借助jQuery自己完成一些功能,所以其实他们对 JS 和 CSS
如何协同工作是了解的)。我在新浪时,和 CSS
工程师配合得很好,很多问题其实事先说明一下我的思路, CSS
工程师们一点就透。我个人可以有更多的时间关注一些别的东西,以自我提升。在新浪时,无论从工作量上,还是从专注程度上,都比之前我
CSS 、 JS
全包时要好上很多。有非常多的知识是我在新浪工作期间学会的,比如ror、python和敏捷。在老东家灰头土脸迎接一个又一个专题页时,我完全不可能在短时间内学习到这么多知识点。而专门设置一个
CSS 工程师的岗位,公司招人也会容易得多,而且无论是 JS 还是 CSS
工程师,因为分开来工作,所以每个人其实都保持了一个很高的工作效率,不用不停地切换思维模式。在薪水方面,
CSS 工程师比 JS 工程师薪水普遍要低一些,事实上这个大家其实都能理解,无论
CSS 工程师们是否愿意承认, JS 的确比 CSS
门槛高,也更有供挖掘的深度。所以 CSS 工程师们也会想要转型做 JS
,往往是以 CSS 入行,再慢慢转型做 JS
。老实说,我觉得有这样一个梯度,无论对公司招聘,还是工程师们的发展,都是非常有利的。

我现在个人非常赞成将两者分开的做法。就像Franky说的“只不过我的原则就是:绝对不搞那种,招御厨的标准,费劲半年,招来一个御厨,结果让人家整天削土豆皮。虽然这个说法有点攻击重构这个工作,但是还是有那么几分道理在”。

图片 5

赞 收藏
评论

图片 1

发表评论

电子邮件地址不会被公开。 必填项已用*标注