成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

個(gè)人常用JavaScript及React常用優(yōu)化總結(jié)

yuanxin / 773人閱讀

摘要:插件性能優(yōu)化及個(gè)人常用優(yōu)化方法經(jīng)常會(huì)觸發(fā)視覺(jué)變化。作用域鏈指的是當(dāng)前作用于下可用變量的集合,它在各種主流瀏覽器中至少包含兩個(gè)部分局部變量的集合和全局變量的集合。在考慮優(yōu)化時(shí),數(shù)值和變量的性能差不多,并且速度顯著優(yōu)于對(duì)象屬性和數(shù)組元素。

JavaScript 插件性能優(yōu)化及個(gè)人react常用優(yōu)化方法

JavaScript 經(jīng)常會(huì)觸發(fā)視覺(jué)變化。有時(shí)是直接通過(guò)樣式操作,有時(shí)是會(huì)產(chǎn)生視覺(jué)變化的計(jì)算,例如搜索數(shù)據(jù)或?qū)⑵渑判?。時(shí)機(jī)不當(dāng)或長(zhǎng)時(shí)間運(yùn)行的 JavaScript 可能是導(dǎo)致性能問(wèn)題的常見(jiàn)原因。您應(yīng)當(dāng)設(shè)法盡可能減少其影響。

JavaScript 性能分析可以說(shuō)是一門藝術(shù),因?yàn)槟帉懙?JavaScript 代碼與實(shí)際執(zhí)行的代碼完全不像?,F(xiàn)代瀏覽器使用 JIT 編譯器和各種各樣的優(yōu)化和技巧來(lái)嘗試為您實(shí)現(xiàn)盡可能快的執(zhí)行,這極大地改變了代碼的動(dòng)態(tài)。

注:如果您真的想了解 JIT 的實(shí)例,應(yīng)當(dāng)查看 Vyacheslav Egorov 提供的 IRHydra2。它顯示了當(dāng) Chrome 的 JavaScript 引擎 V8 對(duì) JavaScript 代碼進(jìn)行優(yōu)化時(shí),JavaScript 代碼的中間狀態(tài)。

盡管如此,您肯定還是可以做一些事情來(lái)幫助您的應(yīng)用很好地執(zhí)行 JavaScript。但 Javascript 性能優(yōu)化絕不是一種書面的技術(shù),借鑒別人的意見(jiàn)和自己平時(shí)項(xiàng)目的總結(jié)給出以下幾條建議:

變量問(wèn)題

當(dāng)一個(gè)變量被引用的時(shí)候,JavaScript將在作用域鏈中的不同成員中查找這個(gè)變量。作 用域鏈指的是當(dāng)前作用于下可用變量的集合,它在各種主流瀏覽器中至少包含兩個(gè)部分:局部變量的集合和全局變量的集合。

簡(jiǎn)單地說(shuō),如果JavaScript引擎在作用域鏈中搜索的深度越大,那么操作也就會(huì)消耗更多的時(shí)間。引擎首先從 this 開(kāi)始查找局部變量,然后是函數(shù)參數(shù)、本地定義的變量,最后遍歷所有的全局變量。

因?yàn)榫植孔兞吭谶@條鏈的起端,所以查找局部變量總是比查找全局變量要塊。所以當(dāng)你想要不止一次地使用一個(gè)全局變量的時(shí)候,你應(yīng)該將它定義成局部變量,就像這樣:

var dom1 = document.getElementById("id1"),
dom2 = document.getElementById("id2");

改寫成

var document = document,
demo1 = document.getElementById("id1"),
demo2 = document.getElementById("id2");
小心的使用閉包

雖然你可能還不知道“閉包”,但你可能在不經(jīng)意間經(jīng)常使用這項(xiàng)技術(shù)。閉包基本上被認(rèn)為是JavaScript中的new,當(dāng)我們定義一個(gè)即時(shí)函數(shù)的時(shí)候,我們就使用了閉包,比如:

document.getElementById("dom").onclick = function(ev) { };

閉包的問(wèn)題在于:根據(jù)定義,在它們的作用域鏈中至少有三個(gè)對(duì)象:閉包變量、局部變量和全局變量。這些額外的對(duì)象將會(huì)導(dǎo)致第1和第2個(gè)建議中提到的性能問(wèn)題。

閉包對(duì)于提高代碼可讀性等方面還是非常有用的,只是不要濫用它們(尤其在循環(huán)中)。

對(duì)象的屬性和數(shù)組元素影響

談到JavaScript的數(shù)據(jù),一般來(lái)說(shuō)有4種訪問(wèn)方式:數(shù)值、變量、對(duì)象屬性和數(shù)組元素。在考慮優(yōu)化時(shí),數(shù)值和變量的性能差不多,并且速度顯著優(yōu)于對(duì)象屬性和數(shù)組元素。

因此當(dāng)你多次引用一個(gè)對(duì)象屬性或者數(shù)組元素的時(shí)候,你可以通過(guò)定義一個(gè)變量來(lái)獲得性能提升。(這一條在讀、寫數(shù)據(jù)時(shí)都有效)

雖然這條規(guī)則在絕大多數(shù)情況下是正確的,但是Firefox在優(yōu)化數(shù)組索引上做了一些有意思的工作,能夠讓它的實(shí)際性能優(yōu)于變量。但是考慮到數(shù)組元素在其他瀏覽器上的性能弊端,還是應(yīng)該盡量避免數(shù)組查找,除非你真的只針對(duì)于火狐瀏覽器的性能而進(jìn)行開(kāi)發(fā)。

不要亂碰DOM

不使用DOM是JavaScript優(yōu)化中另一個(gè)很大的話題。經(jīng)典的例子是添加一系列的列表項(xiàng):如果你把每個(gè)列表項(xiàng)分別加到DOM中,肯定會(huì)比一次性加入所有列表項(xiàng)到DOM中要慢。這是因?yàn)镈OM操作開(kāi)銷很大。

Zakas對(duì)這個(gè)進(jìn)行了細(xì)致的講解,解釋了由于回流(reflow)的存在,DOM操作是非常消耗資源的?;亓魍ǔ1焕斫鉃闉g覽器重新選渲染DOM樹(shù)的處理過(guò)程。比如說(shuō),如果你用JavaScript語(yǔ)句改變了一個(gè)div的寬度,瀏覽器需要重繪頁(yè)面來(lái)適應(yīng)變化。

任何時(shí)候只要有元素被添加到DOM樹(shù)或者從DOM樹(shù)移除,都會(huì)引發(fā)回流。使用一個(gè)非常方便的JavaScript對(duì)象可以解決這個(gè)問(wèn)題——documentFragment,我并沒(méi)有使用過(guò),但是在Steve Souders也表示同意這種做法之后我感覺(jué)更加肯定了。

DocumentFragment 基本上是一種瀏覽器以非可視方式實(shí)現(xiàn)的類似文檔的片段,非可視化的表現(xiàn)形式帶來(lái)了很多優(yōu)點(diǎn),最主要的是你可以在 documentFragment 中添加任何結(jié)點(diǎn)而不會(huì)引起瀏覽器回流。

不要在數(shù)組中挖得太深

另外,程序員應(yīng)該避免在數(shù)組中挖得太深,因?yàn)檫M(jìn)入的層數(shù)越多,操作速度就越慢。

簡(jiǎn)單地說(shuō),在嵌套很多層的數(shù)組中操作很慢是因?yàn)閿?shù)組元素的查找速度很慢。試想如果操作嵌套三層的數(shù)組元素,就要執(zhí)行三次數(shù)組元素查找,而不是一次。

因此如果你不斷地引用 foo.bar, 你可以通過(guò)定義 var bar = foo.bar 來(lái)提高性能。

定時(shí)器的使用

如果針對(duì)的是不斷運(yùn)行的代碼,不應(yīng)該使用setTimeout,而應(yīng)該是用setInterval,因?yàn)閟etTimeout每一次都會(huì)初始化一個(gè)定時(shí)器,而setInterval只會(huì)在開(kāi)始的時(shí)候初始化一個(gè)定時(shí)器。

        var timeoutTimes = 0;
        function timeout() {
            timeoutTimes++;
            if (timeoutTimes < 10) {
                setTimeout(timeout, 10);
            }
        }
        timeout();
        //可以替換為:
        var intervalTimes = 0;
        function interval() {
            intervalTimes++;
            if (intervalTimes >= 10) {
                clearInterval(interv);
            }
        }
        var interv = setInterval(interval, 10);
React上的性能優(yōu)化

對(duì)于小型react前端應(yīng)用,最好的優(yōu)化就是不優(yōu)化因?yàn)镽eact本身就是通過(guò)比較虛擬DOM的差異,從而對(duì)真實(shí)DOM進(jìn)行最小化操作,小型React應(yīng)用的虛擬DOM結(jié)構(gòu)簡(jiǎn)單,虛擬DOM比較的耗時(shí)可以忽略不計(jì)。而對(duì)于復(fù)雜的前端項(xiàng)目,我們所指的渲染性能優(yōu)化,實(shí)際上是指,在不需要更新DOM時(shí),如何避免虛擬DOM的比較。

react組件的生命周期

工欲善其事,必先利其器。理解react的組件的生命周期是優(yōu)化其渲染性能的必備前提。我們可以將react組件的生命周期分為3個(gè)大循環(huán):掛載到DOM、更新DOM、從DOM中卸載。React對(duì)三個(gè)大循環(huán)中每一步都暴露出鉤子函數(shù),使得我們可以細(xì)粒度地控制組件的生命周期。

掛載到DOM

組件首次插入到DOM時(shí),會(huì)經(jīng)歷從屬性和狀態(tài)初始化到DOM渲染等基本流程,可以通過(guò)下圖所示

必須注意的是,掛載到DOM流程在組件的整個(gè)生命周期只有一次,也就是組件第一次插入DOM文檔流時(shí)。在掛載到DOM流程中的每一步也有相應(yīng)的限制:

更新DOM

 組件掛載到DOM后,一旦其props和state有更新,就會(huì)進(jìn)入更新DOM流程。同樣我們也可以通過(guò)一張圖清晰的描述該流程的各個(gè)步驟:
//getDefaultProps()和getInitialState()中不能獲取和設(shè)置組件的state。
//render()方法中不能設(shè)置組件的state。

componentWillReceiveProps()提供了該流程中更新state的最后時(shí)機(jī),后續(xù)的其他函數(shù)都不能再更新組件的state了。我們尤其需要注意的是shouldComponentUpdate函數(shù),它的結(jié)果直接影響該組件是不是需要進(jìn)行虛擬DOM比較,我們對(duì)組件渲染性能優(yōu)化的基本思路就是:在非必要的時(shí)候?qū)houldComponentUpdate返回值設(shè)置為false,從而終止更新DOM流程中的后續(xù)步驟。

從DOM中卸載

 從DOM中卸載的流程比較簡(jiǎn)單,React只暴漏出componentWillUnmount,該函數(shù)使得我們可以在DOM卸載的最后時(shí)機(jī)對(duì)其進(jìn)行干預(yù)。

2、性能分析

   合理的使用shouldComponentUpdate()可以在很大程序上優(yōu)化應(yīng)用。但在實(shí)際情況下,應(yīng)用往往在沙箱或是開(kāi)發(fā)環(huán)境中運(yùn)行的非???,但生產(chǎn)環(huán)境則表現(xiàn)的不盡人意。這時(shí),我們需要對(duì)應(yīng)用進(jìn)行性能分析,然后再有針對(duì)性的在shouldComponentUpdate()中進(jìn)行優(yōu)化。

React 提供了性能分析插件React.addons.Perf,它讓我們可以在需要檢測(cè)的代碼起始位置分別添加Perf.start()和Perf.stop(),并可以通過(guò)Perf.printInclusive()方法打印花費(fèi)時(shí)間,然后我們可以結(jié)合數(shù)據(jù)做進(jìn)一步的分析。

React.addons.Perf插件的詳細(xì)用法,可以查看官方文檔。

3、 借助react Key標(biāo)識(shí)組件

key屬性在組件類之外提供了另一種方式的組件標(biāo)識(shí)。通過(guò)key標(biāo)識(shí)我們可以組件如:順序改變、不必要的子組件更新等情況下,告訴React 避免不必要的渲染而避免性能的浪費(fèi)。

如,對(duì)于如一個(gè)基于排序的組件渲染

var items = sortBy(this.state.sortingAlgorithm, this.props.items);
return items.map(function(item){
  return 
});

當(dāng)順序發(fā)生改變時(shí),React 會(huì)對(duì)元素進(jìn)行diff操作,并改img的src屬性。顯示,這樣的操作效率是非常低的。這時(shí),我們可以為組件添加一個(gè)key屬性以唯一的標(biāo)識(shí)組件:

    return 

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/82014.html

相關(guān)文章

  • 前端資源系列(4)-前端學(xué)習(xí)資源分享&前端面試資源匯總

    摘要:特意對(duì)前端學(xué)習(xí)資源做一個(gè)匯總,方便自己學(xué)習(xí)查閱參考,和好友們共同進(jìn)步。 特意對(duì)前端學(xué)習(xí)資源做一個(gè)匯總,方便自己學(xué)習(xí)查閱參考,和好友們共同進(jìn)步。 本以為自己收藏的站點(diǎn)多,可以很快搞定,沒(méi)想到一入?yún)R總深似海。還有很多不足&遺漏的地方,歡迎補(bǔ)充。有錯(cuò)誤的地方,還請(qǐng)斧正... 托管: welcome to git,歡迎交流,感謝star 有好友反應(yīng)和斧正,會(huì)及時(shí)更新,平時(shí)業(yè)務(wù)工作時(shí)也會(huì)不定期更...

    princekin 評(píng)論0 收藏0
  • 個(gè)人分享--web前端學(xué)習(xí)資源分享

    摘要:前言月份開(kāi)始出沒(méi)社區(qū),現(xiàn)在差不多月了,按照工作的說(shuō)法,就是差不多過(guò)了三個(gè)月的試用期,準(zhǔn)備轉(zhuǎn)正了一般來(lái)說(shuō),差不多到了轉(zhuǎn)正的時(shí)候,會(huì)進(jìn)行總結(jié)或者分享會(huì)議那么今天我就把看過(guò)的一些學(xué)習(xí)資源主要是博客,博文推薦分享給大家。 1.前言 6月份開(kāi)始出沒(méi)社區(qū),現(xiàn)在差不多9月了,按照工作的說(shuō)法,就是差不多過(guò)了三個(gè)月的試用期,準(zhǔn)備轉(zhuǎn)正了!一般來(lái)說(shuō),差不多到了轉(zhuǎn)正的時(shí)候,會(huì)進(jìn)行總結(jié)或者分享會(huì)議!那么今天我就...

    sherlock221 評(píng)論0 收藏0
  • 2017年1月前端月報(bào)

    摘要:平日學(xué)習(xí)接觸過(guò)的網(wǎng)站積累,以每月的形式發(fā)布。年以前看這個(gè)網(wǎng)址概況在線地址前端開(kāi)發(fā)群月報(bào)提交原則技術(shù)文章新的為主。 平日學(xué)習(xí)接觸過(guò)的網(wǎng)站積累,以每月的形式發(fā)布。2017年以前看這個(gè)網(wǎng)址:http://www.kancloud.cn/jsfron... 概況 在線地址:http://www.kancloud.cn/jsfront/month/82796 JS前端開(kāi)發(fā)群月報(bào) 提交原則: 技...

    FuisonDesign 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<