目錄結(jié)構(gòu) 正巧看到在送書,于是乎找了找自己博客上記錄過的一些東西來(lái)及其無(wú)恥的蹭書了~~~ 小廣告:更多內(nèi)容可以看我的博客 優(yōu)化循環(huán)如果現(xiàn)在有個(gè)一個(gè)
這里每次循環(huán)開始前都需要判斷i是否小于
這里多加了一個(gè)變量m用于存放
當(dāng)然我們可以使用while來(lái)替代:
這樣就可只使用一個(gè)變量了 運(yùn)算結(jié)果緩存由于JavaScript中的函數(shù)也是對(duì)象(JavaScript中一切都是對(duì)象),所以我們可以給函數(shù)添加任意的屬性。這也就為我們提供符合備忘錄模式的緩存運(yùn)算結(jié)果的功能,比如我們有一個(gè)需要大量運(yùn)算才能得出結(jié)果的函數(shù)如下:
如果其中不涉及隨機(jī),參數(shù)一樣時(shí)所返回的結(jié)果一致,我們就可以將運(yùn)算結(jié)果進(jìn)行緩存從而避免重復(fù)的計(jì)算:
這里將參數(shù)轉(zhuǎn)化為JSON字符串作為key,如果這個(gè)參數(shù)已經(jīng)被計(jì)算過,那么就直接返回,否則進(jìn)行計(jì)算。計(jì)算完畢后再添加入cache中,如果需要,可以直接查看cache的內(nèi)容: 這是一種典型的空間換時(shí)間的方式,由于瀏覽器的頁(yè)面存活時(shí)間一般不會(huì)很長(zhǎng),占用的內(nèi)存會(huì)很快被釋放(當(dāng)然也有例外,比如一些WEB應(yīng)用),所以可以通過這種空間換時(shí)間的方式來(lái)減少響應(yīng)時(shí)間,提升用戶體驗(yàn)。這種方式并不適用于如下場(chǎng)合: 不要在循環(huán)中創(chuàng)建函數(shù)這個(gè)很好理解,每創(chuàng)建一個(gè)函數(shù)對(duì)象是需要大批量空間的。所以在一個(gè)循環(huán)中創(chuàng)建函數(shù)是很不明智的,盡量將函數(shù)移動(dòng)到循環(huán)之前創(chuàng)建,比如如下代碼:
就可以修改為:
讓垃圾回收器回收那些不再需要的對(duì)象之前我曾在 淺談V8引擎中的垃圾回收機(jī)制 中講到了V8引擎如何進(jìn)行垃圾回收??梢詮闹锌吹剑绻L(zhǎng)時(shí)間保存對(duì)象,老生代中占用的空間將增大,每次在老生代中的垃圾回收過程將會(huì)相當(dāng)漫長(zhǎng)。而垃圾回收器判斷一個(gè)對(duì)象為活對(duì)象還是死對(duì)象,是按照是否有活對(duì)象或根對(duì)象含有對(duì)它的引用來(lái)判定的。如果有根對(duì)象或者活對(duì)象引用了這個(gè)對(duì)象,它將被判定為活對(duì)象。所以我們需要通過手動(dòng)消除這些引用來(lái)讓垃圾回收器對(duì)回收這些對(duì)象。 delete一種方式是通過 null另一種方式是通過將值設(shè)為null來(lái)消除引用。通過將變量或?qū)ο蟮膶傩栽O(shè)為null,可以消除引用,使原本引用的對(duì)象成為一個(gè)“孤島”,然后在垃圾回收的時(shí)候?qū)ζ溥M(jìn)行回收。這種方式不會(huì)改變對(duì)象的結(jié)構(gòu),比使用 全局對(duì)象另外需要注意的是,垃圾回收器認(rèn)為根對(duì)象永遠(yuǎn)是活對(duì)象,永遠(yuǎn)不會(huì)對(duì)其進(jìn)行垃圾回收。而全局對(duì)象就是根對(duì)象,所以全局作用域中的變量將會(huì)一直存在 事件處理器的回收在平常寫代碼的時(shí)候,我們經(jīng)常會(huì)給一個(gè)DOM節(jié)點(diǎn)綁定事件處理器,但有時(shí)候我們不需要這些事件處理器后,就不管它們了,它們默默的在內(nèi)存中保存著。所以在某些DOM節(jié)點(diǎn)綁定的事件處理器不需要后,我們應(yīng)當(dāng)銷毀它們。同時(shí)綁定的時(shí)候也盡量使用事件代理的方式進(jìn)行綁定,以免造成多次重復(fù)的綁定導(dǎo)致內(nèi)存空間的浪費(fèi),事件代理可見前端性能優(yōu)化(DOM操作篇) 閉包導(dǎo)致的內(nèi)存泄露JavaScript的閉包可以說(shuō)即是“天使”又是“魔鬼”,它“天使”的一面是我們可以通過它突破作用域的限制,而其魔鬼的一面就是和容易導(dǎo)致內(nèi)存泄露,比如如下情況:
這里,創(chuàng)建了一個(gè)閉包。使得返回的函數(shù)存儲(chǔ)在result中,而result函數(shù)能夠訪問其作用域內(nèi)的small對(duì)象和big對(duì)象。由于big對(duì)象和small對(duì)象都可能被訪問,所以垃圾回收器不會(huì)去碰這兩個(gè)對(duì)象,它們不會(huì)被回收。我們將上述代碼改成如下形式:
這樣,函數(shù)內(nèi)部只能夠訪問到hasSomeValue變量和small變量了,big沒有辦法通過任何形式被訪問到,垃圾回收器將會(huì)對(duì)其進(jìn)行回收,節(jié)省了大量的內(nèi)存。 慎用eval和withDouglas Crockford將eval比作魔鬼,確實(shí)在很多方面我們可以找到更好地替代方式。使用它時(shí)需要在運(yùn)行時(shí)調(diào)用解釋引擎對(duì) Douglas Crockford也不建議使用with,with會(huì)降低性能,通過with包裹的代碼塊,作用域鏈將會(huì)額外增加一層,降低索引效率 對(duì)象的優(yōu)化緩存需要被使用的對(duì)象JavaScript獲取數(shù)據(jù)的性能有如下順序(從快到慢):變量獲取 > 數(shù)組下標(biāo)獲?。▽?duì)象的整數(shù)索引獲取) > 對(duì)象屬性獲?。▽?duì)象非整數(shù)索引獲?。N覀兛梢酝ㄟ^最快的方式代替最慢的方式:
需要考慮,作用域鏈和原型鏈中的對(duì)象索引。如果作用域鏈和原型鏈較長(zhǎng),也需要對(duì)所需要的變量繼續(xù)緩存,否則沿著作用域鏈和原型鏈向上查找時(shí)也會(huì)額外消耗時(shí)間 緩存正則表達(dá)式對(duì)象需要注意,正則表達(dá)式對(duì)象的創(chuàng)建非常消耗時(shí)間,盡量不要在循環(huán)中創(chuàng)建正則表達(dá)式,盡可能多的對(duì)正則表達(dá)式對(duì)象進(jìn)行復(fù)用 考慮對(duì)象和數(shù)組在JavaScript中我們可以使用兩種存放數(shù)據(jù):對(duì)象和數(shù)組。由于JavaScript數(shù)組可以存放任意類型數(shù)據(jù)這樣的靈活性,導(dǎo)致我們經(jīng)常需要考慮何時(shí)使用數(shù)組,何時(shí)使用對(duì)象。我們應(yīng)當(dāng)在如下情況下做出考慮: 數(shù)組使用時(shí)的優(yōu)化
對(duì)象的拷貝需要注意的是,JavaScript遍歷對(duì)象和數(shù)組時(shí),使用
可修改為:
字面量代替構(gòu)造函數(shù)JavaScript可以通過字面量來(lái)構(gòu)造對(duì)象,比如通過 緩存AJAX曾經(jīng)聽過一個(gè)訪問時(shí)間比較(當(dāng)然不精確): 可看到訪問網(wǎng)絡(luò)資源是相當(dāng)慢的,而AJAX就是JavaScript訪問網(wǎng)絡(luò)資源的方式,所以對(duì)一些AJAX結(jié)果進(jìn)行緩存,可以大大減少響應(yīng)時(shí)間。那么如何緩存AJAX結(jié)果呢 函數(shù)緩存我們可以使用前面緩存復(fù)雜計(jì)算函數(shù)結(jié)果的方式進(jìn)行緩存,通過在函數(shù)對(duì)象上構(gòu)造cache對(duì)象,原理一樣,這里略過。這種方式是精確到函數(shù),而不精確到請(qǐng)求 本地緩存HTML5提供了本地緩存sessionStorage和localStorage,區(qū)別就是前者在瀏覽器關(guān)閉后會(huì)自動(dòng)釋放,而后者則是永久的,不會(huì)被釋放。它提供的緩存大小以MB為單位,比cookie(4KB)要大得多,所以我們可以根據(jù)AJAX數(shù)據(jù)的存活時(shí)間來(lái)判斷是存放在sessionStorage還是localStorage當(dāng)中,在這里以存儲(chǔ)到sessionStorage中為例(localStorage只需把第一行的
使用布爾表達(dá)式的短路在很多語(yǔ)言中,如果bool表達(dá)式的值已經(jīng)能通過前面的條件確定,那么后面的判斷條件將不再會(huì)執(zhí)行,比如如下代碼
這里首先會(huì)計(jì)算 使用原生方法在JavaScript中,大多數(shù)原生方法是使用C++編寫的,比js寫的方法要快得多,所以盡量使用諸如 字符串拼接在IE和FF下,使用直接 使用web workerweb worker是HTML5提出的一項(xiàng)新技術(shù),通過多線程的方式為JavaScript提供并行計(jì)算的能力,通過message的方式進(jìn)行相互之間的信息傳遞,我還沒有仔細(xì)研究過 JavaScript文件的優(yōu)化使用CDN在編寫JavaScript代碼中,我們經(jīng)常會(huì)使用庫(kù)(jQuery等等),這些JS庫(kù)通常不會(huì)對(duì)其進(jìn)行更改,我們可以將這些庫(kù)文件放在CDN(內(nèi)容分發(fā)網(wǎng)絡(luò)上),這樣能大大減少響應(yīng)時(shí)間 壓縮與合并JavaScript文件在網(wǎng)絡(luò)中傳輸JS文件,文件越長(zhǎng),需要的時(shí)間越多。所以在上線前,通常都會(huì)對(duì)JS文件進(jìn)行壓縮,去掉其中的注釋、回車、不必要的空格等多余內(nèi)容,如果通過uglify的算法,還可以縮減變量名和函數(shù)名,從而將JS代碼壓縮,節(jié)約傳輸時(shí)的帶寬。另外經(jīng)常也會(huì)將JavaScript代碼合并,使所有代碼在一個(gè)文件之中,這樣就能夠減少HTTP的請(qǐng)求次數(shù)。合并的原理和sprite技術(shù)相同 使用Application Cache緩存這個(gè)在之前的文章前端性能優(yōu)化(Application Cache篇)中已有描述,就不贅述了 |
|