<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    http://www.tkk7.com/ebecket 返還網
    隨筆-140  評論-11  文章-131  trackbacks-0

    Douglas Crockford談Ajax性能

    2008年12月25日,星期四
    這是Douglas Crockford在圣誕節前的一個講座。我覺得對于前端工程師來說算是一個“新年大片”。英文好的建議直接去看原文http://ericmiraglia.com/blog/?p=140感謝Eric Miraglia提供了完整的文字記錄。
    Crock先用<記憶碎片 >這部電影作為引子。我還沒看過,一定要找來看看。
    如 果要向不太了解JSON的解釋JSON為什么好Crock這句話說的很清楚“A JSON message is less work for the server to generate, it moves much faster on the wire because it’s smaller, it’s less work for the browser to parse and render than an HTML document.”
    “The page is an application with a data connection to a server.”Crock對Ajax Revolution標題的注解。他提到“the client dose not need a copy of the database. it just needs, at any moment, just enough information to serve the user”,后端把所有數據都交給前端處理,后端是省事了,而瀏覽器端的性能則變的極差。“the client and the server are in a dialog, and we make the messages between them be as small as possible”,這是一個關鍵原則。just-in-time data delivery(按需傳輸數據)。
    這 些道理其實盡人皆知,但在設計復雜的應用時,在進行多人協作的項目時,仍然會犯這樣的錯誤。為什么?因為如果真的要實現一個客戶端和服務器端的高效對話, 服務器端的設計就會變的復雜,我充分理解后端工程師也要考慮他們的問題。但為了更高效率,后端多花一些心思是值得的,因為目前瀏覽器還是一個非常低效的應 用平臺(這也是Google推出Chrome的原因),存在顯著的安全問題和性能問題。
    Crock舉的這個memoizer(緩存器)的例子非常經典:
    var fibonacci = function(n){
    return n < 2 ? n :
    fibonacci(n - 1) + fibonacci(n - 2);
    };
    fibonacci(40);
    執行自己 331,160,280 次
    var memoizer = function(memo, fundamental){
    var shell = function(n){
    var result = memo[n];
    if(typeof result !== ‘number’){
    result = fundamental(shell, n);
    memo[n] = result;
    }
    return result;
    }
    return shell;
    }
    var fibonacci = memoizer([0, 1], function(recur, n){
    return recur(n - 1) + recur(n - 2);
    });
    優化后的程序僅執行了38次。”the key to optimization is work avoidance.” (優化的關鍵是“逃避工作”的技巧)

    Crock提到兩種優化思路:streamline和special casing

    streamline(簡 化為使效率更高):更換算法(選擇更好的算法)、逃避工作、清除冗余代碼(項目反復修改每次只是增加,往往忽略清除沒用的代碼)而且”These things are always good to do”這些事情應該一直去做而不是等到出現性能問題之后再解決。

    special casing理解成特別包裝更好一些。為了解決某些特別需求在原有代碼基礎上所做的包裝,優其是對公共組件。會導致冗余代碼越來越多,增加代碼的 size,同時還會增加更多的測試路徑(如果代碼要進行白盒測試,無疑測試成本將增加很多)。要知道產品的需求永遠是善變的。處理這種特殊需求可以寫一些 “適配器”或“橋接器”,不用的話就直接拿掉。

     

    “Avoid unnecessary displays or animation”很多產品經理認為花哨的交互就是好的用戶體驗,或者就是認為它夠shiny,殊不知它帶來的負面影響遠比它的作用要大的多。 Crock是這么說的“A ‘wow’ effect is definitely worthwhile if it improves the user’s productivity, or improves the value of the experience to user.If it’s there just to show that we can do that, I think it’sa waste of our time, it’sa waste of the user’s time.”(譯:如果這樣做能提高用戶的生產力或提升用戶體驗的價值,一個‘喔噻’的效果是價得的。但如果它的存在只是為了表明,我們能夠做到這一點, 我認為這是浪費我們的時間,這是浪費用戶的時間)
    重 點解決影響最大的性能問題。看似費話,其實在開發中避重就輕的事沒少干。關鍵首先要準確的判斷出哪些環節是最大的癥結所在。The bottleneck tends to be the DOM interface — DOM is a really inefficient API.(譯: 瓶頸傾向于DOM接囗 - DOM是一個相當低效的API),還會有reflow計算的問題。“So touch the DOM lightly, if you can.”怎么才能“touch lightly”,Crock告訴我們兩個技巧:一個是在創建的結點添加到DOM樹上之前對其進行操作,這樣不會有回流計算的問題。二是用 innerHTML,它只會跟DOM發生一次關系。
    var d = document.createElement(”div”);
    d.style.height = ‘100px’;
    d.style.border = ‘1px solid red’;
    d.style.color = ‘green’;
    …(該辦的事先辦完)…
    //最后再添加到dom樹中
    document.body.appendChild(d);

    “Don’t Tune For Quirks”不要調那些瀏覽器的怪異問題。建議首先是盡量繞開這些quirks,雖然通過一些技巧可以解決這些問題,但也許在其它瀏覽器上性能就會變 差。而且當瀏覽器升級后修復了這個問題,之前所做的優化可能會變得更糟。Crock建議不做短期優化。
    短短三十多分鐘的講座細細品味的話可以引出很多思考。
    簡單總結一下:
    一是客戶端要輕。程序不要臃腫,不要把所有數據都交給前端處理
    二是代碼是基礎。尋求更好的算法,更好的設計模式
    三是借住工具,不憑直覺
    四是要抓重點。揪住主要問題解決
    五是DOM操作是瓶頸
    六是不要做短期優化

    高性能的Ajax應用-Julien Lecomte

    2007年12月21日,星期五

    高性能的Ajax應用-Julien Lecomte

    第1部分 高性能的開發

    1.為高性能計劃和設計
    -從每一天開始就要計劃高性能
    -跟產品經理和設計師緊密的合作
    -理解設計的基本原理
    -設計和性能之前做解釋和權衡
    -提供選擇和展示各種可能(原型)
    -挑戰自己,實現有挑戰性的設計(不要只說“不”)
    -為了簡化設計和交互,有時候需要妥協

    2.高性能工程開發:一些基本規則
    -少就是多。不要做任何不必要的事。直到變得絕對重要,否則不要做。
    -打破規則。只能在迫不得以的情況下,才能妥協并打破最佳做法。
    -在提升可以感覺到的性能上下功夫。

    3.衡量性能
    -使用用戶真實環境測試
    -在開發中,profile你的代碼
    -使用自動的profiling/性能測試
    -保持功能執行的歷史數據
    -在產品中考慮保留一些(少量的)profiling代碼

    第2部分 高性能的頁面下載

    1.Yahoo!的14條性能原則
    一個頁面工作于3(有時是重疊的)個階段-下載,渲染,運行。14條原則大部分作用于第1個階段。

    2.資源優化
    -最小化CSS和Javascript文件。推薦使用YUI Compressor(http://developer.yahoo.com/yui/compressor)壓縮。遠離那些所謂的先進的壓縮方案,如Packer。
    -合并CSS和Javascript文件。在發布的時候合并(http://www.julienlecomte.net/blog/2007/09/16)或在運行的時候合并。
    -優化圖片資源。如:PngCrush(http://pmt.sourceforge.net/pngcrush)、PngOptimizer(http://psydk.org/PngOptimizer.php)等。

    3.減小非壓縮代碼的大小
    -下載和解析HTML、CSS、Javascript代碼的成本是很高的。
    -用簡練寫法和寫更少的代碼
    -用好Javascript庫
    -在考慮將大的Javascript文件拆成小的文件(bundle)時,解析和編譯腳本時要花費大量額外的時間
    -按需下載代碼(HTML、CSS、Javascript),如,Lazy Loading
    * 參見,http://ajaxpatterns.org/On-Demand_Javascript
    * 使用 YUI Loader
    * Dojo的package system
    * JSAN的Import System

    4.優化初始渲染(1):綜合技巧
    -Consider rendering the first view on the server
    -關閉你的HTML標簽提高解析速度。參見http://msdn2.microsoft.com/en-us/library/ms533020.aspx#Close_Your_Tags
    -考慮盡早緩存。
    -下載基本的資源,延遲或按需下載其他資源。使用YUI ImageLoader。

    5.優化初始渲染(2):不要一直等onload
    -大部分DOM操作可以在onload事件觸發前完成
    -如果你需要控制你的初始化代碼,可以直接寫在里,并把它放在靠近的位置
    -否則,使用YUI事件組件中的onDOMReady方法
    YAHOO.util.Event.onDOMReady(function () {
    // Do something here…
    // e.g., attach event handlers.
    });

    6.優化初始渲染(3):在頁面下載后,再下載腳本。
    -一個好的網站應該在Javascript失效下功能也應該是完整的
    -因此,你可以延遲下載腳本
    -這樣做對下載其他資源(樣式表、圖片等)是有好處的
    -這樣做使網站下載更快

    7.優化初始渲染(4):有條件的預下載
    -預下載潛在的資源(Javascript、CSS、圖片等)真的可以增強用戶體驗。
    -可是,在什么時候進行功妙的預下載是關鍵,否則,預下載會影響用戶體驗。
    -參見http://www.sitepoint.com/article/web-site-optimization-steps/3
    -參見http://search.yahoo.com

    第3部分 高性能的Javascript

    1.減少符號查尋(1):范圍鏈
    -每次訪問變量時都會執行查尋
    -變量從當前范圍向上執行查尋
    -因此,無論何時都在相同范圍中聲明和使用變量
    -完全不要使用with,它會阻止編譯器生成代碼時訪問本地變量的速度(因為首先要遍歷原型鏈,然后是范圍鏈等)
    -緩存外部變量到本地變量。
    不好的寫法:
    var arr = …;
    var globalVar = 0;
    (function () {
    var i;
    for (i = 0; i < arr.length; i++) {
    globalVar++;
    }
    })();

    好的寫法:
    var arr = …;
    var globalVar = 0;
    (function () {
    var i, l, localVar;
    l = arr.length;
    localVar = globalVar;
    for (i = 0; i < l; i++) {
    localVar++;
    }
    globalVar = localVar;
    })();

    2.減少符號查尋(2):原型鏈
    -訪問主對象上的成員的速度比訪問原型鏈上的成員的速度快25%
    -原型鏈越長查尋越慢
    function A () {}
    A.prototype.prop1 = …;

    function B () {
    this.prop2 = …;
    }

    B.prototype = new A();
    var b = new B();//(譯者:prop2為b的主對象成員,而prop1是原型鏈上的成員)

    3.優化對象實例化
    -如果你需要創建很多對象,可以考慮添加成員到原型中,而不添加到單個對象的構造器中。
    -這樣會減少內存的消耗
    -然而會拖慢查尋查尋對象成員的速度

    4.不要使用eval
    -傳字符串到eval中,需要編譯和解釋,相當的慢!
    -完全不要傳一個字符串到setTimeout和setInterval中。可以使用匿名函數代替。
    setTimeout(function () {
    // Code to execute on a timeout
    }, 50);
    -完全不要eval做為方法的構造器。

    5.優化字符串連接
    -在IE(JScript)中,連接兩個字符串會導致一個新的字符串被重新分配資源,同時兩個原字符串被復制:
    var s = “xxx” + “yyy”;
    s += “zzz”;
    -因此在IE中,添加字符串到數組中然后再用Array.join連接比直接用+連接快很多(不要用在簡單的連接中)
    -其他Javascript引擎(WebKit、SpiderMonkey)已經對字符串連接做了優化
    -使用YUI Compressor!

    6.優化正則表達式
    -盡量不要用RegExp構造,除非你的正則表達式需要實時創建。
    -使用test方法測試一個pattern(exec方法會有小的性能問題)
    -使用非捕獲組(?:)
    -保持pattern的簡單

    7.緩存
    -在下面情況下應用緩存是合理的:
    * 更低成本的獲取一個值
    * 值會被經常讀取
    * 值不經常改變
    -會增加內存消耗(權衡)
    -Memoization:
    Module Pattern:
    var fn = (function () {
    var b = false, v;
    return function () {
    if (!b) {
    v = …;
    b = true;
    }
    return v;
    };
    })();

    Store value in function object:
    function fn () {
    if (!fn.b) {
    fn.v = …;
    fn.b = true;
    }
    return fn.v;
    }

    Lazy function definition:
    var fn = function () {
    var v = …;
    return (fn = function () {
    return v;
    })();
    };

    8.如何控制長時間運行處理的Javascript
    -在Javascrit的長時間運行處理過程中,整個瀏覽器會被凍結
    -因此為了維持好的用戶體驗,確保Javascript一個線程在約300兆秒內完成
    -你可以通過用setTimeout將長運行處理拆成的更小處理單元串起來執行
    -更多見http://www.julienlecomte.net/blog/2007/10/28/
    -例子http://www.julienlecomte.net/blogfiles/javascript/long-running-js-process.html
    function doSomething (callbackFn) {
    // Initialize a few things here…
    (function () {
    // Do a little bit of work here…
    if (termination condition) {
    // We are done
    callbackFn();
    } else {
    > // P
    rocess next chunk
    setTimeout(arguments.callee, 0);
    }
    })();
    }

    9.綜合技巧
    -簡單的操作符往往比相應的方法要快
    c = Math.min(a, b);
    c = a < b ? a : b;//更快

    myArray.push(value);
    myArray[myArray.length] = value;//比上面快
    myArray[idx++] = value;//比上面快

    -避免使用try…catch在影響性能的部分:
    不好的寫法:
    var i;
    for (i = 0; i < 100000; i++) {
    try {

    } catch (e) {

    }
    }
    好的寫法:
    var i;
    try {
    for (i = 0; i < 100000; i++) {

    }
    } catch (e) {

    }
    -If possible, avoid for…in in performance-critical sections
    -無論何時分支條件都不改變的情況下,分支應該在外面,不要在里面:
    不好的寫法:
    function fn () {
    if (…) {

    } else {

    }
    }

    好的寫法:
    var fn;
    if (…) {
    fn = function () {…};
    } else {
    fn = function () {…};
    }

    第4部分 高性能的動態HTML

    1.文檔樹的修改:使用innerHTML
    注意事項http://www.julienlecomte.net/blog/2007/12/38

    2.文檔樹的修改:使用cloneNode
    注意:expando屬性或附加的事件會丟失

    3.文檔樹的修改:使用DocumentFragment
    -DocumentFragment(DOM Level 1 Core)是一個輕量級的文檔對象
    var i, j, el, table, tbody, row, cell, docFragment;
    docFragment = document.createDocumentFragment();
    el = document.createElement(”div”);
    docFragment.appendChild(el);
    table = document.createElement(”table”);
    el.appendChild(table);
    tbody = document.createElement(”tbody”);
    table.appendChild(tbody);
    for (i = 0; i < 1000; i++) {

    }
    document.body.appendChild(docFragment);
    -它僅僅支持常規DOM方法和屬性的子集
    -IE實現DocumentFragment不服從W3C規范

    4.限制事件柄的個數
    -附加事件到上百個元素上的成本很高
    -多個事件柄會增加潛在的內存漏洞
    -解決方案:使用事件委托機制,一種依靠事件冒泡的機制

    5.限制回流(Reflow)

    第5部分 高性能的布局和CSS

    綜合技巧
    -使用CSS Sprites
    -避免使用Javascript布局
    -避免使用IE表達式
    -避免使用IE濾鏡(或盡可能少用)
    -優化Table布局
    -優化CSS選擇器http://developer.mozilla.org/en/docs/Writing_Efficient_CSS

    第6部分 高性能的Ajax

    1.綜合技巧
    -完全不要使用同步的XMLHttpRequest。參見http://yuiblog.com/blog/2006/04/04/synchronous-v-asynchronous
    -編程處理網絡超時
    -解決方案:使用YUI Connection Manager
    var callback = {
    success: function () { /* Do something */ },
    failure: function () { /* Do something */ },
    timeout: 5000
    };
    YAHOO.util.Connect.asyncRequest(”GET”, url, callback);

    2.提升可以感覺到的網絡延遲體驗
    -如果數據在提交到服務器端之前經過本地校驗,通常請求的成功率達99.9%
    -因此,為了優化用戶體驗,我們可以采用下面的Pattern:
    * 當請求發出時要更新UI
    * Lock the UI/data structures with the finest possible granularity.
    * 讓用戶知道發生了什么事
    * 讓用戶知道為什么UI被鎖定
    * 當成功返回結果后要及時解除鎖定
    * 要用優雅的方式處理錯誤

    3.綜合技巧
    -知道并發HTTP/1.1連接的最大數量
    -如果后端支持,支持多元的Ajax請求
    -Piggyback unsollicited notifications in a response to an Ajax request.
    -用JSON代替XML做為數據交換格式
    -推送,不要輪詢。使用COMET向瀏覽器發送實時的通知
    -考慮使用本地存儲器緩存數據。
    * IE的userData
    * Flash本地存儲
    * DOM:Storage(WHATWG持久存儲API, 已在Firefox2中實現)
    * Google Gears
    * 其它

    第7部分 性能工具

    -YSlow? http://developer.yahoo.com/yslow
    -Task Manager
    -IE Leak Detector a.k.a Drip [ http://www.outofhanwell.com/ieleak/ ]
    -Stopwatch profiling
    * AjaxView [ http://research.microsoft.com/projects/ajaxview/ ]
    * JsLex [ http://rockstarapps.com/pmwiki/pmwiki.php?n=JsLex.JsLex ]
    * YUI profiler [ http://developer.yahoo.com/yui/profiler/ ]
    -Venkman or Firebug Profiler [ http://www.getfirebug.com/ ]

    (原文:http://yuiblog.com/blog/2007/12/20/video-lecomte/

    posted on 2010-02-28 23:53 becket_zheng 閱讀(254) 評論(0)  編輯  收藏 所屬分類: 網頁web前端技術
    主站蜘蛛池模板: 亚洲色图黄色小说| 亚洲嫩模在线观看| 亚洲av无码一区二区三区四区| av无码久久久久不卡免费网站| 亚洲第一区视频在线观看| 少妇太爽了在线观看免费视频| 亚洲精品视频在线| 97视频免费在线| 亚洲精品无码人妻无码| 日产乱码一卡二卡三免费| 国产成人亚洲精品播放器下载| 免费**毛片在线播放直播| 97在线视频免费公开视频| 亚洲视频在线观看地址| 国产99视频精品免费观看7| 亚洲国产成人久久一区二区三区 | 亚洲香蕉在线观看| 91在线品视觉盛宴免费| 在线播放亚洲精品| 亚洲色欲久久久综合网东京热| 久久aa毛片免费播放嗯啊| 亚洲国产精品综合福利专区| 在线免费观看色片| 亚州**色毛片免费观看| 亚洲va在线va天堂va不卡下载 | 国产亚洲Av综合人人澡精品| 中文字幕亚洲一区| 亚欧在线精品免费观看一区| 亚洲欧美乱色情图片| 亚洲人成网站观看在线播放| 久久aⅴ免费观看| 日韩欧美亚洲国产精品字幕久久久| 国产国拍亚洲精品福利 | 亚洲精品无码久久毛片波多野吉衣| 国产在线观看片a免费观看| 黄色免费网址在线观看| 亚洲avav天堂av在线不卡| 波多野结衣久久高清免费 | 在线观看免费视频一区| 亚洲国产视频一区| 亚洲第一区在线观看|