js和css的顺序关系

1. head里的顺序如下,考虑会对请求有何影响:

a. 外部js在css前面

<script src="1.js"></script>
<link rel="stylesheet" type="text/css" href="1.css?sleep=5s">
<link rel="stylesheet" type="text/css" href="2.css?sleep=5s">

b. 外部js在css后面

<link rel="stylesheet" type="text/css" href="1.css?sleep=5s">
<link rel="stylesheet" type="text/css" href="2.css?sleep=5s">
<script src="1.js"></script>

c. 内部js在css前面

<script>
// do something
</script>
<link rel="stylesheet" type="text/css" href="1.css?sleep=5s">
<link rel="stylesheet" type="text/css" href="2.css?sleep=5s">

d. 内部js在css后面

<link rel="stylesheet" type="text/css" href="1.css?sleep=5s">
<link rel="stylesheet" type="text/css" href="2.css?sleep=5s">
<script>
// do something
</script>

e. 内联css在外联css前面

<style>
body { background:red; }
</style>
<link rel="stylesheet" type="text/css" href="1.css?sleep=5s">

f. 内联css在外联css后面

<link rel="stylesheet" type="text/css" href="1.css?sleep=5s">
<style>
body { background:red; }
</style>

结果:
a,b – head里出现外联js,无论如何放,css文件都不能和body里的请求并行。补充:body里dom渲染取决于head里的js执行完。 (图1)
c – head里的内联js只要在所有外联css前面,css文件可以和body里的请求并行(图2)
d – head里的内联js只要在任一外联css后面,css文件就不能和body里的请求并行。补充:原因也是要等js执行完(图1)
e – firefox/ie下,要等1.css加载完生效。safari/chrome下,则先生效,再加载1.css
f – 等1.css加载完生效

2. 内联js要等它前面的所有外联css文件加载完后执行。之前写过一篇子资源原理的笔记

<link rel="stylesheet" type="text/css" href="1.css?sleep=5s">
<script>
s_time = +new Date;  // 5s后才执行,所以在这里记录开始时间是不准确的。
</script>

3. 外联js放在页面最后,高级浏览器会自动做优化。如:

<head>
<link rel="stylesheet" type="text/css" href="1.css?sleep=5s">
<link rel="stylesheet" type="text/css" href="2.css?sleep=5s">
</head>
<body>
<img src="1.png">
<img src="2.png">
<img src="3.png">
<script src="1.js"></script>
</body>

firefox/chrome/safari加载的优化处理相似。见图3。

4. 内联长执行时间js,无论放在页面任何位置,都会影响整个页面的渲染。测试文件,如:

<body>
<img src="1.png">
<img src="2.png">
<img src="3.png">
 
<button id="bn">button</button>
<script type="text/javascript">
  document.getElementById('bn').onclick = function() {
    alert(1);
  }
  // 正常渲染时间
  document.body.appendChild(document.createTextNode(+new Date - s_time + 'ms'));
</script>
 
<script>
// 执行5s。重新打开页面(不是刷新),整个页面空白5s。
// 前面的dom结构正常渲染,但不显示,等5s后全部显示出来。
</script>
</body>

在页面初始执行阶段如果有长执行时间的内联js,对性能的影响是非常非常严重的!但是,如果把那段执行5s的js放到外部就不会有上述影响,或者移到domreay/onload后执行也可以。

依据上述结论组织页面中的css和js才会更合理。

感谢玉伯的这篇很好做了解释也指出一些问题: http://lifesinger.wordpress.com/2012/02/03/performance-impact-of-js-css-loading-order/

顺流而下, 把梦做完 …… 2011

2011最后一个changeset调了一些无聊的样式,收官不够华丽。

总结一下自己一年做过的事:

FM神秘实验项目 – 很好玩,因为是技术驱动的,我们尝试了node.js。当然少不了各种html5,css3技术混搭。背后还有牛逼的算法。node.js今年很火,yahoo!新一代应用开发平台就是用node.js。它的优势是处理高并发的微请求,这个项目里复杂的运算和数据存储都调service。到底效果怎么样上线后再看吧。

FM WebApp – 我决对是WebApp的拥趸者。但Android 2.2/2.3内置的Webkit就是渣,跟ie6一样招人恨。还好手机的换代更快,我觉得从iOS 5和Android 4开始WebApp的时代要来了。明年打算换个phone7,我喜欢反苹果美学的东西。

首页改版 - 2011年突然流行起“砖块布局”(YY的叫法)像花瓣之类的网站。但新的豆瓣猜布局将是正经的magazine-style布局,是溶合了前后端技术加设计的高级货。

今年还做了团购(已下线)、二手和部落 – 这些项目技术上平淡无奇,贵在开发方式上。比如做部落的过程高度同步,PRD出来后就着手开发,几天整个流程就跑通了,后面等设计出来后再改样式。这种完美时刻,就像比赛中偶尔出现的美妙配合一样。这里面也积累了一些代码组织上的经验。代码组织的三层:业务逻辑代码、通用功能代码,基本架构(类MVC式分层,model是ajax数据交互、controller注册事件、view是javascript template。注意不是single page app那种MVC)。

推荐改版事件 - 细节跳过(…惹了不小的麻烦)。这件事的经验是不要试图实现一个复杂和看似完美的方案,里面可能隐患重重。有时朴实无华是最合适的。像这种通用程度极高的组件,对复用、性能、响应速度都有很高的要求,用户使用上也极敏感。达芬奇说过”简单是极端的复杂“。

上半年主要做了新版FM。它是最适合实践响应性开发的项目,做的不好。明年接着来。国内的设计师对响应性设计无感。这篇文章反映了国外设计的主流思想,基本都在谈响应性设计:A Year in Web Design: How the Experts Saw 2011

在这些产品开发实践中愈加感触:过细过明确的分工会限制单位创造力的发挥,协调成本也高,从而拖缓产品发展,更甭提创新了。各个角色的人(PM、Designer、Engineer)应当通过扩展技能来弥补之间的代沟。也就是Designer应该有产品意识和工程开发意识、Engineer也应该有基本美感,同时,前后端工程师之间应当技术互补。前端问题并不一定用前端技术解决。典型就是静态文件管理,它对前端开发的帮助很大。没它前端代码重构和拆分基本寸步难行。但目前还是简陋。前端开发需要有一套完整的工具体系,闲来整出一张图,后面会谋求更多人支持。总之这是一件任重道远的事,我也有心理准备。

开发要追求高度的模块化,但是在普遍情况下,模块的依赖关系要简单、偏平。也许在很独立的应用或框架内部模块的依赖关系可能会复杂,但纯属个案。因此,前端文件按需加载的粒度不应太小,而在开发环境中维护的应该是粒度更小的模块。因此,后端的预处理和前端的异步按需加载混用是最合理的方案。我对Do也有了新想法,打算2012年重写一下。

今年参加的三个会和所做的分享:
淘宝的技术嘉年华 (slides)
webrebuild年会 (slides)
tencent北京CDC火山囗 (slides)

承办了一次web标准化交流会。这是目前北京坚持下来时间最长的民间前端技术沙龙。

今年还在知乎上比较认真的回答问题:zhihu.com/people/kejun

8月一个人跑到HK看Red Hot Chili Peppers的现场。所有好的东西都充满某种力量,甚至一行代码也是如此。今年还幸运的看了eels、black rebel motor club、envy的现场。稍稍有点后悔没看Bob Dylan,但我更爱Leonard Cohen,这个老家伙据说2012年出新专辑。顶马的十年和声音碎片的十年专场印象也颇深,对于上了岁数的人来说,有点时间厚度的东西就带感。声音碎片的一句歌词特别好:“顺流而下,把梦做完”。

新年快乐!

近期面试感受

这两天大概面了5、6位应届的同学,最后往往忍不住聊的多了些,有点开复老师的感觉了。归纳下来有几个突出的问题。

1. 在公司实习学不到技术,学到的只是做事的方式
这些做事的方式(或者说技巧)有些是必要的,比如沟通方面。但更多是没有价值的,比如大公司繁琐的流程,各种毫无道理的开发规范,拖沓的做事风格等等。对于技术人员来说技巧性的东西千万不能太重。一个技术团队如果让实习生学不到专业上的东西,可以质疑其专业性了。应届生在学校,在公司如果都接触不到最专业的技术,那么他们又怎么能成长起来呢。一个恶性循环的开始。前端开发岗位的需求这么大,但始终缺少专业人才的一个根本原因吧。

2. 用的不是技术,更多是技巧
由于在学校里没有系统的前端开发课程,导致对html/css/javascript基本概念的理解非常薄弱。大部分人的学习方式是:先看书,然后觉得书和实践离得很远就直接实践,遇到问题就去网上搜,而搜到的基本都是“技巧”性的东西。或者是跟着学校里的“牛人”学,掺着各种好的、坏的经验全盘接受。比如实现一个左图右内容的显示效果,写出html和css(见下图)。这是我的一道笔试题,看起来很简单吧。但是还没有人答出最佳答案。如果去网上看,国内那些大网站们是怎么实现的,就不能怪他们了。

笔试题1

a方案 – 百度新闻首页:

<table>
 <tr>
  <td valign="top" class="imgtd">
   <a ...><img ...></a>
 </td>
 <td valign="top">...</td>
 </tr>
</table>

html结构丑陋,但css简单。

b方案 – 新浪微博首页:

<div class="twit_item MIB_linedot2">
  <div class="twit_item_pic">
    <a href="" target="_blank">
      <img src="" ...>
    </a>
  </div>
  <div class="twit_item_content">
   ....
  </div>
</div>

css实现:

.twit_list dd .twit_item_pic{float:left;width:66px;padding-top:2px;}
.twit_list dd .twit_item_content{float:left;width:316px;color:#666;line-height:18px;}

大部分应试者都是这个答案。用了浮动就必须定宽,结构就失去灵活性,同时必须解决浮动带来的一系列问题。

c方案 – 网易首页:

<div class="imgText-temp-1 dotline clearfix">
	<div class="mod-img main-img">
		<a href=""><img src="" ...></a>
	</div>
	<ul class="mod-list main-list">
	<li>...</li>
	<li>...</li>
	<li>...</li>
	<li>...</li>
	</ul>
</div>

css实现:

.imgText-temp-1 { overflow:hidden;padding-left:132px;margin-bottom:3px; }
.imgText-temp-1 .main-img { position:absolute;_display:inline;margin-left:-132px; }

作者意识到float的问题,他用了一个技巧:在容器左侧挤出一个132px的空白,再让.main-img定位为absolute,再向左移132px。
此方案典型的技巧性太重,不是应用技术解决问题,这是不应该提倡的。

这些写法都是欠缺对css基本概念的理解。如果理解block formatting context(块级格式化上下文)的概念, 就不会这么写了。触发了BFC的块级元素,它的边缘不会和float box重叠。所以正解是:

<div class="item">
  <div class="pic">...</div>
  <div class="content">...</div>
</div>

css实现:

.item .pic { float:left;margin-right:10px; }
.item .content { overflow:hidden;zoom:1; } /* 或用display:table-cell */

demo: http://hikejun.com/demo/css/demo_list.html

笔试有几年经验的人也是鲜有答对的。在新技术风起云涌的今天,太忽略基础的东西了。

3. “搜索”式学习害人不浅
面试中有同学觉得书上写的东西不实用,更喜欢边实践边学。但往往实践中主要解决具体问题,比如要实现上面那个例子,从网上搜到一个不好的例子,自己又不足以区分好坏。然后,就把它当成一个解决问题的模式,如果没人纠正,可能几年下来都这么用。网上的资源非常丰富,要区分“技术”和“技巧”。还是那句话,对技术人员来说技巧性的东西不应该太重。

4. 热衷新技术
古人讲究温故而知新还是很有道理的。学习新技术可以给自我镀金,欠缺基础的东西就会内力不足,这样在应用的过程中就会有问题。

5. 学到“二手货”
国内前端技术社区的分享质量总体还是不高。那些照搬国外,加上自己片面认识的资源就是“二手货”。这些资源在看的时候要慧眼识珠啊。最好还是直接看第一手资料。

6. 光看不用,坐等机会
很多同学表示正在看什么什么,或正准备学什么什么。但就是没动手写过,总是希望在实习公司有实践机会。这样的机会可能永远也没有呢,完善自我的技能,是需要自己给自己创造机会,写一些demo,搞一些个人项目,参加一些技术交流,持续关注该技术的发展……坐等只能浪费时间。

D2技术嘉年华分享:前端基础架构的实践和思考

这个话题是我一直以来思考的问题。其实4年前我在淘宝分享过一个基于ant的静态文件编译系统,但那时候对基础架构的全局还没有一个总体思路,现在看来它没有充分用在开发中,不是它本身做的不够好,而是因为它没有完全植入到整个技术体系中,只是一个单纯的工具,这样它发挥的作用始终是有限的。2年前我才真正意识到前端基础架构的意义,它是把技术更好的吸收、组合、应用出来的基础,也是一个足够专业的前端团队高效运转的基础。

我一直以来在追求前端团队职能价值的最大化。那么首先回顾一下前端职能经历了什么样的转变。我相信这些转变不需要过多解释,大家都能理解。但是又有多少团队真正转变过来了。职能和价值更多还是停留在页面是否高效的实现上。

区别只是人多了,分工过细,人被局限在一条流水线的各个环节上,被当成工具使用,没有发挥余地,也没有成长空间。前端工程师实际上沦为苦逼的‘码农’。所以需要一个更好的体制和环境把前端开发的职能作用充分发挥出来,创造更大的价值。同时,对于想上市或想创造奇迹的互联网公司们需要的也不是一两个技术牛人,而是一个更加专业的团队

首先角色定位必须清晰。前端工程师比设计师更懂得界面和交互的实现原理,所以要能弥补设计师或产品经理在技术理解上的不足,这是中国特色。开发的工程特点上跟后端开发非常接近,所以不能脱离整个技术体系,要尽量减少中间环节,共用开发环境,共用系统。前端开发在设计部门是过去时,现在更适合在技术部门。2是打造专业团队,这种专业性不是一两个牛人带来的,而是体制和长时间的技术积淀带来的。3也是通过深厚的技术基础和敏捷的开发方式带动团队高效运转,而不是通过行政管理手段。这个技术基础就是一个不断完善的向前演变的技术平台。最后是结果,带来技术上的持续创新。

今天要谈论的“前端基础架构”就是这个技术平台中的重要内容。什么是 “前端基础架构”?它应当具有这些特点和作用。要先做技术的布局,才能从大格局出发指导用什么和怎么用技术。细节可以先不够好,但整体要有,要能发挥作用。所有人不是机械的完成项目开发需求,而是创造性的应用技术,并且做好技术回收,有意识的积累下来。3是它有团结的作用,内聚所有人的智慧,调剂技术的活跃度,探索新领域。4是从体制上做到技术的大融合,让前后端开发无缝结合在一起。

总结我之前的经验教训,用这个故事可以很好的说明。不是片面做一个局部或放大局部的作用,比如做好一个工具或一个代码库,它的作用都是有限的。而要从大格局出发。所以,我整理了一张图。

这张图从下向上看,它就像一颗树,不断滋生枝干。基础架构的建设正是如些,也是一个不断生长的过程。其中主要的结点构成前端技术的大格局。最下面的是它的根结点,后面会逐一分解。

去年我在另一个活动上分享过同样的话题,不过那时候只做了2成,一年过去了,现在可以说做到4成。它就像一颗种子,需要所有工程师智慧的培育,才能长成大树。

工具、规范和系统看起来是独立的三大块,但它们之间是相互作用,紧密联系的。工具是为落实规范、保证品质定制的,系统又把工具有效的串联起来,建立一套有秩序的开发环境。mission是为了打造高品质的产品使用体验。工具体系由这些部分组成。代码管理是为了代码的模块化组织、提高重用、化繁为简的预处理,从而达到更高的可维护性和灵活性。品质检验的目的是保证代码符合我们约定的统一的代码Guidelines的要求。测试是为了避免异常,规避风险。上线后的运行监测是为了运营过程中的服务品质的持续性。这块是我们正准备做的。

我们在服务器端对无论是内联还是外联的js和css代码进行模块化的组织。使用这种@import的编译语法,在开发环境中看起来是这样的。上线后会将编译后的文件再部署到CDN

css文件除了支持@import编译语法外,还会支持SCSS语法,并且引入Compass的CSS3 Mixin Library,简化开发,使CSS开发更像语言那样去组织,提高开发效率。除此以外,我们还会进一步引入OOCSS概念,称之为Douban-UI,它是对通用信息元素进行对象化的抽象,建立的一套基本样式库。

库和框架是工具中的重要分支。它的根本目的是为了代码资源的重复利用。从格局出发拥抱开源技术,从项目开发中回收技术,结合自主开发弥补空白。除了建立丰富的通用功能库外,同样会重视应用架构的设计,比如应用框架这个分支包括模板系统、前端MVC框架等。在移动开发方面,因为其性能敏感等特殊性,我们会组成更合理的方案,比如用Zepto代替jQuery。在桌面开发上,有洪强宁(豆瓣的首席构架师)开发的onering,它是基于webkit,支持html5的桌面应用开发框架

规范仍然是最最基础的。规范应当具备可操作性,同时要有配套的检验工具。测试部门帮我们在CI中集成了Douban-JSLint,这是根据我们的规范要求定制后的JSLint,同时,我们也会把它植入到开发环境中,很方便的自检。技术文档的积累也是不能忽略的,它是重要的学习资源,结合培训,帮助新同学尽快溶入到团队中。同时,我们也欢迎后端工程师写前端代码,正如我们也会涉足后端一样。这种技能上的重叠,会让协作更默契。我们也正在努力通过规范和工具降低门槛、扫除障碍

我们有三种开发环境,前后端在同一环境下协作开发,尽量减少中间环节。开发前,参与的前后端工程师一起制订一份开发文档,内容主要是URL和对应模板的规划,Ajax的接囗的说明等等。然后,前端部分直接开发出最终的模板和实现交互,用假数据摸拟输出,不好实现的接囗会利用诸如Charles此类工具映射到本地的数据文件上。前后端开发是非常平行的。在项目管理上,也尽量用工具辅助,避免囗头提需求,而是以Ticket的形式启动后面的开发流程,这个过程是简捷而默契的

开发流程追求的是敏捷高效。为了保证最终产品的品质,该有的环节还是不能缺的。所以好的流程是将工具、系统和各种子系统完美的串起来,自动化程度高,同时又操作性强。

正好昨天有人在知乎上邀请我回答一个问题。可见团队大了,技术应用复杂了,要提升它的职能作用,建设前端基础技术架构,是一件非常有意义的事情。

slides: http://www.slideshare.net/kejun/ss-9413262

前端开发理论热点面对面:从怎么看,到怎么做?

View more presentations from kejun

常言道:温故而知新。当对新技术趋之若鹜时,重温一下前端开发中的一些非常基础的理论,对应该“怎么做”,思路会更加清晰。

本来这是对内部实习生的一次培训。也许很多人会期待听到jQuery, Do, CSS3, HTML5神马的,都没有出现。回归最根本,这是一次反思的过程,只有充分理解这些基础理论,才知道“怎么做”,才能做对。你没觉得现在充满了对各种技术偏激的追求,对国外技术盲目的跟随,却忽视这些技术的根本和由来。

聊聊响应性设计和开发

非常有幸受Franky之邀参加北京腾讯CDC“火山囗”活动。第一次同时面对100多设计师谈一些或许设计师会认为跟自己无关的技术话题,虽然我认为这个话题至少50%是设计相关的,感谢他们耐心的听完了。

响应性设计(Responsive UI),这是一个关于新时期设计策略的话题。幻灯里解释了它,我不想再赘述。

这是一个有意义的话题,主要解决跨设备跨平台布署产品的问题。从PC到各种移动设备,各个终端上的产品形态是在一个统一规划的设计策略下管理的。真正的大手笔啊,想想就令人兴奋。

简要列下我认为响应性设计和开发中的要素(具体要到幻灯里看):
1. 兼顾移动设计
2. 模块化设计和开发
3. 浏览器分级支持
4. 自适应布局
5. 资源响应性优化
6. 性能敏感

应用响应性设计不仅仅是变变布局,而是应该把各种设备的不同特点发挥在产品设计中,这里面包含了各种响应性问题。要做到兼顾各种设备是对设计师极大的挑战。而对于工程师来说,要考虑各种技术方案、fallback支持或是降级处理的综合性方案,最终形成一个响应性UI框架把开发的成本降下来,同样是极大的挑战。

这东西现在看起来是一个大公司不想玩、小公司玩不起的事。要实现这个大“阴谋”,需要设计和技术的通力配合。但一般大公司角色分工过于明确,都是各想各的事,不愿意尝试不确定的事,因此通常用人海战术分别解决问题而不是统一解决问题。于是,会有ipad.xx.xx, touch.xx.xx, wap.xx.xx… 这看起来很蠢。当后期维护成本大到无法承受,或看到别人做到时,我想最终会回到这个路子上。

JS文件加载失败处理

浏览器的文件加载实际上是有非常纠结的兼容问题的。最近看到@lifesinger做了一个具体的总结。这里比较麻烦的是IE6~8不区分加载成功或失败,都走一个回调。在网上看了一种解决方案是,在加载文件的最后置一个全局变量或改变标签的属性来区分,这样成功与否就通过这个标志位判断。但显然不太完美,还要改加载文件。

后来尝试另一种思路,先创建一个vbscript,src置成一个JS文件,如这个文件加载正常,肯定会报错否则不会有反应。这样如果window.onerror捕获到错误了,说明文件有效,再正常加载。如果没捕获到,n秒后会触发一个超时。

这部分代码:

      if(ie && ie < 9) {
        vbs = doc.createElement('script');
        vbs.language = 'vbscript';
        vbs.src = file;
       saveErrorHandle = win.onerror;
       win.onerror = function() {
         load();
         win.onerror = saveErrorHandle;
         return true;
       };
       setTimeout(function(){
         ref.parentNode.insertBefore(vbs, ref);
       }, 0);
     } else {
       load();
     }

DEMO: http://hikejun.com/demo/demo_js_errorback.html

更好的用vim浏览Javascript代码

vim默认没有一般IDE的outline视图,浏览长篇Javascript源文件很麻烦,taglist插件正是弥补这点不足。它可以将所有方法和变量分级罗列出来,一目了然。taglist是依赖强大的ctags实现的。ctags支持41种编程语言,其中包括Javascript,但对Javascript支持较随意。

ctags + taglist的安装过程:
1. 下载exuberant ctags
2. 安装exuberant ctags:
> ./configure
> make
> sudo make install
3. 安装taglist
4. 让taglist针对javascript显示更多信息。新建$HOME/.ctags文件,添加:
感谢@KDepp补充: windows用户要注意,放在$HOME/ctags.cnf中。

--regex-JavaScript=/([A-Za-z0-9._$]+)[ t]*[:=][ t]*new[ t]+Object(/1/o,object/
--regex-JavaScript=/([A-Za-z0-9._$]+)[ t]*[:=][ t]*{/1/o,object/
--regex-JavaScript=/([A-Za-z0-9._$()]+)[ t]*[:=][ t]*function[ t]*(/1/f,function/
--regex-JavaScript=/function[ t]+([A-Za-z0-9._$]+)[ t]*([^])]*)/1/f,function/
--regex-JavaScript=/([A-Za-z0-9._$]+)[ t]*[:=][ t]*new[ t]+Array(/1/a,array/
--regex-JavaScript=/([A-Za-z0-9._$]+)[ t]*[:=][ t]*[/1/a,array/
--regex-JavaScript=/([^= ]+)[ t]*=[ t]*[^""]'[^'']*/1/s,string/
--regex-JavaScript=/([^= ]+)[ t]*=[ t]*[^'']"[^""]*/1/s,string/

5. 在.vimrc添加:

let Tlist_JS_Settings = 'javascript;s:string;a:array;o:object;f:function'
let Tlist_Ctags_Cmd = '/usr/local/bin/ctags'

6. 打开一个js,执行:Tlist。

遇到问题可参考下面链接:

http://vim-taglist.sourceforge.net/faq.html

http://easwy.com/blog/archives/exuberant-ctags-chinese-manual/

jsctags是专门针对javascript做的,目的就是提供比ctags更好的索引结果。它完全是用javascript写的,基于node.js和narcissus。现在这个项目已改名为DoctorJS

下面这两个插件都是利用DoctorJS对javascript文件做处理的:
1. Taglist-Plus
2. Tagbar。另一篇介绍Tagbar的文章:http://is.gd/tKfuTe

在编辑.html文件里的javascript,taglist找不到任何标签。只好先:set ft=php,再用Tagbar。

探讨前端代码Review

产品发展越快,对代码的管理也就需要越严格。通常代码在进入QA测试环节前就要进行代码review。review的目的倒不是为了发现bug,主要是为了避免代码设计上的缺陷和保证代码的可维护性。当然还有针对性的review比如安全性、性能、易用性等等。代码review除了可以提高代码的品质外,还能加强团队的协作精神,以及提高团队的整体技术能力。显然这是一件非常有意义的事。

前端代码更需要review。对于本身就不严谨的前端开发语言(html/css/javascript)来说,规范性尤为重要。常常因为各种原因凑合,最后注定要花费更大的代价挽救。也许做好这件事最大的阻碍是时间,活都干不完,哪有时间review。大家对review如果有消极或抵触情绪,review的意义会大打折扣。实际情况如果不能保证上线前所有代码都经过review,即便强制通过工具做到,也会流于形式,反倒丧失原本的意义。

重新调整前端代码review的目的:
1. 落实规范。代码风格的一致性是保证代码可维护性的基础。为此针对代码风格会出台一系列Guidelines,人review和机器review(如jslint等工具)结合是落实规范的有力保证。在制订这些规范时,要考虑它在这方面的操作性。参考http://bit.ly/douban-css, http://bit.ly/douban-javascript

2. 教育意义。review的过程也是相互学习的过程。大到使用某种新技术,小到一行代码的写法,从中都可以学到东西。从这个方面来说,即便上线前没时间review,上线后能够总结收获和经验,对其他人起到某种教育意义这样的review也是很有价值的。

3. 荣誉感。对于工程师来说,这是比奖金更强的动力。众目睽睽下一段丑陋的代码被别人指出来是多么尴尬的事情。同时,要为一周一次的代码review准备足够的可讨论的changeset。世界上没有甘愿平庸的工程师。

4. 发现问题和积累成果。如果没有代码review,在每周的周会上也可以讨论这些问题。但泛泛而谈远没有看着具体代码来的真切。所以我们废除周会改成周期性的代码review。

5. 促进团队协作。周期性的代码评审会也是某种意义的交流会,大家可以了解彼此在做的事情,哪些可以解决自己的问题,或是我做的正好可以帮到别人。review的内容不局限于产品代码,也可以是一个跟具体产品无关的基础类库。

当然,也可以利用工具,对上线前代码做强制审核,未通过的不能上线。但这样容易流于形式。我还是觉得面对面的review更好。

做好代码review需要注意的问题:
1. 规模。人数5、6人为佳,人太多,时间拖得太长,越到后面效果越差。

2. 时间。最多不超过1个半小时,最好控制在1个小时内。

3. 代码量。400〜600行代码之间。越多发现的问题就会越少。

4. 形式。提前将要review的代码链接、changeset链接准备好。找个会议室,集体看投影,或带上各自电脑。每个人轮流讲自己的部分。放点音乐活跃一下气氛也不错 ;)

5. 简要介绍应用场景。更多还是针对代码本身,诸如为什么做这些改动,删掉原来的代码解决什么问题,代码写法上有什么问题,用到哪些技巧性的东西等等。介绍完之后,留出一定提问的时间。
参考了:http://www.ibm.com/developerworks/rational/library/11-proven-practices-for-peer-review

前端代码review我们也是在不断的尝试中。向后端工程师借鉴经验。重要是明确它的目的,不让它流于形式,真正起到积极的作用。

过去的一年

自省一下过去的一年。过去的一年里一直想证明什么,证明自己的能力,证明自己的想法,证明自己的判断,证明自己的选择,证明自己所做事情的意义,就在过去的一年即将过去的时候才意识到试图证明什么是多么愚蠢。

同时也意识到辩解是最没意义的事。外面的人看结果,里面的人看过程。追求结果的关键是转换成简单的行动,让过程尽可能顺利。而在过程中是没有共识的。出发点、角度、意愿都不一样,试图说说就能达成共识是不可能的。这时沟通反到会被当成无能的辩解。自由、平等、信任是建立在某种条件上的东西。只有结果才是消除分歧和获得信任的砝码。过去的一年问题不少,无须辩解。

过去的一年:看了13场演出,听了约60张专辑,参与了约10场技术交流,去了3个城市,看了3本书,健身约104小时,发了1152条tweet,flickr又多了326张照片,写了11篇blog,提交了610个changeset,写了约8113行代码。

下面的部分我承认是写给看到的同事和同行的。过去一年里团队做了很多了不起的事。达成的结果还可以,但我更关心过程,过去一年,前端从明确适应产品发展的重构路线,到对旧体系的关键问题改造,到建立建全基础类库、框架、规范及各种解决方案,再到与产品开发更好结合的开发方式,都取得了不同程度的进展和成果,整体格局显现出来,只是做的还不够充分。整个团队的能力在过去的一年里提升显著。我对自己的定位是做好这个团队的“教练”,不断更新战术和打法,给每一个人创造条件提升水平和施展特长,同时做好引进“球员”的工作。新的一年将大有可为。

新的一年据说是金牛座人转运的一年,走着瞧吧。看好2011年!