SlideShare a Scribd company logo
TBAD F2E 2010 & Velocity China & D2 Review  淘宝广告事业部 李牧 2010-12-20
overview JavaScript Ninja 出品的代码和启示 Facebook QuicklingPageCache Vs. Ajaxxx There and Back Again : HTC(HTML Component) Facebook BigPipe++ : Streaming Anywhere 客户端无阻滞:第三方广告代码的实践 服务端无阻滞:CommonJSNodeJSCFO体系Web死后jser的未来 JavaScript包管理+模块化 : YUI3 & Kissy Vs. KissyLite Google Clousure Compiler 启示 : KissyLite预编译时间窗口优化性能 Jscex 和kslite对异步编码的简化
JavaScript  Ninja 出品的代码和启示 Topic 1:
DomReady Firefox Chrome Safari Opera: DOMContentLoaded IE: doScrollor	script defer onreadystatechangefor iframe
<script> onload Dom载入的JS文件载入完成且执行完成的事件 IE Opera: onreadyStateChange Firefox Chrome Safari Opera: onload
insertAdjacentHTML IE Chrome Safari Opera: insertAdjacentHTML Firefox: HTMLElement.prototype.insertAdjacentElement= function(where, parsedNode) {	}; HTMLElement.prototype.insertAdjacentHTML= function(where, htmlStr) {	};
iframedJS 父页面升级document.domain,IE下IframedJS解决方案: <iframe id= src= "javascript:void(( function(){var d=document;d.open(); d.domain='a.com';d.write('');d.close()})())" ></iframe> BugFix@CKEditor
DOMNodeInserted Firefox Chrome Safari Opera: DOMNodeInserted IE6,7: CSS Expression  IE8std:  	Override :  innerHTML,appendChild… 屈超:Bookmarklet型(云端)应用的前端架构@D2
Tag Customed Firefox Chrome Safari Opera IE9: 直接使用 IE6,7,8: document.createElement("tagName") 屈超:Bookmarklet型(云端)应用的前端架构@D2
Range : insertNode Firefox Chrome Safari Opera: insertNode IE: 圆心的实现 http://www.planabc.net/2010/11/26/range_insertnode/
Ninja 的代码和启示 不同浏览器,使用不同途径实现相同功能. 对JavaScript或Dom的功能进行补强. 解决实际开发中遇到的重大困扰! 	--了解更多的浏览器特性,包括那些某种浏览器独特的特性以拓展解决问题思路,因为特性都是为解决实际问题而加入的.
Facebook QuicklingPageCacheVs. Ajaxxx Topic 2:
网站性能优化的目的 运行流畅加载迅速
Ajaxxx 架构来自于系统特点. 1.页面不多,<100个 2.多数页面重复,由组件搭建 3.页面有数据的区块不多 4.不需要SEO
Ajaxxx 加载迅速 1.所有静态资源在CDN上 2.通过Ajax只加载需要的数据 3.没有任何静态资源加载2次以上 展现流畅 1.没有load,unload消耗 2.没有重复渲染 3.基于事件绑定的组件框架
同类的 Facebook Quickling
QuicklingvsAjaxxx Link Controller – FB使用事件代理,我们使用的是原生的link HistoryManager -- 基本一致 Bootloader -- 我们有面向开发环境的优化 Busy Indicator CSS Unloading Resetting timer functions Permanent link
内存问题 Facebook 会在10个页面之后强制刷新 我们不能这样做,因为IE6强制刷新丢失存在于iframe的历史 我们解决问题的两个方向 1.将历史存入cookie或其他本地存储模式,强制刷新能够恢复历史,配合页面间内存泄露预防 	2.减少YUI3依赖,解决页面内内存泄露问题
PageCache
PageCache启示 我们动态数据及时性要求高,动态数据少,所以不缓存动态数据. Facebook缓存动态数据遇到的非常棘手问题我们都没有. Incremental updates In-page writes 	Cross-page writes 如果我们系统预知到了这些问题,我们不会这样架构. 但从Facebook,我们看到的是解决问题的智慧,勇气和信心!
同类的 New Twitter MUSTACHE模板系统支持NodeJS
Ajaxxx 2011 优化内存使用 更换模板系统为MUSTACHE 使用NodeJS,让页面可以在服务端生成 页面组件更加HTC
There AND BACK Again : HTC (HTML Component) Topic 3:
浏览器内置组件的构成 原生的select组件 我们开发的select组件 按照浏览器构建内置组件的方式构建自定义组件
Microsoft HTC Introduced in Microsoft® Internet Explorer 5, HTML Components (HTCs) provide a mechanism to implement components in script as Dynamic HTML (DHTML) behaviors.
HTC基本架构 为自定义组件开发,各自的属性,事件和方法. 容器:通过样式中的behavior关联至指定容器对象. 属性:通过标签的自定义属性初始化,也可以通过new方法传入的属性初始化 方法:开发暴露给使用者的自定义方法 事件:直接在标签上订阅事件,或通过脚本注册事件监听 事件产生:一般通过事件代理,监听容器内原生键鼠事件,根据触发事件的元素和事件类型,决定是否触发自定义事件.也可以不采用代理的方式直接注册组件内子对象的事件监听,处理较复杂的情况(不冒泡的事件).
Youtube UIX Widget Youtube在VelocityChina介绍<< YouTube的前端性能改进:逐步增强与超越>>其中最重要的UIX Widget系统即是HTC组件开发思想的跨浏览器封装,持续优化实践.
Youtube UIX Widget
Youtube UIX Widget
我们的实践X-HTC 基于YUI3和HTC组件构建思想,开发X-HTC前端组件架构 继承YUI3的Base使用YUI3的ATTR管理属性 使用<ins>标签关联组件与容器 使用mixin的方式区分私有方法集,公共方法集与事件代理方法集 组件对象即为YUI3的EventTarget实例,提供自定义事件支持 扩展YUI3 Widget对组件生命周期的管理.(initializer, renderUI, bindUI, syncUI, renderData, bindData, destructor) 扩展模块属性,解决HTC对其他模块的依赖. 提取数据源,以及数据结构对象,每个组件为单一数据结构(List,Tree,Set,Hash)服务,从多数据源获取数据.
X-HTC 解析 组件名称 属性对象 代理事件 自定义事件 公共方法 依赖模块
X-HTC 解析 组件解构层次 公共方法集mixin 事件代理集mixin 组件数据绑定 数据结构层次
X-HTC 未来 减少对YUI3的依赖,更好的控制内存 使用mustache模板系统渲染组件 适应NodeJS服务端组件生成
FACEBOOK BigPipe++ : STREAMING  HTMLstreaming  AjaxSTREAMING  crossdomain frames  Topic 4:
何时使用Bigpipe Facebook 由于高度定制化,首个请求服务端生成HTML耗时2s以上 当页面第一个请求耗时很短时,完全没有必要使用Bigpipe
BigPipe技术要点 一.Chunked HTTP: 一个HTTP请求可以分段发给发给客户端. PHP中,通过flush(),输出响应片段 二.浏览器支持分段解析HTML: chunk1: 		<body> 			<div>先解析先渲染</div> chunk2: 		<div>后渲染</div> 		</body>
BigPipe实质 : Streaming ChunkedHTTP:让数据分段流动,成为一切Streaming类解决方案的基础. 浏览器分段解析:让HTML,JS数据拥有被分段解析的可能 Facebook BigPipe chunk1: 		<body> 		<div id=‘pagelete1’/><div id=‘pagelete2’/> <script>//pagelet2</script> 	chunk2: <script>//pagelet1</script> 		</body>
Streaming++ Streaming	Ajax: 使用iframe做Ajax请求,即可做到将异步动态数据逐步流入. 这也是长链接(comet)的一种实现方式.
Streaming++ Streaming	Cross Crossdomainiframe: 使用一个iframe做Streaming,利用Dom方法将数据填写到页面其他iframe中. 第三方内容依然可以从Streaming受益 a.com chunk1 b.com: streaming iframe b.com: blank1 chunk2 b.com: blank2
客户端无阻滞: 第三方广告代码稳定性和性能优化 Topic 5:
广告影响网页稳定性 <script> alimama_pid="mm_1_2_3";alimama_type=2;  alimama_width=270;alimama_height=390;   </script>  <script src="http://a.alimama.cn/inf.js"></script> inf.js document.write: <iframe(script) src="http://t.alimama.com/a?i=mm_1_1_1 &fv=10.1&rd=xyz&u=a.com%2Fa.html"></iframe(script)>
静态脚本阻滞是根源 脚本阻滞:HTML中<script>节点对应的脚本下载且执行结束之前,浏览器不会发起任何新的HTTP请求,也不会对该节点以下的任何内容进行渲染.
Script Dom Element 使用ScriptDomElement解决脚本阻滞问题 function scriptDomElement(u) {  	var s = document.createElement('script'), 	h = document.getElementsByTagName('head')[0]; s.src= u;  s.async= true; 	if(h)h.insertBefore(s,h.firstChild);  }  通过Dom方法创建一个script节点,并插入到文档当中. 在各种浏览器中这种方式都能保证脚本与其他资源并行下载.
天生稳定的广告埋点 <script> document.write('<a style="display:none !important" id="t-a-{id}"></a>'); t_h= document.getElementsByTagName('head')[0]; t_s= document.createElement('script'); t_s.async= true; t_s.src= 'http://{host}/{path}?i={pid}'; 	if(t_h)t_h.insertBefore(t_s,t_h.firstChild); </script> 输出占位锚点做位置参照 <a style="display:none !important" id="t-a-{id}"></a> 异步无阻加载广告数据后,回调函数将广告内容插入到锚点之前.
老埋点提速改造 <script> alimama_pid="mm_1_2_3";alimama_type=2;  alimama_width=270;alimama_height=390;   </script>  <script src="http://a.alimama.cn/inf.js"></script>
inf.js-3.0 <script> alimama_pid="mm_1_2_3";alimama_type=2;  alimama_width=270;alimama_height=390;   </script>  <script src="http://anydomain/inf.js"></script>
inf.js-3.0 <script src="http://anydomain/inf.js"></script> <script> alimama_pid="mm_1_2_3";alimama_type=2;  alimama_width=270;alimama_height=390;   window.alimama_show && alimama_show(); </script>
inf.js-3.0 <!-- http://anydomain/any.js include the content of inf.js --> <script src="http://anydomain/any.js"></script> <script> alimama_pid="mm_1_2_3";alimama_type=2;  alimama_width=270;alimama_height=390;   window.alimama_show && alimama_show(); </script>
inf.js-3.0 <script>  //content of inf.js </script> <script> alimama_pid="mm_1_2_3";alimama_type=2;  alimama_width=270;alimama_height=390;   window.alimama_show && alimama_show(); </script>
 http://a.com/a.html: alimama_show() <head>     <script src="main.js"></script> </head> 异步 异步 回调 异步 回调 <script src="inf.js"></script> <script> alimama_show(); </script> <div>     <!-- ad content--> </div> 同步 <iframe  style="display:none !important" id="anchor-pid">    <!-- ad content--> </iframe>
Topic 6: severside clientside 服务端无阻滞: CommonJSNodeJSCFO(CloSures+Functions+Objects)体系 Web死后jser的未来
服务端阻滞 引擎前端机php使用kfc从其他后台服务获取数据 kfc_sendmsg($pg, $msg)  //阻滞..线程等待数据返回… $ret = kfc_recvmsg($pg, KFC_SYNC, $timeout);
更通俗的例子 var result = db.query("select.."); // use result either blocks the entire process or implies multiple execution stacks. db.query("select..", function (result) { 	// use result }); allows the program to return to the event loop immediately.
NodeJS node.js : 基于事件驱动的服务端JavaScript 优势在于同时处理大量不同类型的I/O 通过让所有网络系统I/O无阻塞,让所有文件系统I/O异步化来达到这个目标
NodeJS Node's goal is to provide an easy way to build scalable network programs. many client connections can be handled concurrently.  Node tells the operating system (throughepoll, kqueue, /dev/poll, or select) that it should be notified when a new connection is made, and then it goes to sleep. If someone new connects, then it executes the callback. Each connection is only a small heap allocation.
NodeJS性能同类比较 100byte响应大小并发与RT关系   300并发响应体大小与RT关系 nginxv0.7.65 	thinv1.2.7 (ruby 1.9.1-p376) node v0.1.91 tornadov0.2 (python 2.6.4)
TCP By NodeJS var net = require('net'),srv = net.createServer(),socket = null; var onDataArrived = function(data){ socket.write(data); }; var onConnectSuccess = function(skt){ socket = skt; socket.addListener("data",onDataArrived); }; srv.addListener("connection",onConnectSuccess); srv.listen(8124, "127.0.0.1");
var net = require('net'); net.createServer( 	function (socket) { socket.addListener("data",  			function (data) { socket.write(data); 			} 	); } ).listen(8124, "127.0.0.1"); Add Some Sugar 匿名函数 函数做参数 作用域链 链式调用
Why JavaScript ? 将服务端基于阻塞的系统改造为事件驱动系统,而GUI系统(如浏览器)多是事件驱动的系统. JavaScript是面向事件驱动系统成熟高效的语言. 无需为页面上每个可点击的部件安排一个线程等待点击的发生.
事件驱动中的状态保持 function main(){   var name = "limu";   var age = db.query("selectage from person where name="+name);   print("the age of" + name + "is" + age); } print("query start"); main(); print时变量name和age同时可用.
事件驱动中的状态保持 function main(){ 	var name = "limu"; db.query("selectage from person where name="+name, 		function(age){ 		print("the age of" + name + "is" + age); 		} 	); } main(); print("query start"); 假设查询耗时3秒,3秒后执行回调函数.print时age可用. 而一般而言name作为main函数的局部变量已经出了其作用域范围而被销毁. 如果想继续用name变量需要额外的保存动作,即状态保持.
CFO 体系 Understanding this strong relationship between objects, functions, and closures will improve your JavaScript programming ability giving you a strong foundation for any type of application development.
基于闭包的状态保持 function (socket) { socket.addListener("data",  		function (data) { 		//10s之后data到达本函数运行 			//为什么可以访问socket socket.write(data);	 		} ); } 闭包:function在生成时会保存所有当时可访问变量的引用,以备函数运行时使用.
CommonJS:JS想成为服务端语言还缺什么 Modules Binary strings and buffers Charset encodings Binary, buffered, and textual input and output (io) streams System process arguments, environment, and streams File system interface Socket streams Unit test assertions, running, and reporting Web server gateway interface, JSGI Local and remote packages and package management CommonJS是一种规范,NodeJS是这种规范的部分实现之一。
Web死后Jser的未来 由强大的CFO体系支撑: 熟练的面向事件驱动系统开发能力 无阻塞思想和熟练的异步回调式编码能力 熟练的面向对象程序设计能力
我们的动作 为浏览器端JS实现模块化和包管理以及相关的性能优化 做异步编程的简化和性能优化 在服务端使用NodeJS渲染生成页面的技术,结合Ajaxxx,在不支持JS的浏览器中也能够正常使用Ajaxxx构建的系统.做到一次编码,渐进增强.
JavaScript包管理+模块化:YUI3 & Kissy Vs.KIsssylite Topic 7: PyPI
第三方广告代码要求 必须稳定 足够小 结构化 无限可扩展
kissyLite kissylite,是kissy的一个支持有限方法的子集 目标是用1.5k代码支持可扩展的包管理和模块化管理 预览地址
ksLite -- 足够小 统一风格的OOP,异步的带依赖关系模块化,简单的模板. S.mix S.extend S.clone S.add S.use S.getScript S.substitute
ksLite -- 模块化 模块声明 S.add(modName,attachFunction,Config); 在attachFunction中做类的声明,在Config中指定当前模块所依赖的其他模块. 模块使用 S.use(modNames,callbackFunction); 可以一次使用多个模块,使用时按需载入所需模块,在callbackFunction中即可使用已加载模块中声明的类来生成实例.
KsLite Vs.YUI3 Kissy YUI3 和 Kissy同样提供模块化,但所有模块在use之前必须add. 这种模式不满足第三方代码无限可扩展需求. KsLite引入包管理,提高扩展性.
ksLite -- 基于包的扩展 包内无限可扩展=> 模块名由包名,路径,文件名.三部分构成. {packagename} - [ {path_0} - ... - {path_n} - ] {filename} S.Config.lt_pkgs={ inf:"http://a.alimama.cn/kslite/", test:"http://demo.taobao.com/tbad/kslite/" } 模块"inf-a“:http://a.alimama.cn/kslite/inf/a.js 模块"test-t-1“: http://demo.taobao.com/tbad/kslite/test/t/1.js
ksLite -- 基于包的扩展 可扩展无限包 => package root router 在一个地址记录所有可用的包以及对应的class root. S.Config.lt_pkgrouter = http://a.alimama.cn/kslite/router.js S.mix(S.Config.lt_pkgs,{     pkg1:"http://a.alimama.cn/pkg1/",     pkg2:"http://demo.taobao.com/tbad/pkg2/"     }); 当自带S.Config.lt_pkgs没有相关配置时询问pkgrouter.
ksLite -- 命名约定 S.add("pkg1-path1-mod1",function(S,P){    S["pkg1"]  = S["pkg1"]  ||  {};    P = S["pkg1"]; }); S.use("pkg1-path1-mod1",function(S,P){}); 保证包内对象都在名称空间P,即S.P内. 相当于另一个途径实现S.app(),嵌入至S的app. 为了被Kissy兼容,P只能作为开发约定,手动写在每个包中.
ksLite -- 轻量的add  S.add = function(name, fn, config){ var mods = S.Env.mods, mod;     if (mods[name] && mods[name].status > INIT)return;     mod = {name: name,fn: fn || null,status: LOADED};     mods[name] = S.mix(mod,config); } 不提前attach,保证模块在使用之前没有多余的代码执行消耗. 可选优化:domready之前按需执行,domready之后选择性预热.
ksLite -- 简单的use  S.use = function(modNames, callback){ var mods = S.Env.mods; modNames = modNames.split(','); S.attachMods(modNames, function(){        if (callback) callback(S);     }); } 将attachMods单独提出来.不止供use中使用.
ksLite – 明确的attachMod 如果模块LOADED,直接attach. 如果模块没有LOADED,则异步载入模块.然后attach. 模块load之后,attach时如果发现requires. attachMods(requires,callbcak).之后attach.
multiAsync加载多个模块 S.attachMods = function(modNames,callback){ var i, asyncers = {}; for (i = 0; i < modNames.length; i++) { asyncers[modNames[i]] = {     f: S.attachMod, a: modNames[i] }; } S.multiAsync(asyncers, callback); }
避免循环引用 模块和包都是无限可扩展的,一旦出现循环引用,影响客户页面稳定性 场景: 	mod-a requires mod-b 	mod-b requires mod-c mod-c requires mod-a 运行时: S.use("mod-a",function(){}); throw new Error("Fatal Error,LoopReqs!");
简单粗暴的算法 在env中有一个对象记录 x模块依赖哪些模块 	x模块支持哪些模块 当出现x依赖x的时候 thorw error.
ksLite的相关问题 避免循环引用解决了ksLite可能带来的稳定性隐患 遗留问题: 串行模块加载的性能问题 	attach(模块定义)何时运行的矛盾,提早运行延缓页面初始加载和完全按需运行拖慢事件响应. 异步化编程编码方式的简化
Google Closure Compiler 启示 : KISsylite在预编译时间窗口优化性能 Topic 8:
D2:Closure Complier 在D2论坛,来自Google的Hedger介绍了<<Coding Better Object-Oriented JavaScript with Closure Compiler>> Google Closure Complier告诉我们可以在代码发布前增加一个预编译步骤,在此时除了最小化压缩代码之外,编译器配合编码时的一些标准注释提示,来统一OO风格,减小对象深度以提高访问速度,使用枚举,常量等等其他语言好用的特性.
关于预编译 相对于编译型语言,JavaScript缺少了编译这个环节.传统编译器把代码转换为可执行的机器指令的动作交由浏览器中的JS引擎在运行时执行. 但现代的编译器除了代码翻译还有哪些功能?而JS引擎能在运行时Cover住这些任务么? 最常见的运行时编译无法解决的问题就是代码压缩.所以我们有各种Compressor让代码传输给浏览器的时是最小的.  Google Closure Complier解决了另外一些问题.
预编译打开一扇窗 Google Closure Complier更有意义的是告诉我们,可以有这样一个发布前预编译的步骤,可以有这样的一个时间窗口,在这个时候结合我们自己的应用,结合我们自己遇到的问题是不是也可以做点什么. 我们在预编译时间窗口解决ksLite遗留的性能相关问题.
颗粒化的性能问题 模块开发者开发一个功能,将它封装在mod-a中.  然后我们发现mod-a中可以抽象出来mod-b 于是就有了mod-b,同时mod-a requires mod-b. 模块使用者根据接口约定S.use("mod-a“,function(S){}); 拆分前 mod-a.js 拆分后 mod-a.js mod-b.js 问题:增加一个请求,而且是串行加载. 是否要为可能的重用而进行会引入性能问题的拆分?
预编译时优化 模块开发者不用考虑性能问题,进行最合适的颗粒化. 模块使用者在开发期间始终按照接口编码,即S.use("mod-a"); 编译器建议在发布之前,模块开发者颗粒已确定,模块使用者功能开发完毕,编译时建议此处应该S.use(“mod-a,mod-b”);以便并发加载 编译后 mod-a.js 编译前 mod-a.js mod-b.js mod-b.js 解决了串行的问题.
打包策略 mod-b可能在mod-a之前使用也可能跟随mod-a引入. 如果多数情况mod-b在mod-a之前,那拆分带来好处. 如果多数情况mod-b跟随mod-a引入,那mod-b的内容合并至mod-a将会带来好处. 应该合并a,b. 不应该合并a,b. mod-b.js mod-a.js (include mod-b.js) mod-a.js
最佳打包实践 预编译结合自动化测试可以构建最适合当前应用的打包方案. 预编译结合线上使用数据反馈,可以构建最优打包方案. Facebook在Velocity介绍的<<静态资源管理和优化>>,结合Facebook实际数据统计,计算出最优的模块合并方案.
预加载与延迟加载的矛盾 模块add时要不要attach(执行类定义相关代码). 即模块add时运行类定义还是use时运行类定义. add时attach:会导致页面加载过程中不必要的代码运行消耗,拖慢页面展现速度. use时attach:会导致事件触发时,由于需要得到模块attach以及可能的依赖模块加载,导致交互事件响应缓慢.
按需执行+选择性预热 add时不attach.优先保证页面展现速度. 在DomReady之前,页面展现阶段,只执行需要的代码. 在DomReady之后,对页面的交互功能进行预热. 页面上有很多功能,应该提前预热哪些? 结合重点Case自动化测试用例,预编译可以给出最优的预热方案. S.ready(function(){S.use("mod-b,mod-d,mod-e")});
Jscex 和kslite对异步编码的简化 Topic 9:
asyncer -- 异步执行单元 /*  * @interface asyncer可能需要等待再回调的function.  * @param { * } args * @param { Function | Object } callback info * @param {number} timeout(ms) *  @return {Object}  */ function ayncer(args , callback,timeout){ }
parallel asyncers asyncerA(a,function(resA){  window.resA = resA;     if(window.resB)c(); }); asyncerB(b,function(resB){     window.resB = resB;     if(window.resA)c(); }) function c(){       //your code run after resA & resB both returend.  }
serial asyncers asyncerA(a,function(resA){  asyncerB(b,function(resB){ asyncerC(c,function(resC){            		//your code.         		})     	}); });
S.multiAsync S.multiAsync(asyncers,callback,timeout); 面向asyncer的interface,通过简单的开发,避免paralleasynce类操作等待其他操作完成时的hardcode. 将开发S.serialAsync,避免过多回调造成的作用域链过长而导致的性能下降.
更先进的异步编程简化 Jscex(JavaScript Computation Expressions)由老赵开发,在D2作品秀环节介绍给大家. Jscex让大家以阻塞的模式写代码再经过Jscex实时编译器将代码转化为异步的模式执行.
更先进的异步编程简化 前面的代码编译为下面这段,交给浏览器执行: 如果说异步式编程像机器语言一样难写难懂,Jscex将其转化为高级语言一样易于编写和阅读.而ksLite提供的multiAsync和serialAsync则是像汇编语言一样用较少的代码代价对异步编程略微简化,避免一些hardcode,同时解决一些不易处理的性能问题.
Thanks!limu@taobao.comhttp://twitter.com/lenel_li

More Related Content

What's hot

重构之道 触屏篇
重构之道 触屏篇重构之道 触屏篇
重构之道 触屏篇麦哥UE
 
Web安全解决方案V1.0
Web安全解决方案V1.0Web安全解决方案V1.0
Web安全解决方案V1.0xuanliang
 
Creating CSS Template with Barrie North
Creating CSS Template with Barrie NorthCreating CSS Template with Barrie North
Creating CSS Template with Barrie North
John Coonen
 
深入剖析浏览器
深入剖析浏览器深入剖析浏览器
深入剖析浏览器
jay li
 
掌星 移动互联网开发笔记-Vol002
掌星 移动互联网开发笔记-Vol002掌星 移动互联网开发笔记-Vol002
掌星 移动互联网开发笔记-Vol002rainx1982
 
Img lazy-load
Img lazy-loadImg lazy-load
Img lazy-load
liuzhitao2000
 

What's hot (7)

Jsp讲义
Jsp讲义Jsp讲义
Jsp讲义
 
重构之道 触屏篇
重构之道 触屏篇重构之道 触屏篇
重构之道 触屏篇
 
Web安全解决方案V1.0
Web安全解决方案V1.0Web安全解决方案V1.0
Web安全解决方案V1.0
 
Creating CSS Template with Barrie North
Creating CSS Template with Barrie NorthCreating CSS Template with Barrie North
Creating CSS Template with Barrie North
 
深入剖析浏览器
深入剖析浏览器深入剖析浏览器
深入剖析浏览器
 
掌星 移动互联网开发笔记-Vol002
掌星 移动互联网开发笔记-Vol002掌星 移动互联网开发笔记-Vol002
掌星 移动互联网开发笔记-Vol002
 
Img lazy-load
Img lazy-loadImg lazy-load
Img lazy-load
 

Viewers also liked

D2-ETao-show
D2-ETao-showD2-ETao-show
D2-ETao-showleneli
 
SLT Times Single Stock Futures
SLT Times Single Stock FuturesSLT Times Single Stock Futures
SLT Times Single Stock Futures
nico9111
 
广告投放代码和创意代码持续优化
广告投放代码和创意代码持续优化广告投放代码和创意代码持续优化
广告投放代码和创意代码持续优化leneli
 
Water molecules2
Water molecules2Water molecules2
Water molecules2gary6h
 
Zs social media
Zs social mediaZs social media
Zs social media
Wael Albassam
 
Ravi project
Ravi projectRavi project
Ravi projectgary6h
 
Pen test for sys admin
Pen test for sys adminPen test for sys admin
Pen test for sys adminsussurro
 
OPOA in Action -- 使用MagixJS简化WebAPP开发
OPOA in Action -- 使用MagixJS简化WebAPP开发OPOA in Action -- 使用MagixJS简化WebAPP开发
OPOA in Action -- 使用MagixJS简化WebAPP开发leneli
 
Conflict Management Style
Conflict Management StyleConflict Management Style
Conflict Management Style
Yvette Mong-Batar
 
Adoption Announcement
Adoption AnnouncementAdoption Announcement
Adoption Announcementcltipton
 
Zs social media
Zs social mediaZs social media
Zs social media
Wael Albassam
 
第三方广告代码稳定性和性能优化实战
第三方广告代码稳定性和性能优化实战第三方广告代码稳定性和性能优化实战
第三方广告代码稳定性和性能优化实战leneli
 
How ZI Created a Successful HR Framework
How ZI Created a Successful HR FrameworkHow ZI Created a Successful HR Framework
How ZI Created a Successful HR Framework
Wael Albassam
 
After Yahoo 34 Rules -- 网站性能优化新进展
After Yahoo 34 Rules -- 网站性能优化新进展After Yahoo 34 Rules -- 网站性能优化新进展
After Yahoo 34 Rules -- 网站性能优化新进展
leneli
 
使用kslite支持第三方内容开发
使用kslite支持第三方内容开发使用kslite支持第三方内容开发
使用kslite支持第三方内容开发leneli
 
Multi-Player Metasploit: Tag Team Pen Testing and Reporting
Multi-Player Metasploit: Tag Team Pen Testing and ReportingMulti-Player Metasploit: Tag Team Pen Testing and Reporting
Multi-Player Metasploit: Tag Team Pen Testing and Reporting
sussurro
 

Viewers also liked (17)

Zs social media
Zs social mediaZs social media
Zs social media
 
D2-ETao-show
D2-ETao-showD2-ETao-show
D2-ETao-show
 
SLT Times Single Stock Futures
SLT Times Single Stock FuturesSLT Times Single Stock Futures
SLT Times Single Stock Futures
 
广告投放代码和创意代码持续优化
广告投放代码和创意代码持续优化广告投放代码和创意代码持续优化
广告投放代码和创意代码持续优化
 
Water molecules2
Water molecules2Water molecules2
Water molecules2
 
Zs social media
Zs social mediaZs social media
Zs social media
 
Ravi project
Ravi projectRavi project
Ravi project
 
Pen test for sys admin
Pen test for sys adminPen test for sys admin
Pen test for sys admin
 
OPOA in Action -- 使用MagixJS简化WebAPP开发
OPOA in Action -- 使用MagixJS简化WebAPP开发OPOA in Action -- 使用MagixJS简化WebAPP开发
OPOA in Action -- 使用MagixJS简化WebAPP开发
 
Conflict Management Style
Conflict Management StyleConflict Management Style
Conflict Management Style
 
Adoption Announcement
Adoption AnnouncementAdoption Announcement
Adoption Announcement
 
Zs social media
Zs social mediaZs social media
Zs social media
 
第三方广告代码稳定性和性能优化实战
第三方广告代码稳定性和性能优化实战第三方广告代码稳定性和性能优化实战
第三方广告代码稳定性和性能优化实战
 
How ZI Created a Successful HR Framework
How ZI Created a Successful HR FrameworkHow ZI Created a Successful HR Framework
How ZI Created a Successful HR Framework
 
After Yahoo 34 Rules -- 网站性能优化新进展
After Yahoo 34 Rules -- 网站性能优化新进展After Yahoo 34 Rules -- 网站性能优化新进展
After Yahoo 34 Rules -- 网站性能优化新进展
 
使用kslite支持第三方内容开发
使用kslite支持第三方内容开发使用kslite支持第三方内容开发
使用kslite支持第三方内容开发
 
Multi-Player Metasploit: Tag Team Pen Testing and Reporting
Multi-Player Metasploit: Tag Team Pen Testing and ReportingMulti-Player Metasploit: Tag Team Pen Testing and Reporting
Multi-Player Metasploit: Tag Team Pen Testing and Reporting
 

Similar to TBAD F2E 2010 review

高性能网站最佳实践
高性能网站最佳实践高性能网站最佳实践
高性能网站最佳实践longhao
 
Struts1+ hibernate3
Struts1+ hibernate3Struts1+ hibernate3
Struts1+ hibernate3
edanwade
 
淘宝移动端Web开发最佳实践
淘宝移动端Web开发最佳实践淘宝移动端Web开发最佳实践
淘宝移动端Web开发最佳实践
Du Yamin
 
淘宝移动端Web开发最佳实践
淘宝移动端Web开发最佳实践淘宝移动端Web开发最佳实践
淘宝移动端Web开发最佳实践jay li
 
Html5css3 go.yeefe.com
Html5css3 go.yeefe.comHtml5css3 go.yeefe.com
Html5css3 go.yeefe.comtellyeefe
 
揭秘Html5和Css3 ---- 鲁超伍
揭秘Html5和Css3 ---- 鲁超伍揭秘Html5和Css3 ---- 鲁超伍
揭秘Html5和Css3 ---- 鲁超伍
裕波 周
 
Using google appengine (2)
Using google appengine (2)Using google appengine (2)
Using google appengine (2)Wei Sun
 
Using google appengine_1027
Using google appengine_1027Using google appengine_1027
Using google appengine_1027Wei Sun
 
Exam 98-375 HTML5 Application Development Fundamentals
Exam 98-375 HTML5 Application Development FundamentalsExam 98-375 HTML5 Application Development Fundamentals
Exam 98-375 HTML5 Application Development Fundamentals
Chieh Lin
 
口碑导航更换项目总结
口碑导航更换项目总结口碑导航更换项目总结
口碑导航更换项目总结
liuzhitao2000
 
Using google appengine_final
Using google appengine_finalUsing google appengine_final
Using google appengine_finalWei Sun
 
Collaboration On Rails
Collaboration On RailsCollaboration On Rails
Collaboration On RailsJesse Cai
 
Web设计 3 java_script初探(程序员与设计师的双重眼光)
Web设计 3 java_script初探(程序员与设计师的双重眼光)Web设计 3 java_script初探(程序员与设计师的双重眼光)
Web设计 3 java_script初探(程序员与设计师的双重眼光)ziggear
 
Js dom
Js domJs dom
Js dom
lidashuang
 
淘宝移动端Web开发实践
淘宝移动端Web开发实践淘宝移动端Web开发实践
淘宝移动端Web开发实践完颜 小卓
 
Chicago EXPO Creating a Pure CSS Template in Joomla 1.5
Chicago EXPO Creating a Pure CSS Template in Joomla 1.5Chicago EXPO Creating a Pure CSS Template in Joomla 1.5
Chicago EXPO Creating a Pure CSS Template in Joomla 1.5
compassdesign
 
WEB 安全基础
WEB 安全基础WEB 安全基础
WEB 安全基础xki
 
Denver CMS Expo Creating CSS template
Denver CMS Expo Creating CSS templateDenver CMS Expo Creating CSS template
Denver CMS Expo Creating CSS templatecompassdesign
 
Ibatis技术讲座
Ibatis技术讲座Ibatis技术讲座
Ibatis技术讲座
xujie
 

Similar to TBAD F2E 2010 review (20)

高性能网站最佳实践
高性能网站最佳实践高性能网站最佳实践
高性能网站最佳实践
 
Struts1+ hibernate3
Struts1+ hibernate3Struts1+ hibernate3
Struts1+ hibernate3
 
淘宝移动端Web开发最佳实践
淘宝移动端Web开发最佳实践淘宝移动端Web开发最佳实践
淘宝移动端Web开发最佳实践
 
淘宝移动端Web开发最佳实践
淘宝移动端Web开发最佳实践淘宝移动端Web开发最佳实践
淘宝移动端Web开发最佳实践
 
Html5css3 go.yeefe.com
Html5css3 go.yeefe.comHtml5css3 go.yeefe.com
Html5css3 go.yeefe.com
 
揭秘Html5和Css3 ---- 鲁超伍
揭秘Html5和Css3 ---- 鲁超伍揭秘Html5和Css3 ---- 鲁超伍
揭秘Html5和Css3 ---- 鲁超伍
 
Using google appengine (2)
Using google appengine (2)Using google appengine (2)
Using google appengine (2)
 
Using google appengine_1027
Using google appengine_1027Using google appengine_1027
Using google appengine_1027
 
Web base 吴志华
Web base 吴志华Web base 吴志华
Web base 吴志华
 
Exam 98-375 HTML5 Application Development Fundamentals
Exam 98-375 HTML5 Application Development FundamentalsExam 98-375 HTML5 Application Development Fundamentals
Exam 98-375 HTML5 Application Development Fundamentals
 
口碑导航更换项目总结
口碑导航更换项目总结口碑导航更换项目总结
口碑导航更换项目总结
 
Using google appengine_final
Using google appengine_finalUsing google appengine_final
Using google appengine_final
 
Collaboration On Rails
Collaboration On RailsCollaboration On Rails
Collaboration On Rails
 
Web设计 3 java_script初探(程序员与设计师的双重眼光)
Web设计 3 java_script初探(程序员与设计师的双重眼光)Web设计 3 java_script初探(程序员与设计师的双重眼光)
Web设计 3 java_script初探(程序员与设计师的双重眼光)
 
Js dom
Js domJs dom
Js dom
 
淘宝移动端Web开发实践
淘宝移动端Web开发实践淘宝移动端Web开发实践
淘宝移动端Web开发实践
 
Chicago EXPO Creating a Pure CSS Template in Joomla 1.5
Chicago EXPO Creating a Pure CSS Template in Joomla 1.5Chicago EXPO Creating a Pure CSS Template in Joomla 1.5
Chicago EXPO Creating a Pure CSS Template in Joomla 1.5
 
WEB 安全基础
WEB 安全基础WEB 安全基础
WEB 安全基础
 
Denver CMS Expo Creating CSS template
Denver CMS Expo Creating CSS templateDenver CMS Expo Creating CSS template
Denver CMS Expo Creating CSS template
 
Ibatis技术讲座
Ibatis技术讲座Ibatis技术讲座
Ibatis技术讲座
 

TBAD F2E 2010 review