天天看點

Web開發中你注意這些前台開發問題了嗎?(前台構架篇)

     Web2.0帶給我們更好的使用者體驗和更炫更酷的效果,javascript,flash, Silverlight都是躍躍欲試。目前應用最多的還是javascript,是以你會經常看到很多web2.0網站有n多的js和css,這時管理這些檔案和如此多的代碼怎麼提性能提升的問題也來了。以下就來講講我目前想到的一些問題吧。

       1.js和css引用時如何做到讓請求進行并發下載下傳。

       我們通過firebug,就會發現通過link和script标記在頁面上的引用資源每個請求都是以一個隊列形式排隊等候,一個資源下載下傳完成後才會下載下傳别外一個請求資源。它不像我們頁面裡面的圖檔(img标記和樣式中引用的圖檔,樣式裡面引用的圖檔必須等到css檔案加載完畢後才能下載下傳圖檔),可以并發下載下傳資源檔案。YSlow曾經對Web站點優化中提出,盡量把css放在head中(樣式突然在其它資源下載下傳完畢後才展現,那太有戲劇性了),但是有點搞不明白,為什麼浏覽對css加載也是一個隊列,難道怕在樣式中有重名部份的沖突?YSlow還提出過把js放在頁面的尾部,那樣的話整個頁面下載下傳js資源差不多在onload完在。這點很是深有體會,當你的script放在head的時候,整個頁面展現都得script一個個加載完畢再發生,這直接影響着Web性能,我想比網站的速度比使用者體驗來得更重要吧,是以我們應該把js放在尾部。那麼是不是說直接放在尾部就好了呢?我想還有一點可以優化的,就是讓其并發下載下傳。那麼如何解決這些資源的并發下載下傳問題呢?

       我的方法是通過動态追加dom的方法(appendChild,動态追加link和script節點标記到head下)。使用這種方式,我們會發現我們的隊列突然變得成了百米沖刺了,一聲哨下,都沖向終點了(當然每個并發請求數肯定還是有一定限制的)。不過在ie下appendChild這種方法在window.onload事件無法引用資源的函數,是以在ie時我用docoument.write去輸出(ie下用document.write也是并發下載下傳,而firefox是不行的)。是以通常在引用檔案的時候使用include的方法,以下列出include代碼。

<code>var $include=function(file, callback){     var isScript=file.indexOf(".css")==-1;     var attLink,path,extName="";     if(isScript){         attLink="src";         path=COREJSPATH;         scripts = $tag("script");         if(file.indexOf(".js")==-1) extName=".js";     }else{         scripts = $tag("link");         attLink="href";         path=CORECSSPATH;     }     if(file.indexOf("/")==-1){         file=path+file+extName;     }     for (var i = 0; i &lt; scripts.length; i++) {         if(scripts[i][attLink]==file){             return;         }     }     var fileref;     if (isScript){ //If object is a js file         if(window.ie){             fileref="script"+$time;             document.write("&lt;script src=\""+file+"\" id=\""+fileref+"\" type=\"text/javascript\"&gt;&lt;/script&gt;");         }else{             fileref=$create('script');             fileref.setAttribute("type","text/javascript");             fileref.setAttribute("src", file);             document.head.appendChild(fileref);         }     }     else { //If object is a css file         if(window.ie){             fileref="script"+$time;             document.write("&lt;link rel=\"stylesheet\" rev=\"stylesheet\" href=\""+f+"\"  id=\""+fileref+"\"  type=\"text/css\" media=\"screen\"/&gt;");         }else{             fileref=$create("link");             fileref.setAttribute("rel", "stylesheet");             fileref.setAttribute("type", "text/css");             fileref.setAttribute("href", file);             document.head.appendChild(fileref);         }     }     if(callback) {         fileref=$(fileref);         addEvent(fileref,'load',callback);         fileref.onreadystatechange = function(){             if(this.readyState=="loaded" || this.readyState=="complete"){                 callback();             }         };     } };</code>

<code>注:</code>

<code></code>

<code>1.CORECSSPATH(目前css存放的相對路徑),COREJSPATH(目前js存放的相對路徑),用這個原因主要是路徑問題,這個稍後再講。</code>

<code>2.callback是當檔案加載完成後再調用方法。</code>

<code>3.順便說一下我主要用mootools的一些函數</code>

<code>   2.我們的js檔案管理及引用太講究了,侵入性太強了,一個小心把順序弄錯或者依賴沒引用那就慘遭了,如果像有C#的using引用多好呀!</code>

<code>項目一天一天在擴大,此時發現已經有一大堆js檔案了,問題就來了——管理這些檔案依賴和順序很麻煩。js類庫中可能存在着依賴關系,每個引用都得知道該類的依賴關系然後再寫入&lt;script src="你的js檔案" type="text/javascript"&gt;&lt;/script&gt;,而且說不定你的js有裝載前的依賴關系(也就是說引用一個js前,需要把某個js放在你的引用的那個js前面),不然你運作結果肯定是error,是以我們急需管理這樣一些類的解決方案,這方面看到JSI好像做的挺不錯的。(JSI還沒深入研究,不太懂其原理,看似好複雜)</code>

<code>js的依賴關系示例(引自JSI的文檔說明)</code>

<code>有3個類:動物(Animal),貓(Cat),老鼠(Mouse);</code>

<code>他們有如下依賴關系:</code>

<code>貓、鼠 裝載前依賴動物類(裝載這兩個類時,需要建立動物執行個體作為其原型;該操作必須在裝載時完成,為裝載前依賴)</code>

<code>貓鼠裝載後,在使用過程中,互相依賴(貓鼠的行為中需要判别對方的行為,使用到了互相的引用,為互相裝載後依賴)。</code>

<code>     可表示為如下圖例:紅色代表裝載前依賴,淺綠色表示裝載後依賴:</code>

<code>     </code>

<code>來說說我的想法(目前還未實作),最好存在一個依賴關系的配置檔案,而且所有的依賴關系都存放在一個配置檔案中并說明依賴關系(呵呵,最好vs自動能生成關系),我看到JSI好像每個依賴得寫一個__package___.js檔案,那樣是不是麻煩了?(呵呵,不太懂)</code>

<code>   3.關于路徑問題。</code>

<code>js,css的路徑管理也是我們管理的一部份,哪天我們的頁面換了個檔案夾位置,就得改代碼裡的路徑那實在是太糟糕了。是以我用上面的$include方法,隻要你的核心js檔案路徑确定,其它路徑也随之确定(用$include方法引進的資源檔案)。如果你想通過改變檔案位置後不用改路徑的話,那麼通過核心檔案在伺服器輸出核心js ,那問題也就迎刃而解了(圖檔的路徑也是一道理,是以w3c好像要取消img标記,統一放css中)。但是這樣做會産生對某種開發語言的依賴,不知道園子裡的朋友有沒有更好的解決辦法?</code>

<code>   4.關于js和css的緩存。</code>

<code>我的解決辦法是:通過你的核心部份的js後加參數(随後include進來的js後面都給其定意和核心js一樣的參數),而如果你想所有控制所有頁面,隻能在伺服器端輸出核心腳本(同路徑問題的伺服器端輸出)。</code>

<code>   5.如何減小多張圖檔的連接配接數</code>

<code>可以合并一張圖檔,用css樣式定位。如:</code>

<code>.afirst,.alast,.anext,.apre,.nnext,.nlast,.nfirst,.npre{background:url(imgs/grid/gridbg.gif) 0px -116px;}</code>

<code>.anext{background-position:0px -153px;}</code>

<code>.alast{background-position:0px -221px;}</code>

<code>.apre{background-position:0px -185px;}</code>

<code>.nnext{background-position:0px -135px;}</code>

<code>.nlast{background-position:0px -200px;}</code>

<code>.nfirst{background-position:0px -97px;}</code>

<code>.npre{background-position:0px -169px;}</code>

<code>其實上面圖檔是同一張,隻是定位在不同位置吧!(css的路徑引用圖檔的路徑好像比js好)</code>

<code>上而合并一張圖檔還有一個好處是,比如當你按鈕可能onmouseover時一一張圖檔,而onmouserout又是一另張圖檔,使用者滑鼠經過就會有感覺閃了一下,如果網速慢還要再去下載下傳那個圖檔的過程,這是呈現的是一片空明(呵呵,在一定程度上提升使用者體驗)</code>

<code>  6.站點釋出後css,js壓縮</code>

<code>我的想法是這樣的(沒實作),當我們的vs在生成網站的時候可以自動将js或者css自動壓縮 (當然可能還是會遇到點問題的,因為很有可能js壓縮後出現問題,你在寫js的時可能會少了一個分号,那樣必定會造成出錯)</code>

<code>  7.按需裝載和延遲裝載問題</code>

<code>上面如果我用$include引進檔案還得在window.onload事件裡面去執行,如果能在$include下面的代碼能可引用包含進來的檔案的function的話,那就可以實作按需裝載的過程了。可是通常這種解決辦法是通過一種同步的阻塞式的裝載過程,使用者體驗很差(電腦像當機一樣了)。JSI号稱可以延遲裝載這個過程,不知道這個過程是怎麼實作的。</code>

<code> </code>

<code>本文轉自 netcorner 部落格園部落格,原文連結: http://www.cnblogs.com/netcorner/archive/2008/08/04/1259800.html  ,如需轉載請自行聯系原作者</code>

繼續閱讀