這篇文章將介紹下實際使用performance對頁面進行優化的過程。總的來講,chrome performance工具讓咱們更方便的發如今代碼運行過程當中的問題在哪裏,便於對一些可能注意不到的問題進行定位、分析和優化。原文首發於我的博客react
首先,咱們對進入整個詳情頁進行分析,整個頁面的結構大體以下,主要包含三個部分:基本信息,可視化圖和時間軸。時間軸內部包含時間軸的詳情信息,包括表格和幾種類型的可視化圖等,內部比較重。如圖所示:git
咱們點擊錄製,查看進入頁面的性能圖:github
能夠看到,渲染當前頁面的耗時將近1.2s,咱們看看究竟是哪裏出現了問題。對渲染部分進行放大,咱們發如今渲染時間軸的過程當中,大部分時間耗費在了每一個時間節點詳情內容的展現上面,可是默認狀態下,他們是進行隱藏的。也就是說,咱們進行了N個節點的沒必要要的渲染,只需把他們幹掉就行了。chrome
查看代碼,發現是如下位置致使的,咱們進行了一個展開盒子的封裝,相似這樣:緩存
<Box data={data} border collapse loading={loading}> <AlertDetail /> </Box>
在非展開狀態下,咱們依然對內容進行了渲染,只是使用樣式進行了隱藏,可是這樣React仍然會進行虛擬dom的渲染和計算,在這裏咱們對其進行改造,讓其只在展開時進行渲染,並儘可能緩存渲染的結果。修改完成後,咱們會發現,Scripting由以前的880+ms變成了670ms減小了200ms左右:app
咱們繼續看,會發現頁面初始化時,詳情部分會有大量的Evaluate Script耗時,主要是耗費在告警詳情右側的分類及各分類下的可視圖及詳情引發的。dom
咱們可能會想,這裏在初始化時並無進行渲染,爲何仍然會耗費時長進行計算呢?繼續追查我發現緣由在這裏:tcp
在整個詳情組件中,咱們對包括http,tcp等全部類型的組件進行了引用,而後根據其類型進行組件的匹配,在各個組件中可能包含了每一個類型對應的定義、分類和計算等等等等,不只增長了加載時間,更延長了初始化時間,顯然咱們這麼作是不對的。工具
在此,咱們可使用懶加載方式對其進行優化,僅展現其對應類型的圖,避免了沒必要要的資源浪費和計算時間。性能
修改以後,咱們再次進行性能測試,發如今進入頁面時,詳情組件的耗費時長由260ms變爲不到2ms:
而Scripting由以前的670+ms變成了415ms減小了250ms左右:
至此,進入頁面的耗時已由最開始的1.2s左右變成了如今的0.7s左右。
咱們在點擊時間軸查看詳情時,會進行幾個操做。關閉其餘已開啓的詳情內容,展開當前詳情內容,根據當前的類型進行對應類型的詳情內容展現,上邊已經提到過。這個過程會涉及到React的update操做,咱們來對這個過程進行一下優化。
首先咱們點擊錄製按鈕,而後點擊展開,並對其進行錄製。咱們會發現如下的結果:
點擊展開按鈕,Timeline組件進行了屢次重複渲染,顯然這是不該該的,咱們來看下是哪裏致使的。咱們看到整個時間軸組件中,有這樣一段代碼,在時間軸組件中使用connect鏈接了timeline和alertList兩個數據,其中,alertList數據是詳情內種中對應的告警列表。兩組數據對應的更改都會映射到組件的更新,好比時間軸的展開收起,以及alertList請求,請求成功及失敗等。
按理來講,alertList對應的請求,僅對應到當前展開內容的更新便可。所以,咱們對此有幾種修改方案:
在此咱們採用第一種,避免alertList對整個組件的影響。
咱們會發現,點開詳情後,整個timeLine只進行了一次大更新,詳情的更新只在展開的組件中進行。
咱們會發現,在對某一個時間點進行展開時,整個list列表的節點都進行了更新,以下圖所示。顯然這樣的性能耗費是及其大且不重要的。假如列表的內容不少,那極有可能形成大量的更新致使頁面卡死。
由於其餘的list列表節點都引用了alertList這個prop, 當其進行改變時,全部的節點都會進行更新,因此咱們須要使用shouldComponentUpdate手動對其進行優化:
// 當開關狀態變化時,才重新渲染,不然不須要 shouldComponentUpdate (nextProps, nextState) { const opened = _.get(this.props, 'open') const willOpen = _.get(nextProps, 'open') if (opened === willOpen && !willOpen) { return false } else { // 相似pureComponent進行淺比較 return !_.isEqual(this.props, nextProps) || !_.isEqual(this.state, nextState) } }
再次進行錄製,咱們發現只要當前Item進行了更新,整個Timeline更新時間縮短到不到40ms,極大的增長了體驗。
其餘優化過程與上面相似,再也不贅述。
經過配合performance工具進行一步步優化,整個頁面的渲染和更新性能有了極大的提高,咱們也藉此知道了在平時書寫代碼過程當中須要注意的問題。咱們簡單的作一下總結: