iT邦幫忙

第 12 屆 iT 邦幫忙鐵人賽

DAY 18
2
Modern Web

從比入門再往前一點開始,一直到深入React.js系列 第 18

【Day.18】開發者工具React Dev tool與useContext的效能問題

由於我們在執行React程式前,都要透過webpack和Babel打包編譯成瀏覽器看的懂的ES5,實際跑在瀏覽器的程式碼就會和本來React裡面長的樣子差很多,Debug時就要直接去改原始code才會比較方便,很麻煩。

這個時候,我們就會需要React Dev tool的協助。

安裝

請在Chrome/Firefox插件商店搜尋React並安裝React Dev tool

重新開啟瀏覽器後,打開我們的程式,如果有看到右上方有React Icon就代表安裝成功了

監控/修改 Component

點擊F12後,點選右邊選單中的Component

你就會看到剛剛我們寫的程式的架構

點擊其中一個元件,你就能從右邊的面板看到這個元件的state、props、hook、context的現在的值

你也可以在這裡直接修改props或state,修改後的結果會直接顯示在畫面上:

尋找Component對應在DOM的元素

點選元件後點右上方的眼睛,React-dev-tool就會在Element頁籤上顯示元件對應在DOM的原始元素。

印出元件相關資訊

點選旁邊的蟲,元件的相關資訊就會印在console

尋找元件打包後的程式碼

在旁邊的按鈕可以幫我們找到React元件對應到打包後JS檔的位置

效能監控

點擊F12後,點選右邊選單中的Profiler

Profiler可以幫我們監控每一次的操作中,哪些元件被重新render、render花了多久,操作方法如下:

然而如果每次都要按錄製再去看到底誰被re-render是一件很麻煩的事情。所以你也可以點開右邊的齒輪,設定讓React-dev-tool用顏色標記重新被渲染的元素。設定方法如下:

另外,在齒輪中,你也能夠設定讓它記憶每個component被re-render的原因,方便你Debug。

奇怪的事情發生了 - useContext的問題

如果你有注意到的話,會發現我們點擊剛剛製作的元件時,明明在上一篇中我們把isOpen從控制MenuItem的開關拔掉了,但是當isOpen被改變時,MenuItem還是被重新渲染了。而當你去看Profiler記憶的過程,會發現上面寫著「父元件被重新渲染」。

所以只要父元件被重新渲染,即使只是一小部份,所有子元件都會被重新渲染嗎?

不,並不是,React沒有這麼爛。理論上的確是只應該渲染「跟那一小部份有關的地方」,以上面的例子而言是button。

會造成這個問題是因為useContext原始的實作方法,不是去檢查該context更動會不會改變子元件。而是當context被更新時,直接讓所有使用useContext的元件都被重新渲染

這個問題在專案小的時候還能夠忽視,但當專案大起來,這件事就很讓人頭痛了。

當然,因應這個問題,有非常多開發者提供了第三方函式庫來加入一個檢查是否真的要渲染的篩選器。但是有沒有用原生React API就能解決的方法呢? 難道官方沒有提出任何解決方法放它爛嗎?

接下來的這幾篇,我們會來討論如何用原生React API處理各種效能問題(包含這件事)。


上一篇
【Day.17】React入門 - 利用useContext進行多層component溝通
下一篇
【Day.19】React效能 - 用memo避免不必要的重複渲染
系列文
從比入門再往前一點開始,一直到深入React.js30

尚未有邦友留言

立即登入留言