<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 返還網(wǎng)
    隨筆-140  評論-11  文章-131  trackbacks-0

    Douglas Crockford談Ajax性能

    2008年12月25日,星期四
    這是Douglas Crockford在圣誕節(jié)前的一個講座。我覺得對于前端工程師來說算是一個“新年大片”。英文好的建議直接去看原文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標(biāo)題的注解。他提到“the client dose not need a copy of the database. it just needs, at any moment, just enough information to serve the user”,后端把所有數(shù)據(jù)都交給前端處理,后端是省事了,而瀏覽器端的性能則變的極差。“the client and the server are in a dialog, and we make the messages between them be as small as possible”,這是一個關(guān)鍵原則。just-in-time data delivery(按需傳輸數(shù)據(jù))。
    這 些道理其實盡人皆知,但在設(shè)計復(fù)雜的應(yīng)用時,在進行多人協(xié)作的項目時,仍然會犯這樣的錯誤。為什么?因為如果真的要實現(xiàn)一個客戶端和服務(wù)器端的高效對話, 服務(wù)器端的設(shè)計就會變的復(fù)雜,我充分理解后端工程師也要考慮他們的問題。但為了更高效率,后端多花一些心思是值得的,因為目前瀏覽器還是一個非常低效的應(yīng) 用平臺(這也是Google推出Chrome的原因),存在顯著的安全問題和性能問題。
    Crock舉的這個memoizer(緩存器)的例子非常經(jīng)典:
    var fibonacci = function(n){
    return n < 2 ? n :
    fibonacci(n - 1) + fibonacci(n - 2);
    };
    fibonacci(40);
    執(zhí)行自己 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);
    });
    優(yōu)化后的程序僅執(zhí)行了38次。”the key to optimization is work avoidance.” (優(yōu)化的關(guān)鍵是“逃避工作”的技巧)

    Crock提到兩種優(yōu)化思路:streamline和special casing

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

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

     

    “Avoid unnecessary displays or animation”很多產(chǎn)品經(jīng)理認為花哨的交互就是好的用戶體驗,或者就是認為它夠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.”(譯:如果這樣做能提高用戶的生產(chǎn)力或提升用戶體驗的價值,一個‘喔噻’的效果是價得的。但如果它的存在只是為了表明,我們能夠做到這一點, 我認為這是浪費我們的時間,這是浪費用戶的時間)
    重 點解決影響最大的性能問題。看似費話,其實在開發(fā)中避重就輕的事沒少干。關(guān)鍵首先要準(zhǔn)確的判斷出哪些環(huán)節(jié)是最大的癥結(jié)所在。The bottleneck tends to be the DOM interface — DOM is a really inefficient API.(譯: 瓶頸傾向于DOM接囗 - DOM是一個相當(dāng)?shù)托У腁PI),還會有reflow計算的問題。“So touch the DOM lightly, if you can.”怎么才能“touch lightly”,Crock告訴我們兩個技巧:一個是在創(chuàng)建的結(jié)點添加到DOM樹上之前對其進行操作,這樣不會有回流計算的問題。二是用 innerHTML,它只會跟DOM發(fā)生一次關(guān)系。
    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”不要調(diào)那些瀏覽器的怪異問題。建議首先是盡量繞開這些quirks,雖然通過一些技巧可以解決這些問題,但也許在其它瀏覽器上性能就會變 差。而且當(dāng)瀏覽器升級后修復(fù)了這個問題,之前所做的優(yōu)化可能會變得更糟。Crock建議不做短期優(yōu)化。
    短短三十多分鐘的講座細細品味的話可以引出很多思考。
    簡單總結(jié)一下:
    一是客戶端要輕。程序不要臃腫,不要把所有數(shù)據(jù)都交給前端處理
    二是代碼是基礎(chǔ)。尋求更好的算法,更好的設(shè)計模式
    三是借住工具,不憑直覺
    四是要抓重點。揪住主要問題解決
    五是DOM操作是瓶頸
    六是不要做短期優(yōu)化

    高性能的Ajax應(yīng)用-Julien Lecomte

    2007年12月21日,星期五

    高性能的Ajax應(yīng)用-Julien Lecomte

    第1部分 高性能的開發(fā)

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

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

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

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

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

    2.資源優(yōu)化
    -最小化CSS和Javascript文件。推薦使用YUI Compressor(http://developer.yahoo.com/yui/compressor)壓縮。遠離那些所謂的先進的壓縮方案,如Packer。
    -合并CSS和Javascript文件。在發(fā)布的時候合并(http://www.julienlecomte.net/blog/2007/09/16)或在運行的時候合并。
    -優(yōu)化圖片資源。如: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.優(yōu)化初始渲染(1):綜合技巧
    -Consider rendering the first view on the server
    -關(guān)閉你的HTML標(biāo)簽提高解析速度。參見http://msdn2.microsoft.com/en-us/library/ms533020.aspx#Close_Your_Tags
    -考慮盡早緩存。
    -下載基本的資源,延遲或按需下載其他資源。使用YUI ImageLoader。

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

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

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

    第3部分 高性能的Javascript

    1.減少符號查尋(1):范圍鏈
    -每次訪問變量時都會執(zhí)行查尋
    -變量從當(dāng)前范圍向上執(zhí)行查尋
    -因此,無論何時都在相同范圍中聲明和使用變量
    -完全不要使用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.優(yōu)化對象實例化
    -如果你需要創(chuàng)建很多對象,可以考慮添加成員到原型中,而不添加到單個對象的構(gòu)造器中。
    -這樣會減少內(nèi)存的消耗
    -然而會拖慢查尋查尋對象成員的速度

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

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

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

    7.緩存
    -在下面情況下應(yīng)用緩存是合理的:
    * 更低成本的獲取一個值
    * 值會被經(jīng)常讀取
    * 值不經(jīng)常改變
    -會增加內(nèi)存消耗(權(quán)衡)
    -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的長時間運行處理過程中,整個瀏覽器會被凍結(jié)
    -因此為了維持好的用戶體驗,確保Javascript一個線程在約300兆秒內(nèi)完成
    -你可以通過用setTimeout將長運行處理拆成的更小處理單元串起來執(zhí)行
    -更多見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.綜合技巧
    -簡單的操作符往往比相應(yīng)的方法要快
    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
    -無論何時分支條件都不改變的情況下,分支應(yīng)該在外面,不要在里面:
    不好的寫法:
    function fn () {
    if (…) {

    } else {

    }
    }

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

    第4部分 高性能的動態(tài)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);
    -它僅僅支持常規(guī)DOM方法和屬性的子集
    -IE實現(xiàn)DocumentFragment不服從W3C規(guī)范

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

    5.限制回流(Reflow)

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

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

    第6部分 高性能的Ajax

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

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

    3.綜合技巧
    -知道并發(fā)HTTP/1.1連接的最大數(shù)量
    -如果后端支持,支持多元的Ajax請求
    -Piggyback unsollicited notifications in a response to an Ajax request.
    -用JSON代替XML做為數(shù)據(jù)交換格式
    -推送,不要輪詢。使用COMET向瀏覽器發(fā)送實時的通知
    -考慮使用本地存儲器緩存數(shù)據(jù)。
    * IE的userData
    * Flash本地存儲
    * DOM:Storage(WHATWG持久存儲API, 已在Firefox2中實現(xiàn))
    * 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)  編輯  收藏 所屬分類: 網(wǎng)頁web前端技術(shù)
    主站蜘蛛池模板: 国产99精品一区二区三区免费 | 爱情岛论坛免费视频| 手机在线看永久av片免费| 亚洲春黄在线观看| 青青视频观看免费99| 99热亚洲色精品国产88| 在线观看免费成人| 天堂亚洲国产中文在线| 韩国免费三片在线视频| 国产亚洲精品免费| 亚洲午夜精品久久久久久浪潮| 三年在线观看免费观看完整版中文 | 四虎在线播放免费永久视频 | 国内精品免费久久影院| 亚洲精品你懂的在线观看| 成人无码a级毛片免费| 亚洲视频在线播放| 国产香蕉九九久久精品免费| 亚洲av第一网站久章草| 精品亚洲成α人无码成α在线观看 | 鲁大师在线影院免费观看 | 久久99精品视免费看| 亚洲精品视频免费看| 四虎影视www四虎免费| 美女又黄又免费的视频| 亚洲日韩精品射精日| 亚洲成人免费在线观看| 亚洲熟妇成人精品一区| 亚洲午夜AV无码专区在线播放| 久久免费观看国产99精品| 亚洲欧洲另类春色校园网站| 亚洲AⅤ无码一区二区三区在线| 国产综合免费精品久久久| 亚洲人成图片网站| 亚洲熟妇丰满多毛XXXX| 久久精品国产免费观看三人同眠| 亚洲国产区男人本色| 亚洲国产精品无码专区在线观看| 免费观看成人毛片a片2008| 成年免费大片黄在线观看com| 亚洲伊人久久大香线蕉苏妲己|