React?Native性能優(yōu)化紅寶書方案詳解
一、React Native介紹
React Native 是Facebook在React.js Conf2015 推出的開源框架,使用React和應(yīng)用平臺的原生功能來構(gòu)建 Android 和 iOS 應(yīng)用。通過 React Native,可以使用 JavaScript 來訪問移動平臺的 API,使用 React 組件來描述 UI 的外觀和行為。
JS實(shí)現(xiàn)調(diào)用的能力中間的適配層提供了一些橋接方案
1、RN優(yōu)勢
1.1 HTML/CSS/JS開發(fā)成本低,用統(tǒng)一的代碼規(guī)范開發(fā)移動端程序,不用關(guān)注移動端差異
1.2 天然跨平臺,開發(fā)一次,可以生成Android和ios兩個系統(tǒng)上的APP,這減少了開發(fā)人員需要編寫不同版本的應(yīng)用程序的時間和工作量。
1.3 無審核熱更新
1.4 可擴(kuò)展
1.5 易學(xué)易用:React Native 基于 React,開發(fā)人員可以使用熟悉的 JavaScript 和 React 組件模型來構(gòu)建應(yīng)用程序,因此很容易學(xué)習(xí)和上手。
RN的本質(zhì)是把中間的這個橋Bridge給搭好,讓JS和native可以互相調(diào)用。
RN為我們提供了JS的運(yùn)行環(huán)境,所以前端開發(fā)者們只需要關(guān)心如何編寫JS代碼,
畫UI只需要畫到virtual DOM 中,不需要特別關(guān)心具體的平臺。
至于如何把JS代碼轉(zhuǎn)成native代碼的臟活累活,RN底層全干了
2、RN劣勢
2.1 不成熟,項(xiàng)目版本更新維護(hù)較頻繁,學(xué)習(xí)成本高,試錯成本高,有些問題較少解決方案,開發(fā)進(jìn)度慢
2.2 性能:整體性能仍不如原生
2.3 兼容性:涉及底層的功能,需要針對Android和ios雙端單獨(dú)開發(fā)
2.4 有限的第三方庫:盡管 React Native 社區(qū)不斷增長,但相對于其他混合應(yīng)用框架,第三方庫和插件的數(shù)量還是有限的。這可能使開發(fā)人員在某些方面受到限制。
2.5 有些原生功能需要自己實(shí)現(xiàn):雖然 React Native 提供了大量原生組件,但某些原生功能需要開發(fā)人員自己實(shí)現(xiàn),這可能需要額外的時間和工作量。
3、跨平臺框架比較
開發(fā)模式 | 原生開發(fā) | 混合開發(fā) | Web開發(fā) |
運(yùn)行環(huán)境 | Android、iOS、Windows | 混合App、 React Native,Weex、Flutter | 瀏覽器、WebView |
編程語言 | Java,Objective-C | JavaScript、Dart | HTML、CSS、JavaScript |
可移植性 | 差 | 一般 | 好 |
開發(fā)速度 | 慢 | 一般 | 快 |
性能 | 快 | 一般 | 慢 |
學(xué)習(xí)成本 | 高 | 一般 | 低 |
4、Hybrid App 優(yōu)勢
4.1 跨平臺開發(fā)
4.2 離線訪問
4.3 原生應(yīng)用程序的用戶體驗(yàn)
4.4 快速開發(fā)和迭代
混合應(yīng)用程序結(jié)合了Web應(yīng)用程序和本地應(yīng)用程序的優(yōu)點(diǎn),既能夠在原生應(yīng)用程序環(huán)境中運(yùn)行,也能夠在 Web 瀏覽器中運(yùn)行,并且具有更好的用戶體驗(yàn)和功能。這種開發(fā)方式可以大大減少開發(fā)時間和成本,提高開發(fā)效率。
5、React Native 0.68之前的架構(gòu)
5.1、整體UI渲染太過于依賴JsBridge,容易出現(xiàn)阻塞影響整體UI體驗(yàn)
5.2、性能和問題反饋?zhàn)畲蟮慕M件:
ScrollView:一次渲染不做任何回收,啟動性能慢,占用內(nèi)存大
FlatList:做了組件回收,快速滑動中容易出現(xiàn)白屏和卡頓
Shadow層最終呈現(xiàn)到原生的UI是異步的,滑動太快會有大量的UI
5.3、事件阻塞在JsBridge,導(dǎo)致了長時間白屏的出現(xiàn)
6、RN中的視圖渲染
javascript:JS代碼的執(zhí)行線程,將源碼通過Metro打包后傳給JS引擎進(jìn)行解析:
結(jié)構(gòu) 樣式 屬性
Main線程(UI線程或原生線程):主要負(fù)責(zé)原生渲染(Native UI)和調(diào)用原生模塊(Native Modules Shadow 線程Layout線程:創(chuàng)建Shadow Tree來模擬Reac結(jié)構(gòu)樹(類似虛擬DOM),再由Yoga引擎將Flexbox等樣式,解析成平臺的布局方式:
寬高 位置
7、RN架構(gòu)設(shè)計(jì)--新舊架構(gòu)對比
7.1、JavaScript層:
支持React 16+新特性
增強(qiáng)JS靜態(tài)類型檢查(CodeGen)
引入JSI允許替換不同的JavaScript引擎
7.2、Bridge層:
劃分了Fabric和TurboModules,分別負(fù)責(zé)管理UI和Native模塊
7.3、Native層:
精簡核心模塊,將非核心部分拆除去,作為社區(qū)模塊,獨(dú)立維護(hù)
8、從 0.68 版本開始React Native 的新架構(gòu)
8.1、JSI (JavaScript Interface)
一個用 C++ 寫成的輕量級框架
實(shí)現(xiàn)JS引擎的互換
通過JS直接調(diào)用Native
減少不必要的線程通信,省去序列化和反序列化的成本,
減輕了通信壓力,提高了通信性能
8.2、CodeGen
FaceBook推出的代碼生成工具
加入了類型約束后,減少了數(shù)據(jù)類型錯誤
自動將 Flow 或 TS 有靜態(tài)類型檢查的 JS 代碼轉(zhuǎn)換為 Fabric 和 TurboModules 使用的原生代碼
8.3、優(yōu)化Bridge層
Fabric是整個框架中的新UI層,簡化了之前的渲染
Turbo Modules通過JSI可以讓JS直接調(diào)用Native模塊,實(shí)現(xiàn)同步操作,實(shí)現(xiàn)Native模塊按需加載,減少啟動時間,提高性能
8.4、精簡核心代碼(LEAN Core)
將React Native核心包進(jìn)行瘦身,非必要包移到社區(qū)單獨(dú)維護(hù)
9、React介紹
Facebook,Learn Once,write anywhere
數(shù)據(jù)驅(qū)動,狀態(tài)決定界面的變化,虛擬dom(抽象層)
虛擬dom的好處,首先是性能的優(yōu)化,不直接操作Dom先進(jìn)行一些比較,計(jì)算找出需要變化的部分,在實(shí)際的dom中進(jìn)行操作
其次,這個抽象層,還提供了邏輯代碼跨平臺移植的可能性
虛擬dom的下方對接的,是網(wǎng)頁,是移動端,是電視端,任何一個可以渲染的端,都可以做接口的適配,使得代碼在任何地方使用
主要四個部分:
組件:類組件、函數(shù)式組件
屬性Props
狀態(tài)State
jsx:React 和 React Native 都使用JSX 語法,這種語法使得你可以在 JavaScript 中直接輸出本質(zhì)上也就是 JavaScript,所以你可以在其中直接使用變量元素,JSX
hook api: todo補(bǔ)充
生命周期: todo補(bǔ)充
二、性能優(yōu)化點(diǎn)
1、RN加載的主要時間消耗
todo:補(bǔ)充
2、RN性能優(yōu)化-拆包、分包
React Native 頁面的 JavaScript 代碼包是熱更新平臺根據(jù)版本號進(jìn)行下發(fā)的,每次有業(yè)務(wù)改動,我們都需要通過網(wǎng)絡(luò)請求更新代碼包。
因此,我們在對JavaScript 代碼進(jìn)行打包的時候,需要將包拆分成兩個部分:
2.1、Common 部分,也就是 React Native 源碼部分;
2.2、業(yè)務(wù)代碼部分,也就是我們需要動態(tài)下載的部分
具體操作:
JavaScript 代碼包中 React Native 源碼相關(guān)的部分是不會發(fā)生變化的,所以我們不需要在每次業(yè)務(wù)包更新的時候都進(jìn)行下發(fā),在工程中內(nèi)置一份就好了。Common 包內(nèi)置到工程中業(yè)務(wù)代碼包進(jìn)行動態(tài)下載利用 JSContext 環(huán)境,在進(jìn)入載體頁后在環(huán)境中先加載 Common 包,再加載業(yè)務(wù)代碼包就可以完整的渲染出 React Native 頁面
todo:代碼示例?
3、首屏渲染
通過拆包的方案,已經(jīng)減少了動態(tài)下載的業(yè)務(wù)代碼包的大小。但是還會存在部分業(yè)務(wù)非常龐大,拆包后業(yè)務(wù)代碼包的大小依然很大的情況,依然會導(dǎo)致下載速度較慢,并且還會受網(wǎng)絡(luò)情況的影響。
因此,我們可以再次針對業(yè)務(wù)代碼包進(jìn)行拆分
將一個業(yè)務(wù)代碼包拆分為一個主包和多個子包的方式
在進(jìn)入頁面后優(yōu)先請求主包的 JavaScript 代碼資源,能夠快速地渲染首屏頁面,
緊接著用戶點(diǎn)擊某一個模塊時,再繼續(xù)下載對應(yīng)模塊的代碼包并進(jìn)行渲染,就能再進(jìn)一步減少加載時間。
4、減少渲染的節(jié)點(diǎn)-通過組件懶加載提高應(yīng)用性能
組件懶加載可以讓 react 應(yīng)用在真正需要展示這個組件的時候再去展示,有效的減少渲染的節(jié)點(diǎn)數(shù),提高頁面的加載速度
React 官方在 16.6 版本后引入了新的特性:React.lazy 和 React.Suspense,這兩個組件的配合使用可以比較方便進(jìn)行組件懶加載的實(shí)現(xiàn)
React.lazy 該方法主要的作用就是可以定義一個動態(tài)加載的組件,這可以直接縮減打包后 bundle 的體積,
并且可以延遲加載在初次渲染時不需要渲染的組件
Suspense組件中的 fallback 屬性接受任何在組件加載過程中你想展示的 React 元素。
你可以將 Suspense 組件置于懶加載組件之上的任何位置,你甚至可以用一個 Suspense 組件包裹多個懶加載組件。 代碼示例如下:
import React, {Suspense} from 'react'; const OtherComponent = React.lazy(() => import('./OtherComponent)); const AnotherComponent = React.lazy(() => import('./AnotherComponent)); function MyComponent() { return( <div> <Suspense fallback={<div> loading...</div>}> <section> <OtherComponent/> <AnotherComponent/> </section> </Suspense> </div> ) }
使用懶加載可以減少bundle文件大小,
不同的文件打包到不同的頁面組件當(dāng)中,加快組件的呈現(xiàn)
import React, {lazy, Suspense} from 'react'; const OtherComponentLazy = lazy(() => import('./OtherComponent)); const AnotherComponentLazy = lazy(() => import('./AnotherComponent)); function Suspensed(lazyComponent) { return (props) { <Suspense fallback={<div></div>}> <lazyComponent {...props} /> </Suspense> } } export const OtherComponent = Suspensed(OtherComponentLazy) export const AnotherComponent = Suspensed(AnotherComponentLazy)
5、提交階段優(yōu)化-避免重復(fù)無限渲染
當(dāng)應(yīng)用程序狀態(tài)發(fā)生更改時,React會調(diào)用render方法。
如果在render方法中繼續(xù)更改應(yīng)用程序狀態(tài),就會發(fā)生render方法遞歸調(diào)用,導(dǎo)致應(yīng)用報錯。
Render方法應(yīng)該作為純函數(shù),render方法的執(zhí)行要根據(jù)狀態(tài)的改變,保持組件的行為和渲染方法一致。
執(zhí)行提交階段鉤子,會阻塞瀏覽器更新頁面。
如果在提交階段鉤子函數(shù)中更新組件 State,會再次觸發(fā)組件的更新流程,造成兩倍耗時。
一般在提交階段的鉤子中更新組件狀態(tài)的場景有:
- 類組件應(yīng)使用 getDerivedStateFromProps 鉤子方法代替,函數(shù)組件應(yīng)使用函數(shù)調(diào)用時執(zhí)行 setState的方式代替。
- 使用上面兩種方式后,React 會將新狀態(tài)和派生狀態(tài)在一次更新內(nèi)完成。
- 根據(jù) DOM 信息,修改組件狀態(tài)。在該場景中,除非想辦法不依賴 DOM 信息,否則兩次更新過程是少不了的,就只能用其他優(yōu)化技巧了。
6、組件卸載前執(zhí)行清理操作
React 組件性能優(yōu)化的核心是減少渲染真實(shí)DOM節(jié)點(diǎn)的頻率,減少Virtual DOM 比對的頻率
在組件中為window注冊的全局事件,以及定時器,在組件卸載前要清理掉,防止組件卸載后繼續(xù)執(zhí)行影響應(yīng)用性能
import React,{ Component } from 'react'; export default class Hello extends Component { componentDidMount() { this.timer = setTimeout( () => { console.log('把一個定時器的引用掛在this上'); }, 500 ); } componentWillUnmount() { // 如果存在this.timer,則使用clearTimeout清空。 // 如果你使用多個timer,那么用多個變量,或者用個數(shù)組來保存引用,然后逐個clear this.timer && clearTimeout(this.timer); } };
7、通過使用占位符標(biāo)記提升React組件的渲染性能
使用Fragment不對應(yīng)具體的視圖,減少了包含的額外標(biāo)記的數(shù)量
僅僅是代表可以包裝而已,跟空的標(biāo)識符一樣,視圖層級關(guān)系減少有利于視圖渲染,
滿足在組件頂級具有單個父級的條件
<div> ... </div> // 上面會多出一個無意義標(biāo)記 // 應(yīng)該改為 <fragment> ... </fragment> // 或者寫成下面這樣也是可以的 <> ... </>
8、縮小狀態(tài)影響范圍-狀態(tài)下放到使用組件的內(nèi)部
React不直接操作DOM,它在內(nèi)存中維護(hù)一個快速響應(yīng)的DOM描述,render方法返回一個DOM的描述
React能夠計(jì)算出兩個DOM描述的差異,然后更新瀏覽器中的DOM,這就是著名的DOM Diff。
就是說React在接收到屬性(props)或者狀態(tài)(state)更新時,就會通過前面的方式更新UI。所以React整個UI渲染是比較快的。但是這里面可能出現(xiàn)的問題是:
假設(shè)我們定義一個父組件,其包含了5000個子組件。我們有一個輸入框輸入操作,每次輸入一個數(shù)字,對應(yīng)的那個子組件背景色變紅。
父組件更新默認(rèn)觸發(fā)所有子組件更新,子組件的props為空對象,{} === {} 永遠(yuǎn)會返回false
優(yōu)化思想:將變的和不變的分開(state,props,context)
我們需要先手動創(chuàng)建一個有嚴(yán)重渲染性能的組件,如下所示:
import { useState } from 'react'; export default function App() { let [color, setColor] = useState('red'); return ( <div> <input value={color} onChange={(e) => setColor(e.target.value)} /> <p style={{ color }}>Hello, world!</p> <ExpensiveTree /> </div> ); } function ExpensiveTree() { let now = performance.now(); while (performance.now() - now < 100) { // Artificial delay -- do nothing for 100ms } return <p>I am a very slow component tree.</p>; }
很顯然,當(dāng) App 組件內(nèi)的狀態(tài)發(fā)生了改變,ExpensiveTree 組件會 re-render, 事實(shí)上 ExpensiveTree 組件的 props、state 并未發(fā)生改變,這并不是我們期望的結(jié)果。
export default function App() { let [color, setColor] = useState('red'); return ( <div> <input value={color} onChange={(e) => setColor(e.target.value)} /> <p style={{ color }}>Hello, world!</p> <ExpensiveTree /> </div> ); }
我們可以看到以上 ExpensiveTree 組件并不依賴 App 組件內(nèi)部的狀態(tài),因此我們是否可以考慮,將依賴 color 的元素抽離到一個依賴 color 的組件中呢?
export default function App() { return ( <> <Form /> <ExpensiveTree /> </> ); } function Form() { let [color, setColor] = useState('red'); return ( <> <input value={color} onChange={(e) => setColor(e.target.value)} /> <p style={{ color }}>Hello, world!</p> </> ); }
此時,將依賴 color 的元素提取到了 Form 組件中,F(xiàn)orm 組件內(nèi)部的狀態(tài)不再影響 ExpensiveTree 組件的渲染,問題便得到了解決。
9、跳過不必要的組件更新-通過純組件提升性能
- 類組件中使用PureComponent
- 函數(shù)式組件中使用React.memo
在 React 工作流中,如果只有父組件發(fā)生狀態(tài)更新,即使父組件傳給子組件的所有 Props 都沒有修改,也會引起子組件的 Render 過程。
如果子組件的 Props 和 State 都沒有改變,那么其生成的 DOM 結(jié)構(gòu)和副作用也不應(yīng)該發(fā)生改變。
純組件會對組件輸入數(shù)據(jù)進(jìn)行淺層比較,如果當(dāng)前輸入數(shù)據(jù)和上次輸入數(shù)據(jù)相同,組件不會重新渲染。
比較引用數(shù)據(jù)類型在內(nèi)存中的引用地址是否相同,比較基本數(shù)據(jù)類型的值是否相同
為什么不直接進(jìn)行diff操作?而要先進(jìn)行淺比較?
淺比較只操作當(dāng)前組件的state和props,diff操作會重新遍歷整個VirtualDOM樹
10、跳過不必要的組件更新-通過shouldComponentUpdate
純函數(shù)只能進(jìn)行淺層比較,要進(jìn)行深層比較,
使用shouldComponentUpdate,它用于編寫自定義比較邏輯
ShouldComponentUpdate(nextProps,nextState){ if(nextProps……){ return true } return false }
11、跳過不必要的組件更新-通過memo純組件提升性能
Memo基本使用:將函數(shù)組件變?yōu)榧兘M件,當(dāng)前props和上一次的props進(jìn)行淺比較,如果相同就阻止組件重新渲染
Memo函數(shù)是淺層數(shù)據(jù)比較,如果遇到引用數(shù)據(jù)類型,需要傳遞自定義比較邏輯,傳給Memo函數(shù)的第二個參數(shù)
memo的第二個參數(shù)示例如下:
// 給memo傳遞第二個參數(shù),自定義比較邏輯 import React, { memo, useEffect, useState } from 'react' function App () { const [person, setPerson] = useState({ name: '張三', age: 20, job: 'waiter' }) const [index, setIndex] = useState(0) useEffect(() => { let timer = setInterval(() => { setIndex(prev => prev + 1) setPerson({ ...person, job: 'chef' }) }, 1000) return () => { clearInterval(timer) } }, [index, person]) return ( <div> {index} <ShowName person={person} /> </div> ) } function compare (prevProps, nextProps) { if ( prevProps.person.name !== nextProps.person.name || prevProps.person.age !== nextProps.person.age ) { return false } return true } const ShowName = memo(function ({ person }) { console.log('render...') return ( <div> {person.name} {person.age} </div> ) }, compare) export default App
12、跳過不必要的組件更新- useMemo、useCallback緩存優(yōu)化
useMemo、useCallback 實(shí)現(xiàn)穩(wěn)定的 Props 值
useMemo 緩存上次計(jì)算的結(jié)果,當(dāng) useMemo 的依賴未發(fā)生改變時,就不會觸發(fā)重新計(jì)算,一般用在非常耗時的場景中,
如:遍歷大列表做統(tǒng)計(jì)信息。
useCallback ,將父組件傳遞給子組件時,子組件會因?yàn)橹匦聄ender發(fā)生改變的時候,緩存一個值
useCallback 是 React 的一個 Hook,它用于記住函數(shù)的引用,避免在每次渲染時都創(chuàng)建一個新的函數(shù)實(shí)例。這可以幫助優(yōu)化性能,因?yàn)楸苊獠槐匾闹劁秩竞妥咏M件的重新渲染。
使用場景:
當(dāng)你有一個函數(shù),它依賴于某些 props 或 state,但你不希望它在這些依賴發(fā)生變化時重新創(chuàng)建,你可以使用 useCallback 來保持引用不變。
如果你有一個子組件,它是純的(不依賴外部狀態(tài),只依賴于傳入的 props),并且你希望避免非必要的重渲染,你可以使用 useCallback 來保證傳遞給子組件的函數(shù)引用保持不變。
例子代碼:
import React, { useCallback } from 'react'; function ParentComponent() { const [count, setCount] = useState(0); // 使用 useCallback 來避免在每次渲染時都創(chuàng)建一個新的函數(shù)實(shí)例 const incrementCount = useCallback(() => { setCount(count + 1); }, [count]); return ( <div> <p>Count: {count}</p > <button onClick={incrementCount}>Increment</button> ChildComponent onIncrement={incrementCount} /> </div> ); } function ChildComponent({ onIncrement }) { // 這里我們不需要每次 ParentComponent 渲染時都創(chuàng)建一個新的函數(shù)實(shí)例 // 因?yàn)?onIncrement 引用沒有變化 return <button onClick={onIncrement}>Increment from Child</button>; }
在這個例子中,incrementCount 是一個函數(shù),用于增加計(jì)數(shù)。我們使用 useCallback 來保證在 ParentComponent 的多次渲染中,incrementCount 函數(shù)的引用是不變的,這樣 ChildComponent 就不會因?yàn)?ParentComponent 的渲染而不必要地重新渲染。
13、列表使用Key屬性
遍歷展示視圖時使用 key,key 幫助 React 識別哪些元素改變了,比如被添加或刪除。因此你應(yīng)當(dāng)給數(shù)組中的每一個元素賦予一個確定的標(biāo)識
const numbers = [1, 2, 3, 4, 5]; const listItems = numbers.map((number) => <li key={number.toString()}> {number} </li>);
使用 key 注意事項(xiàng):
這個元素在列表中擁有的一個獨(dú)一無二的字符串。通常,我們使用數(shù)據(jù)中的 id 來作為元素的 key
14、不要使用內(nèi)聯(lián)函數(shù)定義:
如果使用內(nèi)聯(lián)函數(shù),函數(shù)是引用數(shù)據(jù)類型,在內(nèi)存中的地址不會相同,則每次render函數(shù)時,都會創(chuàng)建一個新的函數(shù)實(shí)例
在渲染階段會綁定新函數(shù)并將舊實(shí)例扔給垃圾回收,因此綁定內(nèi)聯(lián)函數(shù),需要額外的垃圾回收和綁定到DOM的工作
1.Render(){ Return (<input type=“button” onClick={(e)=>{this.setState({inputVal:e.target.value})}}>) } 2.setNewState=(e)->{this.setState({inputVal:e.target.value})} //箭頭函數(shù)被添加到類的實(shí)例對象屬性而不是原型對象屬性,如果組件被多次重用,每個實(shí)例都會有一個相同的函數(shù)實(shí)例,降低了函數(shù)實(shí)例的可重用性,造成了資源的浪費(fèi) Render(){ Return (<input type=“button” onClick={(e)=>{this.setNewState}/> ) } 3.Export default class a extends React.Component{ constructor(){ this.handleClick = this.handClick.bind(this)//構(gòu)造函數(shù)只執(zhí)行一次 } } handleClick(){xxxxx} <input type=“button” onClick={this.handleClick}/> //render方法每次執(zhí)行時都會調(diào)用bind方法生成新的函數(shù)實(shí)例 <input type=“button” onClick={this.handleClick.bind(this)}/>
15、避免使用內(nèi)聯(lián)樣式
使用內(nèi)聯(lián)樣式時,會被編譯為JavaScript代碼,JavaScript將樣式規(guī)則映射到元素上,瀏覽器需要花費(fèi)更多時間處理腳本和渲染UI。
它是在執(zhí)行時為元素添加樣式,而不是在編譯時為元素添加樣式。
因此,性能非常的低,更好的辦法是將CSS文件導(dǎo)入組件。能通過css直接做的事情,就不要通過JavaScript去做,因?yàn)镴avaScript操作DOM非常慢
16、事件節(jié)流和防抖
利用debounce、throttle 避免重復(fù)回調(diào)
節(jié)流:
意味著不會立即執(zhí)行,在觸發(fā)事件之前會加上幾毫秒延遲,
throttle 更適合需要實(shí)時響應(yīng)用戶的場景中更適合,
如通過拖拽調(diào)整尺寸或通過拖拽進(jìn)行放大縮?。ㄈ纾簑indow 的 resize 事件)。實(shí)時響應(yīng)用戶操作場景中,如果回調(diào)耗時小,
甚至可以用 requestAnimationFrame 代替 throttle。
頁面滾動到底部的時候,使用節(jié)流,否則觸發(fā)多個網(wǎng)絡(luò)請求調(diào)用,導(dǎo)致性能問題
防抖:
在輸入框中鍵入數(shù)據(jù),直到用戶不再輸入數(shù)據(jù)為止,兼容網(wǎng)絡(luò)調(diào)用提升性能
在搜索場景中,只需響應(yīng)用戶最后一次輸入,無需響應(yīng)用戶的中間輸入值,
debounce 更適合使用在該場景中。
到此這篇關(guān)于React Native性能優(yōu)化紅寶書的文章就介紹到這了,更多相關(guān)React Native性能優(yōu)化內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
30行代碼實(shí)現(xiàn)React雙向綁定hook的示例代碼
本文主要介紹了30行代碼實(shí)現(xiàn)React雙向綁定hook的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-04-04Redis數(shù)據(jù)結(jié)構(gòu)面試高頻問題解析
這篇文章主要為大家介紹了Redis數(shù)據(jù)結(jié)構(gòu)高頻面試問題解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-06-06在React中實(shí)現(xiàn)分塊導(dǎo)出大量數(shù)據(jù)表格并壓縮成圖片的解決方案
在現(xiàn)代Web開發(fā)中,處理和展示大量數(shù)據(jù)是一個常見的挑戰(zhàn),特別是在使用React框架時,我們經(jīng)常需要將這些數(shù)據(jù)以表格的形式展示,并提供導(dǎo)出功能,本文將介紹如何在React中實(shí)現(xiàn)一個高效、分塊導(dǎo)出大量數(shù)據(jù)表格,并將其壓縮為圖片的解決方案,需要的朋友可以參考下2024-12-12ReactNative 之FlatList使用及踩坑封裝總結(jié)
本篇文章主要介紹了ReactNative 之FlatList使用及踩坑封裝總結(jié),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-11-11解決react中useState狀態(tài)異步更新的問題
本文主要介紹了react中useState狀態(tài)異步更新的問題,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-07-07