
React-Native-Best-Espractice 는 반응 네이티브 모범 사례 및 패키지로, 성능 향상 기술과 앱의 성능을 높이는 유틸리티를 제공합니다.
피할 수없는 리 러더에 대해 알려주는 이유가있는 이유를 사용해야합니다.
import React from 'react' ;
const useWDYR = __DEV__ ;
if ( useWDYR ) {
const whyDidYouRender = require ( '@welldone-software/why-did-you-render' ) ;
whyDidYouRender ( React , {
// Enable tracking in all pure components by default
trackAllPureComponents : true ,
trackHooks : true ,
include : [
// Uncomment to enable tracking in all components. Must also uncomment /^Screen/ in exclude.
// /.*/,
// Uncomment to enable tracking by displayName, e.g.:
// /^Components/,
] ,
exclude : [
// Uncomment to enable tracking in all components
// /^Components/,
] ,
} ) ;
} 위의 파일 코드를 앱 루트 index.js 로 가져옵니다
소품이 변경되지 않을 때 구성 요소를 다시 렌더링하는 건너 뛸 수 있습니다.
무거운 계산과 배열 및 객체 창조물을 메모하여 모든 렌더링에서 재창조되지 않도록하는 것이 중요합니다. 상태가 변경되거나 Redux가 일부 작업을 파견하거나 사용자가 텍스트 입력에 입력 할 때 (모든 단일 키 프레스에 대해 리 렌더)를 입력 할 때 재 러너가 발생합니다. 당신은 매우 명백한 이유로 그 렌더링에서 많은 작업을 실행하고 싶지 않습니다. 따라서 무거운 필터링, 목록 작업 없음 등.
소품이 얕은 경우 순수한 구성 요소 (또는 React.memo 구성 요소)는 다시 렌더링되지 않습니다.
렌더링 함수에서 생성 한 각 변수는 각 렌더마다 재 할당됩니다. 이것은 값 유형 의 경우 문제가되지 않지만 렌더링마다 참조 유형이 다릅니다. 해당 변수를 소품을 통해 순수한 구성 요소 로 전달하면 소품이 논리적으로 동일하더라도 여전히 다시 렌더링됩니다. 종종 이러한 변수는 다리를 넘어 앱을 느리게 만듭니다.
순수한 구성 요소가 렌더링되면 이전 소품을 현재 소품과 비교하고 얕은 지 확인합니다.
숫자 , 문자열 및 부울은 가치 유형 이므로 값으로 비교할 수 있습니다.
const i1 = 7 ;
const i2 = 7 ;
const equal = i1 === i2 ; // true객체 , 배열 및 함수 는 참조 유형 이므로 논리적 값으로 비교할 수 없지만 참조로 비교 해야합니다.
const o1 = { x : 7 } ;
const o2 = { x : 7 } ;
const equal = o1 === o2 ; // false 참조 비교는 단순히 변수의 메모리 주소를 비교하므로 위의 코드 예제에서 o1 === o1 만 true 입니다.
'반응 신용-최고의 실습에서'비평 적 '
from물체를 실제 평등으로 비교하지만 더 이상 얕은 평등은 아닙니다.
렌더링 함수에서 객체를 생성하면 모든 단일 렌더마다 재창조됩니다. 이것은 첫 번째 렌더에서 객체를 만들 때 두 번째 렌더의 객체에 대해 참조와 평등 하지 않다는 것을 의미합니다. 바로 이런 이유로 메모리가 존재합니다.
useMemo 후크를 사용하여 의존성 (두 번째 인수)이 동일하게 유지되는 한, 기준 평등을 유지하고 각 렌더링에 다시 제작하지 않을 배열 및 객체를 메모 화하십시오. 또한 useMemo 사용하여 배열 작업, 필터링 등과 같은 무거운 계산을 캐시합니다.useCallback 후크를 사용하여 함수를 메모 화하십시오.useDeepCallback 다시 만들고 있지만 동일한 값을 가질 수 useDeepImperativeHandle ' useDeepEffect import {useDeepEffect, ...} from 'react-native-best-practice' useDeepLayoutEffect일반적으로 후크 개념으로 인해 기능 구성 요소를보다 쉽게 최적화 할 수 있습니다. 그러나 클래스 구성 요소에 유사한 기술을 적용 할 수 있습니다. 이로 인해 더 많은 코드가 생길 수 있습니다.
애니메이션 및 성능 집약적 인 작업은 기본 스레드에서 예약되지만 전체 비즈니스 로직은 단일 JavaScript 스레드에서 실행되므로 가능한 한 적은 작업을 수행해야합니다. JavaScript 스레드에서 너무 많은 작업을 수행하면 비디오 게임에서 높은 핑과 비교할 수 있습니다. 여전히 원활하게 둘러 볼 수 있지만 모든 상호 작용이 너무 오래 걸리기 때문에 게임을 할 수는 없습니다.
기본 구성 요소 ( <View> , <Text> , <Image> <Blurhash> 그것들은 메모 화 될 수 있으므로 React는 얕은 평등에 대한 소품을 비교하고 마지막 렌더와 다른 소품과는 다른 경우에만 다리 위로 전달합니다. 올바르게 메모하지 않으면 모든 단일 렌더마다 다리 위로 소품을 전달하여 다리가 매우 점유 될 수 있습니다. 스타일 예제를 참조하십시오 - 스타일은 모든 재 렌더로 다리 위로 보내집니다!
다음은 JavaScript 스레드에서 너무 많은 작업을 피하는 데 도움이되는 몇 가지 예입니다.
return < View style = { [ styles . container , { backgroundColor : 'red' } ] } /> ; const style = useMemo ( ( ) => [ styles . container , { backgroundColor : 'red' } ] , [ ] ) ;
return < View style = { style } /> ;useAnimatedStyle 의 리안 화 된 스타일은 역동적이어야하므로. 렌더러에서 filter , map 또는 기타 배열 작업을 사용하면 모든 렌더마다 전체 작업이 다시 실행됩니다.
return (
< Text > { users . filter ( ( u ) => u . status === 'online' ) . length } users online </ Text >
) ; const onlineCount = useMemo (
( ) => users . filter ( ( u ) => u . status === 'online' ) . length ,
[ users ]
) ;
return < Text > { onlineCount } users online </ Text > ; .map 사용하여 여러 React보기를 렌더링하기 위해 이것을 적용 할 수도 있습니다. 그것들은 useMemo 와 함께 메모 될 수 있습니다.
return < View onLayout = { ( layout ) => console . log ( layout ) } /> ; const onLayout = useCallback ( ( layout ) => {
console . log ( layout ) ;
} , [ ] ) ;
return < View onLayout = { onLayout } /> ; 렌더러 (예 : useSelector useComponentDidAppear 의 다른 통화에 대해 생각해보십시오. 콜백도 마무리하십시오!
function MyComponent ( props ) {
return < PressableOpacity onPress = { ( ) => props . logoutUser ( ) } /> ;
} function MyComponent ( props ) {
return < PressableOpacity onPress = { props . logoutUser } /> ;
} function MyComponent ( props ) {
return (
< RecyclerListView scrollViewProps = { { horizontal : props . isHorizontal } } />
) ;
} function MyComponent ( props ) {
const scrollViewProps = useMemo (
( ) => ( {
horizontal : props . isHorizontal ,
} ) ,
[ props . isHorizontal ]
) ;
return < RecyclerListView scrollViewProps = { scrollViewProps } /> ;
} function MyComponent ( ) {
return < RecyclerListView scrollViewProps = { { horizontal : true } } /> ;
} const SCROLL_VIEW_PROPS = { horizontal : true } ;
function MyComponent ( ) {
return < RecyclerListView scrollViewProps = { SCROLL_VIEW_PROPS } /> ;
} 이는 객체 및 구성 요소의 상태 또는 소품에 의존하지 않는 함수에도 적용됩니다. useMemo 및 useCallback 보다 훨씬 효율적이기 때문에 가능한 경우 항상 이것을 사용하십시오.
const [ me , setMe ] = useState ( users . find ( ( u ) => u . id === myUserId ) ) ; const [ me , setMe ] = useState ( ( ) => users . find ( ( u ) => u . id === myUserId ) ) ; useState hook는 초기화 기능을 허용합니다. 첫 번째 예제 ( "BAD")는 모든 렌더마다 .find 를 실행하지만 두 번째 예제는 전달 된 기능을 한 번만 실행하여 상태를 초기화합니다.
새로운 구성 요소를 쓸 때 나는 항상 내 렌더링 함수에 로그 명령문을 넣어 작업 중일 때 내 구성 요소가 얼마나 자주 재 렌더링하는지를 시청합니다. 일반적으로 구성 요소는 가능한 한 적게 렌더링해야하며 콘솔에 많은 로그가 나타나면 뭔가 잘못된 것을 알고 있습니다. 작업을 시작한 후에이 기능을 구성 요소에 넣고 한 번 제거하는 것이 좋습니다.
function ComponentImWorkingOn ( ) {
// code
console . log ( 're-rendering ComponentImWorkingOn!' ) ;
return < View /> ;
}또한 왜 Did-You Render Library를 사용하여 구성 요소가 왜 재 렌더링되었는지 (Prop Change, State Changes, ...) 왜 일찍 실수를 잡을 수 있는지 알아낼 수 있습니다.
React.memo export const MyComponent = ( props ) => {
return ...
} const MyComponentImpl = ( props ) => {
return ...
}
export const MyComponent = React . memo ( MyComponentImpl ) ; 구성 요소가 동일한 소품이 주어진 동일한 결과를 동일한 결과를 렌더링하면 결과를 메모하여 성능 향상을 위해 React.memo(...) 를 호출 할 수 있습니다. 즉, RECT는 구성 요소 렌더링을 건너 뛰고 마지막으로 렌더링 된 결과를 재사용 할 수 있습니다. React.memo 의 공식 문서를보고 React.memo(...) 현명하게 사용하십시오.
앱이 느리게 느껴지면 반응성 성능 형성 라이브러리를 사용해보십시오. Flipper 플러그인을 사용하여 대화식 시간 , 구성 요소 렌더링 시간 , 스크립트 실행 등과 같은 다양한 측면에서 앱의 성능을 프로파일 링하십시오.
조기에 최적화하지 마십시오. 여기에 사용 된 몇 가지 예 (예 : useMemo One)는 매우 작으며 아이디어 만 보여줍니다. `usememo와 같은 후크에는 비용이 제공되므로 (함수와 DEP 배열을 할당하고, 실제 후크를 호출하고 배열 비교를 실행) 구성 요소 자체가 최적화되면 객체 나 배열을 직접 전달하는 것이 좋습니다. 특정 구성 요소 복잡성 또는 특정 종속성 그래프를 사용한 후, 메모 링 함수는 성능이 큰 승리가 될 수 있지만 불필요하게 복잡한 코드로 이어지고 때로는 성능이 나빠지는 경우도 있습니다. 항상 전후에 벤치 마크!
npm i react-native-best-practice
네이티브 React Hooks 에서와 같이 모든 인수가 통과합니다
import {useDeepEffect} from 'react-native-best-practice'
useDeepEffect(()=>{
},[recreatedDeepObject])
useDeepEffect => useEffectuseDeepMemo => useMemouseDeepCallback => useCallbackuseDeepImperativeHandle => useImperativeHandleuseDeepLayoutEffect => useLayoutEffectisEqual =>는 isequal을 깊이 점검합니다cloneDeep =>는 물체와 배열을 깊이 복제합니다 UI 프레임 속도 및 JS 프레임 속도를 알려주는 앱을 개발하는 동안 항상 Pref Monitor를 켜십시오. 프레임이 떨어지면 프레임을 떨어 뜨리고 대화식 (TTI)을 낮추는 데 시간을내는 새로운 코드를 확인할 수 있으므로 앱에서 Dev Menu 열고 Show Perf Monitor 할 수 있습니다. 
플랫리스트를 사용하지 말고, 화면에서 볼 수있는 제한된 수의 뷰 만 생성하고 렌더링하는 재활용 뷰의 개념을 사용하므로 항상 플래시리스트를 사용하십시오.
커스텀 로거 인스턴스를 작성하고 이모티콘을 시행하여 로그를 분류하십시오. 이렇게하면 콘솔에서 관련 라인을 발견하기가 더 쉽고 전반적으로 더 친절 해 보입니다. 나중에 디버깅의 긴 밤에서 자신을 구하기 위해 많은 로깅을하십시오! 
항상 @reactnavigation의 기본 스택을 사용하십시오. 플랫폼 네이티브 스크린 프리미티브를 사용하기 때문에 거의 항상 JS 기반 스택에 대한 성능 향상 가치가 있습니다. 
Redux 이미 Redux를 사용하고 있다면 메모 화 된 "선택기"기능에 대한 Reselect를 사용해야합니다.
React Context 이미 React Context를 사용하고 있다면 메모 화 된 "선택기"기능에 사용 된 컨텍스트-선택기를 사용해야합니다. 그렇지 않으면 컨텍스트 값이 변경됩니다.
이 Libs Recoil, Jotai Zustand를 사용하여 주 경영진
부모 구성 요소에서 아동 구성 요소에서 무언가를 해야하는 경우, 자녀 구성 요소로 전달되는 상태를 가지고 재생하는 대신 자녀 구성 요소에서 기능을 호출하는 데 ref 및 useimperative handle을 사용하십시오.
많은 버퍼를 처리하여 앱 속도를 높이기 위해 @craftzdog의 React-Native-Buffer Fork를 사용하십시오. JSI를 통해 노출 된 C ++ 백업 구현을 사용합니다.이 구현은 JS 기반 구현보다 약 4 배 빠릅니다. 
React-Native-MMKV를 사용하여 다음 앱 출시에서도 지속되는 로컬 스토리지에서 데이터를 동기화하고 검색하십시오. MMKV는 웹의 LocalStorage와 비교하여 데이터를 암호화하고 여러 인스턴스를 가질 수 있습니다! 
Real-Native-Blurhash를 사용하여 이미지와 비디오에 대한 아름다운 흐릿한 자리 표시자를 보여줍니다. 컨텐츠의 흐릿한 버전 ( "Blurhash") 서버 측을 나타내는 짧은 문자열을 생성하고 데이터와 함께 앱으로 보내십시오! 
사용자에게 숫자를 제시 할 때는 숫자를 올바른 로케일 (쉼표, 통화 부호 등으로 포맷해야하지만 .tolocalestring (..)은 작업을 수행하는 반면 실제로 자신의 NumberFormat 인스턴스를 구성하여 성능을 ~ 2x로 향상시킬 수 있습니다! 
항상 안전한 지역 삽입물을 적절하게 처리하십시오. 전체 화면을 A로 감싸는 대신 패딩으로 작업하여 클리너 UI를 만들 수 있습니다.
여기, 우리는 contentContainerStyle={{ paddingBottom: safeAreaBottom }} 다음과 같이 통과했습니다.
"효과적인 현대 C ++"을 읽으십시오. C ++ 개발자가 아니더라도이 책은 메모리 관리가 어떻게 작동하는지 이해하는 데 도움이 될 것입니다.이 책은 React (Native)에 대한 생각에 영향을 미칩니다. 사실 제가 읽은 유일한 프로그래밍 책입니다.
{} === {}가 거짓 인 이유, 정체성 평등이 어떻게 작동하는지, 리 러더가 수많은 할당 수준, 사본을 피하는 방법 및 코드를 작성할 때 조금 다르게 생각하게하는 성능에 대한 다른 많은 것들을 이해할 수 있습니다. 조기에 최적화하지 않습니까?
그리고 JSI로 C ++ 개발에 들어가고 싶다면이 책을 읽는 것이 더 좋습니다. C ++는 JS만큼 용서하지 않습니다. C ++ 코드가 잘못된 라이브러리를 만들면 사용자가 앱 Sigabrt를 만드는 것에 대해 미워합니까?
구성 요소를 직접 사용하지 마십시오. 대신, 자신만의 추상화를 만들어서 매번 글꼴 이름, 글꼴 크기 또는 색상으로 자신을 반복하지 않으며 언제든지 속성을 변경하는 것이 더 쉽습니다.
또한 닐 대신 사용하려고 할 때마다 경고하기 위해 Eslint 규칙을 작성하십시오. 
다수를 다룰 때는 JS 기반 라이브러리 대신 React-Native-Bignumber를 사용하십시오. ⚡️ 순수한 C ++ 구현으로 뒷받침되며 특정 응용 프로그램에서 BN.JS보다 ~ 330 배 빠릅니다 (예 : #Crypto Apps, Ethers.js, Elliptic, Bitcoin) 
#Crypto / cryptography로 작업 할 때 JS 기반 라이브러리 대신 React-Native-Quick-Crypto를 사용하십시오. ⚡️ 순수한 C ++ 구현에 의해 뒷받침되며 특정 시나리오에서 반응-신용-크립토 또는 암호화 브라우저보다 최대 58 배 빠릅니다.
Android 앱의 성능 점수를 생성하기 위해 손전등을 사용할 수 있습니다.
성능 최적화를 위해 프로파일 링을 할 수 있습니다.
console.log console.log 해야합니다. Log 문은 FPS를 낮추면 Console.Log를 제거 하여이 글로그를 제거 할 수 있습니다.
Marc Rousavy와 Margelo 덕분에 대부분 모범 사례는