SlideShare ist ein Scribd-Unternehmen logo
1 von 66
Downloaden Sie, um offline zu lesen
Jackson Tian/田永强 @朴灵 at SAP

从无阻塞脚本加载(LAB.js)到浏
览器线程模型

                              5/7/2011   1
Agenda

 为什么script会阻塞页面解析
 如何实现无阻塞脚本加载
 依赖管理与无阻塞并行加载与顺序执行(LAB.js实现机
 制)
 无阻塞脚本加载潜在问题
 为什么要谈谈JavaScript线程
 为什么要谈谈同步与异步
 浏览器线程消息模型
 从Web Worker看浏览器的线程
 NodeJS的单线程与多线程

                       5/7/2011   2
说到无阻塞脚本加载

 你不得不知道的大牛是
 Steve Souders
 At Google on web performance and open
  source initiatives.
 http://www.stevesouders.com/




                                 5/7/2011   3
为什么script标签会阻塞页面解
析
 从Document.write说起
  Document.write() 是魔鬼。
    <p>task 1.</p>
    <script>document.write(“<p>task5</p>”);</script>
    <p>task 2.</p>
    <p>task 3.</p>
    <p>task 4.</p>
  浏览器在UI渲染上,采用队列的方式实现




                                      5/7/2011         4
5/7/2011   5
Document.write是魔鬼

 队列的基本原则
  先进先出原则(FIFO, First-In-First-Out)
   http://zh.wikipedia.org/wiki/%E9%98%9F%E5%8
   8%97
 Document.write破坏了原始的UI更新队列
 从document.write来看,JavaScript设计之
 初只是用来做Web页面辅助的



                                 5/7/2011        6
5/7/2011   7
Alert也是魔鬼

 alert(“I am evil, too.”);
 是否有人通过alert来debug JavaScript程序
  呢?
   for(var i=0; i< 1000; i++) {
    alert(“Hi, ” + i);
    }
 alert最坏的地方在于它中断整个UI线程
 用户体验的敌人(桌面浏览器)
 confirm,prompt方法也是类似的
                                   5/7/2011   8
为什么script标签会阻塞页面解
析
 基于以上的历史原因,JavaScript线程与UI
    共用同一进程,而且JS任务优先于UI任务
   浏览器会在遇到Script标签的时候进行解析
    和执行
   如果Script是外链的话,还要等待下载
   如果页面存在多个外链脚本,下载是串行
    的
   在IE8, Firefox3.5, Safari4和Chrome2开始允
    许并行下载JavaScript文件,但是依然会阻
    塞页面的其他资源的下载
                              5/7/2011     9
Chromium解析流程




               此图由Tapir(貘)提供,感谢他

                    5/7/2011       10
YSlow的35条军规
       Put Scripts at the Bottom
         http://developer.yahoo.com/performance/rules.html#js_bottom
         如果脚本的下载+解析+执行的时间太久,UI队列没有得到执行,
          页面会出现空白
         Yahoo!建议将所有的脚本都放在</body>之前,让UI队列优先
          执行和显示。
       Minimize HTTP Requests
         http://developer.yahoo.com/performance/rules.html#num_http
         页面脚本过多的情况下,通过combo和compress减少请求数
       问题?
         在</body>之前存在一个较大的脚本文件需要下载和执行
         UI在ready之后,需要较长时间等待脚本的下载和执行,在脚本
          ready之前,UI是出于无事件响应状态的。


                                                     5/7/2011           11
无阻塞脚本加载

 我们需要预先加载脚本,而且不阻塞UI的
 渲染
  对YSlow规则说No
   Put Scripts at the Bottom

 为过往的犯错买单,看看标准和浏览器厂
 商都做了什么方案来补救




                                5/7/2011   12
Defer属性

 HTML4标准为<script>标签定义了defer属性,
 以此声明告诉浏览器内容中不包含
 document.write之类破坏DOM的脚本
 浏览器会延迟(无阻塞)下载脚本,并按
  <script>脚本顺序执行。
 在onload事件前执行
 实现/支持情况
  IE4.0
  Firefox3.5
                     5/7/2011   13
Async属性

 HTML5标准为<script>标签定义了async属性
 与defer属性相同的是脚本会无阻塞加载
 与defer属性不同的是脚本在加载完了立即
  执行,并非按照<script>标签顺序执行
 实现/支持情况
    Firefox3.6
    Opera10.5
    Safari
    Chrome
    IE9.0(defer的别名?)

                        5/7/2011   14
标准与实现之间的差距

 动态脚本元素
  利用一小段脚本去创建<script>标签,实现无阻
   塞加载
  var script = document.createElement('script');
   script.src = 'myscript.js';
   var head =
   document.getElementsByTagName('head')[0];
   head.appendChild(script);



                                     5/7/2011       15
Script标签的onload事件
function loadScript(url, callback){
 var script = document.createElement(”script”)
      script.type = “text/javascript”;
 if (script.readyState){ //IE
          script.onreadystatechange = function(){
             if (script.readyState == “loaded” ||
                  script.readyState == “complete”){
                script.onreadystatechange = null;
                callback();
             }
          };
       } else { //Others
          script.onload = function(){
             callback();
          };
       }
 script.src = url;
      document.body.appendChild(script);
    }


                                                      5/7/2011   16
无阻塞脚本加载实例

 Google Analytics代码
   http://code.google.com/intl/zh-
    CN/apis/analytics/docs/tracking/asyncTracking.ht
    ml




                                      5/7/2011         17
XMLHttprequest脚本注入

 $.get(“script.js”, function (responseText) {
  var script =
  document.createElement(“script”);
  script.type=“text/javascript”;
  script.text = “responseText”;
  document.body.appendChild(script);
  });
 可以控制下载和执行
 该方法基于Ajax,受同源策略影响,无法使
  用CDN。

                                    5/7/2011     18
XMLHttpRequest Eval

 $.get(“script.js”, function (responseText) {
  eval(responseText);
  });
 与XMLHttpRequest具有相同的优点和缺点
 但是,Eval is Evil。




                                    5/7/2011     19
document.write Script Tag

 document.write(“<script src=‘script.js’>
  </script>”);
 只有IE生效
 如果在文档流关闭之后再调用
  document.write(),整个DOM会被毁坏




                                   5/7/2011   20
Script in Iframe

 我也不知道怎么搞。
 很复杂。
 Google都Google不到。
 也许是<iframe src=“#”></iframe>




                            5/7/2011   21
问题总结

 同源策略限制(XHR inject, XHR eval,Iframe)
 顺序执行(动态script元素, async)
 浏览器支持(async, defer)
 并行下载与顺序执行




                            5/7/2011    22
各种方法支持一览
        方法     并行加载       顺序执行   不受同源限制          浏览器都支持
Defer         √       √          √          x
Async         √       x          √          x
动态脚本元素         √      x          √          √
XHR Inject    √       √          x          √
XHR Eval      √       √          x          √
Document.write √      √          √          x

Iframe        √       ?          x          √




                                      5/7/2011            23
无顺序执行的要求情况下
        方法     并行加载       顺序执行   不受同源限制          浏览器都支持
Defer         √       √          √          x
Async         √       x          √          x
动态脚本元素         √      x          √          √
XHR Inject    √       √          x          √
XHR Eval      √       √          x          √
Document.write √      √          √          x

Iframe        √       ?          x          √




                                      5/7/2011            24
5/7/2011   25
如何控制依赖加载

 通过onload事件控制?
 loadScript(“file1.js”, function() {
    loadScript(“file2.js”, function() {
      loadScript(“file3.js”, function() {
          alert(“All ready.”);
       });
    });
 });
 这是串行加载的


                                            5/7/2011   26
如何控制依赖加载

 或者采用defer?
  <script src=“script1.js” defer></script>
  <script src=“script2.js” defer></script>
  <script src=“script3.js” defer></script>
 显然浏览器支持不够




                                    5/7/2011   27
如何控制依赖加载

 更或者通过XHR动态加载,顺序执行
 同源策略怎么办?




                5/7/2011   28
如何控制依赖加载

 在Server端组织好脚本顺序,并且combo成
  一个文件
 这是一个好主意!!!
 但是总有你不能combo的文件,比如本地
  化的资源文件




                   5/7/2011   29
依赖加载
   ≠
必须顺序加载
   ≠
 串行加载

     5/7/2011   30
顺序执行
  ≠
立即执行



       5/7/2011   31
有没有一种方法

 能实现并行下载
 能实现顺序执行
 能没有副作用




            5/7/2011   32
LAB.js

 @getify
 Kyle Simpson
 公司:Getify Solutions
 LABjs被很多大网站所采用,包括新版的
  Twitter, Zappos, 以及 Vimeo.
 Kyle Simpson在Steve Sounders的启示下写
  下了LABjs这个库,用于管理并行加载和顺
  序执行

                         5/7/2011    33
LABjs的诀窍

 对于Firefox/Opera,采用动态Script DOM
  element可以完美地实现并行下载和顺序执
  行
 对于Safari/Chrome,无法保证顺序执行,
  但是LABjs通过插入一个<script
  type=“text/cache” src=“#”>来实现。
  IE/Safari/Chrome浏览器会下载文件到缓存
  并触发onload事件,但不会执行


                         5/7/2011   34
LABjs的诀窍

 在需要的文件下载完成之后,再次通过插
  入正确的type=“text/javascript”而且监听
  onload来完成对于顺序执行的控制
 LABjs判断script文件是否同域文件,优先选
  择XHR Injection实现并行下载,顺序执行
 Text/cache严重依赖浏览器的非标准特性




                       5/7/2011    35
LABjs示例

 Sample Code
   <script src="LAB.js"></script>
    <script>
    $LAB .script("http://remote/jquery.js”).wait()
    .script("/local/plugin1.jquery.js")
    .script("/local/plugin2.jquery.js").wait()
    .script("/local/init.js").wait(function(){ initMyPage();
    });
    </script>




                                                 5/7/2011      36
LABjs方法

 主要方法
  Script()
    可以多次调用script方法来并行加载脚本
  Wait()
    通过调用wait方法来保证序列中的脚本执行顺序




                       5/7/2011   37
LABjs API示意




              5/7/2011   38
题外话

 曾经Firefox4试图改掉动态脚本元素按顺序执行的
  特性,使得像Chrome/Safari一样
 那么,在面对CDN脚本,text/cache失效的情况下,
  LABjs会无可奈何地进行串行下载
 有链接为证:
  http://blog.getify.com/2010/10/ff4-script-loaders-and-
   order-preservation/
  http://blog.getify.com/2010/10/mozilla-labjs-the-story-
   unfolds/
  http://blog.getify.com/2010/10/mozilla-labjs-part-2/


                                             5/7/2011        39
题外话

 后来,getify赢了




                5/7/2011   40
无阻塞脚本与DOM

 在脚本加载完成的时候,DOM可能
  DOM还没有DOMContentLoaded(加载速度快或
  者来自cache)
   访问DOM是危险的
  DOM可能已经DOMContentLoaded了
   绑定DOMContentLoaded事件永远也不会被触发
   如何判断DOM是否ready
  DOM甚至已经Onload了(IE)



                        5/7/2011   41
如何解决以上问题?

 DOM还没有DOMContentLoaded(加载速度
 快或者来自cache)
  保证DOM操作注册在DOMContentLoaded事件
  中
 DOM可能已经DOMContentLoaded了
  绑定DOMContentLoaded事件永远也不会被触发
  通过document.readyState == “complete”判断
  DOMready
 DOM甚至已经Onload了(IE)
  document.readyState 依然有效


                              5/7/2011     42
回顾

 Combo脚本文件,以减少链接数
 优先加载和无阻塞加载,实现界面快速响
  应
 采用LABjs做依赖管理,实现并行下载和顺
  序执行
 控制好访问DOM的代码,确保在
  DOMContentLoaded后执行


                 5/7/2011   43
为什么要啰嗦浏览器线程

 无阻塞加载讲得又不深入,还要啰嗦浏览
 器线程
 因为扯谈了这么多,目的只是将脚本的下
  载线程脱离UI线程而已
 设计JavaScript执行和UI渲染共用UI线程的
  人上辈子是折翼的天使,伤不起




                     5/7/2011   44
JavaScript线程怨念知多少

 为什么JavaScript作为一门编程语言,却没
  有多线程?
 抱怨JavaScript没有多线程的程序员不是好
  程序员
 有多少人用setTimeout模拟过多线程




                   5/7/2011   45
JavaScript线程

 JavaScript的多线程
  找到约 1,280,000 条结果 (用时 0.13 秒)
  http://www.google.com.hk/search?sourceid=chro
   me&ie=UTF-
   8&q=JavaScript+%E5%A4%9A%E7%BA%BF%E7
   %A8%8B




                                  5/7/2011         46
可是

 你知道的
  浏览器并不是单线程
  JavaScript是单线程 ≠ 浏览器是单线程
  WebApp ≠ JavaScript App
  WebApp = 浏览器 + JavaScript + CSS + HTML +
  Images + …. + API
 所以
  JavaScript的单线程是有原因的


                                5/7/2011      47
浏览器线程知多少

 UI渲染线程/JavaScript执行线程
 资源下载线程(JavaScript, CSS, Image,
  Object)
 Ajax线程
 Web Worker线程
 还有?欢迎补充




                           5/7/2011   48
前端,你伤不起

 在所有下载线程中
  为什么CSS文件加载不会block页面?
  为什么图片加载不会block页面?
  为什么flash加载不会block页面?
  为什么ajax还有同步和异步之分?
  为什么JavaScript文件会block UI?




                           5/7/2011   49
关于AJAX的同步异步

 同步与异步的差别来自于AJAX的盛行
 同步Ajax会锁住整个浏览器,直到请求完成
 而异步请求则无影响,但是接收结果必须
 通过回调函数




                5/7/2011   50
被各种ajax库宠坏的孩子们
   看看最原始的Ajax吧
       var httpRequest;
        if (window.XMLHttpRequest) { // Mozilla, Safari, ...
           httpRequest = new XMLHttpRequest();
         } else if (window.ActiveXObject) { // IE
           httpRequest = new ActiveXObject("Microsoft.XMLHTTP");
        }
        httpRequest.onreadystatechange = function(){
           if (httpRequest.readyState === 4) {
             if (httpRequest.status === 200) {
                  // perfect!
             } else {
                 // there was a problem with the request,
                // for example the response may be a 404 (Not Found)
                // or 500 (Internal Server Error) response codes
             }
           } else {
               // still not ready
           }
        };
        httpRequest.open('GET', ‘http://url', true);
        httpRequest.send(null);



                                                                       5/7/2011   51
异步Ajax模型




           5/7/2011   52
同步Ajax模型




           5/7/2011   53
消息模型与事件驱动

 在所有的浏览器线程之间的交互,是通过
  消息来传递的
 我们唯一能控制的线程是UI线程
 其余的线程我们只能通过侦听事件消息才
  能得到数据
 所有的事件handler都由浏览器来做事件驱
  动


                  5/7/2011   54
消息编程模型 Vs. 多线程编程

 消息模型是构建在多线程的基础之上的
 在JavaScript的领域里(包括NodeJS), 多线程
  的细节被隔离
 应用里的多线程操作通过事件驱动和消息
  传递暴露给程序员
 鼓吹消息模型而鄙视多线程模型的程序员
  不是好的工程师


                       5/7/2011    55
从Web Worker看浏览器的线程

 将JavaScript执行线程脱离UI线程
 Web Worker的线程也可以控制,但是交互
 依然是消息




                      5/7/2011   56
浏览器是最成熟的消息模型应用

 异步Ajax
 各种资源的下载消息通知
 浏览器原生事件驱动
  UI事件驱动
  网络事件驱动




                5/7/2011   57
消息模型的优势

 编程模型简化
  多线程框架由底层实现和托管,我们只负责调
   用API启动线程,发送消息和侦听消息
  对编程人员隔离多线程的烦恼
 程序耦合性低
  程序代码属于被trigger的状况,不耦合于目标
   代码
  我讨厌异步特有的callback编程,但是我喜欢消
   息模型
 原生的AOP编程

                    5/7/2011   58
消息模型的弱势

 无法手动构造多线程实现并行和异步
  严重依赖应用的支持
   以web worker和websocket为例,只有浏览器支持
   的情况下,才能享受到消息模型的好处
 事件驱动依赖应用实现
  可以手动触发自定义事件,但是对于特殊事件
 无法触发




                         5/7/2011     59
NodeJS是一个跑在Server端的浏览器


  浏览器架构(Chrome)   NodeJS架构




                     5/7/2011   60
未来世界也许会是这样的

 它也许是浏览器
 它也许是NodeJS
 它也许什么应用都不是,但是应用都跑在
 这上面




               5/7/2011   61
为何JScript在服务端会死掉?

 var objConn = Server.CreateObject("ADODB.Connection");
 // open our ADO connection and Execute the SQL command
 objConn.Open("dsn=helpdesk", "sa", "");
 objConn.Execute(strCommandText);
 var returnErrCode =
   objConn.Execute("SELECT @@ERROR as
  errorCode").GetString();


 objConn.Close();
 objConn = null;



                                           5/7/2011        62
JScript Vs. NodeJS

 JScript之死
  摒弃了JavaScript在浏览器中的异步机制
  完全无视消息模型
  无多线程支持
  在Server端,表现与PHP和ASP无异
 NodeJS之生
  延续JavaScript在浏览器端赖以生存的特性
  异步,消息模型,事件驱动
  向程序员屏蔽多线程

                      5/7/2011   63
结语

 Block UI的JavaScript不是好JavaScript
 无消息模型,不JavaScript
 无事件驱动,不JavaScript
 浏览器是多线程的,JavaScript是单线程
 上一条适用于NodeJS




                             5/7/2011   64
References

 http://www.stevesouders.com/blog/2009/04/
  27/loading-scripts-without-blocking/
 http://www.blog.highub.com/mobile-
  2/mobile-safari-scripts-loading-without-
  blocking/
 http://blogs.sitepoint.com/non-blocking-
  async-defer/



                                  5/7/2011    65
Thanks




         5/7/2011   66

Weitere ähnliche Inhalte

Was ist angesagt?

使用 wagon + VS Code 輕鬆打造 Windows 平台 PHP/Laravel 開發環境
使用 wagon + VS Code 輕鬆打造 Windows 平台 PHP/Laravel 開發環境使用 wagon + VS Code 輕鬆打造 Windows 平台 PHP/Laravel 開發環境
使用 wagon + VS Code 輕鬆打造 Windows 平台 PHP/Laravel 開發環境Shengyou Fan
 
YUI 教學 - 前端工程開發實務訓練
YUI 教學 - 前端工程開發實務訓練YUI 教學 - 前端工程開發實務訓練
YUI 教學 - 前端工程開發實務訓練Joseph Chiang
 
从无阻塞并行脚本加载(Lab.js)到浏览器消息模型
从无阻塞并行脚本加载(Lab.js)到浏览器消息模型从无阻塞并行脚本加载(Lab.js)到浏览器消息模型
从无阻塞并行脚本加载(Lab.js)到浏览器消息模型裕波 周
 
[Modern Web 2016] 讓你的 PHP 開發流程再次潮起來
[Modern Web 2016] 讓你的 PHP 開發流程再次潮起來[Modern Web 2016] 讓你的 PHP 開發流程再次潮起來
[Modern Web 2016] 讓你的 PHP 開發流程再次潮起來Shengyou Fan
 
TypeScript-twmvc#16
TypeScript-twmvc#16TypeScript-twmvc#16
TypeScript-twmvc#16twMVC
 
CodeIgniter 2.0.X
CodeIgniter 2.0.XCodeIgniter 2.0.X
CodeIgniter 2.0.XBo-Yi Wu
 
How to choose web framework
How to choose web frameworkHow to choose web framework
How to choose web frameworkBo-Yi Wu
 
啟動 Laravel 與環境設定
啟動 Laravel 與環境設定啟動 Laravel 與環境設定
啟動 Laravel 與環境設定Shengyou Fan
 
COSCUP 2016 Laravel 部署工作坊 - 部署指南
COSCUP 2016 Laravel 部署工作坊 - 部署指南COSCUP 2016 Laravel 部署工作坊 - 部署指南
COSCUP 2016 Laravel 部署工作坊 - 部署指南Shengyou Fan
 
模块化和组件化Css
模块化和组件化Css模块化和组件化Css
模块化和组件化CssWu tianhao
 
PHP 語法基礎與物件導向
PHP 語法基礎與物件導向PHP 語法基礎與物件導向
PHP 語法基礎與物件導向Shengyou Fan
 
基于Ivy ant的java构建初探
基于Ivy ant的java构建初探基于Ivy ant的java构建初探
基于Ivy ant的java构建初探Anson Yang
 
Model 設定與 Seeding
Model 設定與 SeedingModel 設定與 Seeding
Model 設定與 SeedingShengyou Fan
 
Visual Studio Code 快速上手指南
Visual Studio Code 快速上手指南Visual Studio Code 快速上手指南
Visual Studio Code 快速上手指南Shengyou Fan
 
Why to choose laravel framework
Why to choose laravel frameworkWhy to choose laravel framework
Why to choose laravel frameworkBo-Yi Wu
 
Phalcon the fastest php framework 阿土伯
Phalcon   the fastest php framework 阿土伯Phalcon   the fastest php framework 阿土伯
Phalcon the fastest php framework 阿土伯Hash Lin
 
專案分層架構 twMVC#18
專案分層架構 twMVC#18專案分層架構 twMVC#18
專案分層架構 twMVC#18twMVC
 
第三方内容开发最佳实践
第三方内容开发最佳实践第三方内容开发最佳实践
第三方内容开发最佳实践taobao.com
 
專案啟動與環境設定
專案啟動與環境設定專案啟動與環境設定
專案啟動與環境設定Shengyou Fan
 
Asp.net mvc 6 新功能初探
Asp.net mvc 6 新功能初探Asp.net mvc 6 新功能初探
Asp.net mvc 6 新功能初探Gelis Wu
 

Was ist angesagt? (20)

使用 wagon + VS Code 輕鬆打造 Windows 平台 PHP/Laravel 開發環境
使用 wagon + VS Code 輕鬆打造 Windows 平台 PHP/Laravel 開發環境使用 wagon + VS Code 輕鬆打造 Windows 平台 PHP/Laravel 開發環境
使用 wagon + VS Code 輕鬆打造 Windows 平台 PHP/Laravel 開發環境
 
YUI 教學 - 前端工程開發實務訓練
YUI 教學 - 前端工程開發實務訓練YUI 教學 - 前端工程開發實務訓練
YUI 教學 - 前端工程開發實務訓練
 
从无阻塞并行脚本加载(Lab.js)到浏览器消息模型
从无阻塞并行脚本加载(Lab.js)到浏览器消息模型从无阻塞并行脚本加载(Lab.js)到浏览器消息模型
从无阻塞并行脚本加载(Lab.js)到浏览器消息模型
 
[Modern Web 2016] 讓你的 PHP 開發流程再次潮起來
[Modern Web 2016] 讓你的 PHP 開發流程再次潮起來[Modern Web 2016] 讓你的 PHP 開發流程再次潮起來
[Modern Web 2016] 讓你的 PHP 開發流程再次潮起來
 
TypeScript-twmvc#16
TypeScript-twmvc#16TypeScript-twmvc#16
TypeScript-twmvc#16
 
CodeIgniter 2.0.X
CodeIgniter 2.0.XCodeIgniter 2.0.X
CodeIgniter 2.0.X
 
How to choose web framework
How to choose web frameworkHow to choose web framework
How to choose web framework
 
啟動 Laravel 與環境設定
啟動 Laravel 與環境設定啟動 Laravel 與環境設定
啟動 Laravel 與環境設定
 
COSCUP 2016 Laravel 部署工作坊 - 部署指南
COSCUP 2016 Laravel 部署工作坊 - 部署指南COSCUP 2016 Laravel 部署工作坊 - 部署指南
COSCUP 2016 Laravel 部署工作坊 - 部署指南
 
模块化和组件化Css
模块化和组件化Css模块化和组件化Css
模块化和组件化Css
 
PHP 語法基礎與物件導向
PHP 語法基礎與物件導向PHP 語法基礎與物件導向
PHP 語法基礎與物件導向
 
基于Ivy ant的java构建初探
基于Ivy ant的java构建初探基于Ivy ant的java构建初探
基于Ivy ant的java构建初探
 
Model 設定與 Seeding
Model 設定與 SeedingModel 設定與 Seeding
Model 設定與 Seeding
 
Visual Studio Code 快速上手指南
Visual Studio Code 快速上手指南Visual Studio Code 快速上手指南
Visual Studio Code 快速上手指南
 
Why to choose laravel framework
Why to choose laravel frameworkWhy to choose laravel framework
Why to choose laravel framework
 
Phalcon the fastest php framework 阿土伯
Phalcon   the fastest php framework 阿土伯Phalcon   the fastest php framework 阿土伯
Phalcon the fastest php framework 阿土伯
 
專案分層架構 twMVC#18
專案分層架構 twMVC#18專案分層架構 twMVC#18
專案分層架構 twMVC#18
 
第三方内容开发最佳实践
第三方内容开发最佳实践第三方内容开发最佳实践
第三方内容开发最佳实践
 
專案啟動與環境設定
專案啟動與環境設定專案啟動與環境設定
專案啟動與環境設定
 
Asp.net mvc 6 新功能初探
Asp.net mvc 6 新功能初探Asp.net mvc 6 新功能初探
Asp.net mvc 6 新功能初探
 

Ähnlich wie 从无阻塞并行脚本加载(Lab.js)到浏览器消息模型

千呼萬喚始出來的Java SE 7
千呼萬喚始出來的Java SE 7千呼萬喚始出來的Java SE 7
千呼萬喚始出來的Java SE 7javatwo2011
 
EventProxy introduction - JacksonTian
EventProxy introduction - JacksonTianEventProxy introduction - JacksonTian
EventProxy introduction - JacksonTianJackson Tian
 
Event proxy introduction
Event proxy introductionEvent proxy introduction
Event proxy introductionmysqlops
 
Beyond rails server
Beyond rails serverBeyond rails server
Beyond rails serverMichael Chen
 
OPOA in Action -- 使用MagixJS简化WebAPP开发
OPOA in Action -- 使用MagixJS简化WebAPP开发OPOA in Action -- 使用MagixJS简化WebAPP开发
OPOA in Action -- 使用MagixJS简化WebAPP开发leneli
 
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 FundamentalsChieh Lin
 
Dynamic JS Loader
Dynamic JS LoaderDynamic JS Loader
Dynamic JS Loaderfeifeipan
 
非常靠谱 Html 5
非常靠谱 Html 5 非常靠谱 Html 5
非常靠谱 Html 5 Tony Deng
 
张所勇:前端开发工具推荐
张所勇:前端开发工具推荐张所勇:前端开发工具推荐
张所勇:前端开发工具推荐zhangsuoyong
 
GlassFish特性介绍
GlassFish特性介绍GlassFish特性介绍
GlassFish特性介绍Jim Jiang
 
Lazyload实践
Lazyload实践Lazyload实践
Lazyload实践Wu tianhao
 
2012 java two-desktop-appliction-using-j-ruby-with-swt
2012 java two-desktop-appliction-using-j-ruby-with-swt2012 java two-desktop-appliction-using-j-ruby-with-swt
2012 java two-desktop-appliction-using-j-ruby-with-swttka
 
常用开发工具介绍
常用开发工具介绍常用开发工具介绍
常用开发工具介绍haozes
 
D2-ETao-show
D2-ETao-showD2-ETao-show
D2-ETao-showleneli
 
Javascript primer plus
Javascript primer plusJavascript primer plus
Javascript primer plusDongxu Yao
 
互联网创业服务器运维工具集
互联网创业服务器运维工具集互联网创业服务器运维工具集
互联网创业服务器运维工具集zhen chen
 
钟志 第八期Web标准化交流会
钟志 第八期Web标准化交流会钟志 第八期Web标准化交流会
钟志 第八期Web标准化交流会Zhi Zhong
 
Docker Compose
Docker ComposeDocker Compose
Docker ComposeMiles Chou
 

Ähnlich wie 从无阻塞并行脚本加载(Lab.js)到浏览器消息模型 (20)

千呼萬喚始出來的Java SE 7
千呼萬喚始出來的Java SE 7千呼萬喚始出來的Java SE 7
千呼萬喚始出來的Java SE 7
 
EventProxy introduction - JacksonTian
EventProxy introduction - JacksonTianEventProxy introduction - JacksonTian
EventProxy introduction - JacksonTian
 
Event proxy introduction
Event proxy introductionEvent proxy introduction
Event proxy introduction
 
Beyond rails server
Beyond rails serverBeyond rails server
Beyond rails server
 
OPOA in Action -- 使用MagixJS简化WebAPP开发
OPOA in Action -- 使用MagixJS简化WebAPP开发OPOA in Action -- 使用MagixJS简化WebAPP开发
OPOA in Action -- 使用MagixJS简化WebAPP开发
 
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
 
Dynamic JS Loader
Dynamic JS LoaderDynamic JS Loader
Dynamic JS Loader
 
非常靠谱 Html 5
非常靠谱 Html 5 非常靠谱 Html 5
非常靠谱 Html 5
 
张所勇:前端开发工具推荐
张所勇:前端开发工具推荐张所勇:前端开发工具推荐
张所勇:前端开发工具推荐
 
GlassFish特性介绍
GlassFish特性介绍GlassFish特性介绍
GlassFish特性介绍
 
Lazyload实践
Lazyload实践Lazyload实践
Lazyload实践
 
Berserk js
Berserk jsBerserk js
Berserk js
 
Html5
Html5Html5
Html5
 
2012 java two-desktop-appliction-using-j-ruby-with-swt
2012 java two-desktop-appliction-using-j-ruby-with-swt2012 java two-desktop-appliction-using-j-ruby-with-swt
2012 java two-desktop-appliction-using-j-ruby-with-swt
 
常用开发工具介绍
常用开发工具介绍常用开发工具介绍
常用开发工具介绍
 
D2-ETao-show
D2-ETao-showD2-ETao-show
D2-ETao-show
 
Javascript primer plus
Javascript primer plusJavascript primer plus
Javascript primer plus
 
互联网创业服务器运维工具集
互联网创业服务器运维工具集互联网创业服务器运维工具集
互联网创业服务器运维工具集
 
钟志 第八期Web标准化交流会
钟志 第八期Web标准化交流会钟志 第八期Web标准化交流会
钟志 第八期Web标准化交流会
 
Docker Compose
Docker ComposeDocker Compose
Docker Compose
 

Mehr von Jackson Tian

D2_node在淘宝的应用实践_pdf版
D2_node在淘宝的应用实践_pdf版D2_node在淘宝的应用实践_pdf版
D2_node在淘宝的应用实践_pdf版Jackson Tian
 
D2_Node在淘宝的应用实践
D2_Node在淘宝的应用实践D2_Node在淘宝的应用实践
D2_Node在淘宝的应用实践Jackson Tian
 
Mobile webapp&v5 html5_min
Mobile webapp&v5 html5_minMobile webapp&v5 html5_min
Mobile webapp&v5 html5_minJackson Tian
 
Nodejs异步原理和缺陷 - 赵成
Nodejs异步原理和缺陷 - 赵成Nodejs异步原理和缺陷 - 赵成
Nodejs异步原理和缺陷 - 赵成Jackson Tian
 
Mongoskin - Guilin
Mongoskin - GuilinMongoskin - Guilin
Mongoskin - GuilinJackson Tian
 
MobileWebAppFramework_V5_design
MobileWebAppFramework_V5_designMobileWebAppFramework_V5_design
MobileWebAppFramework_V5_designJackson Tian
 
Why Nodejs Guilin Shanghai
Why Nodejs Guilin ShanghaiWhy Nodejs Guilin Shanghai
Why Nodejs Guilin ShanghaiJackson Tian
 
NodeJS快速服务端开发 朝沐金风 Shanghai
NodeJS快速服务端开发 朝沐金风 ShanghaiNodeJS快速服务端开发 朝沐金风 Shanghai
NodeJS快速服务端开发 朝沐金风 ShanghaiJackson Tian
 
Ruby vs Node ShiningRay Shanghai
Ruby vs Node ShiningRay ShanghaiRuby vs Node ShiningRay Shanghai
Ruby vs Node ShiningRay ShanghaiJackson Tian
 
Browser vs. Node.js Jackson Tian Shanghai
Browser vs. Node.js   Jackson Tian ShanghaiBrowser vs. Node.js   Jackson Tian Shanghai
Browser vs. Node.js Jackson Tian ShanghaiJackson Tian
 

Mehr von Jackson Tian (11)

D2_node在淘宝的应用实践_pdf版
D2_node在淘宝的应用实践_pdf版D2_node在淘宝的应用实践_pdf版
D2_node在淘宝的应用实践_pdf版
 
D2_Node在淘宝的应用实践
D2_Node在淘宝的应用实践D2_Node在淘宝的应用实践
D2_Node在淘宝的应用实践
 
(C)NodeJS
(C)NodeJS(C)NodeJS
(C)NodeJS
 
Mobile webapp&v5 html5_min
Mobile webapp&v5 html5_minMobile webapp&v5 html5_min
Mobile webapp&v5 html5_min
 
Nodejs异步原理和缺陷 - 赵成
Nodejs异步原理和缺陷 - 赵成Nodejs异步原理和缺陷 - 赵成
Nodejs异步原理和缺陷 - 赵成
 
Mongoskin - Guilin
Mongoskin - GuilinMongoskin - Guilin
Mongoskin - Guilin
 
MobileWebAppFramework_V5_design
MobileWebAppFramework_V5_designMobileWebAppFramework_V5_design
MobileWebAppFramework_V5_design
 
Why Nodejs Guilin Shanghai
Why Nodejs Guilin ShanghaiWhy Nodejs Guilin Shanghai
Why Nodejs Guilin Shanghai
 
NodeJS快速服务端开发 朝沐金风 Shanghai
NodeJS快速服务端开发 朝沐金风 ShanghaiNodeJS快速服务端开发 朝沐金风 Shanghai
NodeJS快速服务端开发 朝沐金风 Shanghai
 
Ruby vs Node ShiningRay Shanghai
Ruby vs Node ShiningRay ShanghaiRuby vs Node ShiningRay Shanghai
Ruby vs Node ShiningRay Shanghai
 
Browser vs. Node.js Jackson Tian Shanghai
Browser vs. Node.js   Jackson Tian ShanghaiBrowser vs. Node.js   Jackson Tian Shanghai
Browser vs. Node.js Jackson Tian Shanghai
 

从无阻塞并行脚本加载(Lab.js)到浏览器消息模型