React面試寶典視頻課程
React 是靠數(shù)據(jù)驅(qū)動視圖改變的一種框架,它的核心驅(qū)動方法就是用其提供的 setState 方法設(shè)置 state 中的數(shù)據(jù)從而驅(qū)動存放在內(nèi)存中的虛擬 DOM 樹的更新。
更新方法就是通過 React 的 Diff 算法比較舊虛擬 DOM 樹和新虛擬 DOM 樹之間的 Change ,然后批處理這些改變。
React 性能優(yōu)化的手段
React 中進(jìn)行性能優(yōu)化的手段可以從多個(gè)維度進(jìn)行分類,以下是一些關(guān)鍵類別及其對應(yīng)的優(yōu)化策略:
1. 組件優(yōu)化
使用PureComponent或React.memo:對于僅根據(jù)props和state改變才重新渲染的組件,使用React.PureComponent或者對其包裝一層React.memo,它們都能通過淺比較props來避免不必要的重新渲染。
shouldComponentUpdate/React Hooks中的useMemo/useCallback:在類組件中實(shí)現(xiàn)shouldComponentUpdate生命周期方法來手動控制是否更新組件。在函數(shù)組件中,使用useMemo緩存計(jì)算結(jié)果,useCallback緩存回調(diào)函數(shù),防止因依賴項(xiàng)不變而引起的無效渲染。
2. 狀態(tài)管理與變更
減少不必要的setState調(diào)用:合并多次對同一狀態(tài)的修改,例如使用useState hook時(shí),可以利用函數(shù)式的setState來一次性更新多個(gè)狀態(tài)值。
選擇性地更新state:只在props或state真正發(fā)生變化時(shí)才進(jìn)行更新,避免頻繁或大面積的state變更引發(fā)大量子組件重新渲染。
3. Virtual DOM與Diff算法優(yōu)化
合理構(gòu)建組件層級:保持組件樹扁平化,減少不必要的嵌套層次,使React的diff算法更高效。
利用key屬性:為列表元素提供穩(wěn)定的唯一key,幫助React識別并最小化DOM變動。
少用 dom 層級 多使用箭頭標(biāo)簽替代
4. 事件處理優(yōu)化
使用合成事件:React的合成事件系統(tǒng)可以減少全局事件監(jiān)聽器的數(shù)量,提高事件處理效率。
避免內(nèi)聯(lián)函數(shù)綁定:在事件處理函數(shù)中,避免每次渲染時(shí)創(chuàng)建新的函數(shù)引用,而是使用箭頭函數(shù)或者useCallback來緩存函數(shù)引用。
5. 懶加載與代碼分割
動態(tài)導(dǎo)入:使用React.lazy和Suspense來按需加載組件,減輕初始加載負(fù)擔(dān),提高首屏加載速度。
使用優(yōu)先級加載CSS、JavaScript和圖片資源。
6. 優(yōu)化渲染過程
使用ReactDOM.createPortal:將某些組件渲染到根DOM之外,比如渲染到document.body,可以避免不必要的re-render。
CSS動畫與交互優(yōu)化:配合requestAnimationFrame等API來處理復(fù)雜的動畫,減少不必要的布局重排和重繪。
7、工具輔助
Profiler工具:利用React DevTools的Profiler面板分析組件渲染性能瓶頸。
性能監(jiān)控與警告:設(shè)置性能指標(biāo)監(jiān)控點(diǎn),及時(shí)發(fā)現(xiàn)和修復(fù)潛在性能問題。
8、前端通用優(yōu)化
靜態(tài)資源壓縮與HTTP緩存:優(yōu)化CSS、JavaScript文件大小,合理設(shè)置HTTP緩存策略。
服務(wù)端渲染(SSR):針對SEO友好和首屏加載速度,結(jié)合Next.js等框架進(jìn)行服務(wù)器端渲染。
Fiber架構(gòu)出現(xiàn)之前 react 存在的問題
主線程阻塞:在React 15及更早版本中,當(dāng)組件樹發(fā)生更新時(shí),React會通過遞歸算法一次性完成整個(gè)組件樹的渲染過程,這個(gè)過程如果涉及大量組件,會導(dǎo)致主線程長時(shí)間阻塞,無法處理其他的UI交互,從而造成卡頓和延遲,降低用戶體驗(yàn)。
無法中斷與恢復(fù)渲染:原有的渲染過程不具備中斷和恢復(fù)的能力,一旦開始渲染,就必須等到整個(gè)過程結(jié)束,即使在中間有更高優(yōu)先級的任務(wù)也需要等待。
無法實(shí)現(xiàn)增量渲染:以往的React無法有效區(qū)分渲染任務(wù)的重要性和緊急程度,所有更新任務(wù)都被視為同等重要的,無法做到逐步、增量地渲染UI。
資源優(yōu)化不足:舊版React無法根據(jù)應(yīng)用的具體需求動態(tài)分配資源,無法高效利用有限的CPU周期來優(yōu)化渲染性能。
1、說說React的事件機(jī)制?
在React中,基于瀏覽器事件有一套自身的事件機(jī)制,包括:事件注冊、事件合成、事件派發(fā)等,這些事件被稱為合成事件。它的所有事件都是掛載在Document對象上,當(dāng)真實(shí)DOM觸發(fā)時(shí),會冒泡到document上后,再處理react事件,所以會先執(zhí)行原生事件,再處理react事件,最后再真正執(zhí)行document上掛載事件。
2、說說React中引入css的方式有哪幾種?區(qū)別?
常見的引入方式:
在組件內(nèi)直接使用
組件中引入.css文件
組件中引入.modules.css文件
CSS in JS
3、React中組件之間是如何通信的?
react中通信方式有以下幾種:
父向子:父組件在調(diào)用子組件的時(shí)候,只需要在子組件標(biāo)簽內(nèi)傳遞參數(shù),子組件通過props屬性就能接收父組件傳遞過來的參數(shù)。
子向父:子組件向父組件通信的基本思路是,父組件向子組件傳一個(gè)函數(shù),然后通過這個(gè)函數(shù)的回調(diào),拿到子組件傳過來的值。
兄弟間:父組件作為中間層來實(shí)現(xiàn)數(shù)據(jù)的互通,通過使用父組件傳遞。
父向后代:使用 context 提供了組件之間通訊的一種方式,可以共享數(shù)據(jù),其他數(shù)據(jù)都能讀取對應(yīng)的數(shù)據(jù)。
非關(guān)系:使用redux,創(chuàng)建全局資源數(shù)據(jù)管理,共用實(shí)現(xiàn)通信。
4、Redux工作原理
Redux 是 React 的第三方狀態(tài)管理庫,創(chuàng)建于上下文API存在之前。它基于一個(gè)稱為存儲的狀態(tài)容器的概念,組件可以從該容器中作為 props 接收數(shù)據(jù)。更新存儲區(qū)的唯一方法是向存儲區(qū)發(fā)送一個(gè)操作,該操作被傳遞到一個(gè)reducer中。reducer接收操作和當(dāng)前狀態(tài),并返回一個(gè)新狀態(tài),觸發(fā)訂閱的組件重新渲染。