
A melhor prática do React-Native é uma prática recomendada e um pacote nativo de reação e um pacote, que fornece técnicas para aumentar o desempenho, bem como as concessionárias para aumentar o desempenho do aplicativo
Você deve usar o porquê, que você renderiza, que o notifica sobre os renderizadores potencialmente evitáveis.
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/,
] ,
} ) ;
} Importar o código do arquivo acima para o seu aplicativo raiz index.js
Permite pular a reformulação de um componente quando seus adereços permanecem inalterados.
É importante memorizar cálculos pesados, bem como matrizes e criações de objetos, para que eles não sejam recriados em todas as renderizações. Uma renderização ocorre quando o estado muda, o Redux envia alguma ação ou quando o usuário digita uma entrada de texto (renderize novamente para cada pressionamento de teclas). Você não quer executar muitas operações nessas renderizações por razões muito óbvias - portanto, sem filtragem pesada, sem operações de lista, etc.
Um componente puro (ou um componente React.memo ) não renderiza se seus adereços forem rasos iguais .
Cada variável que você criar em sua função de renderização será re-alocada em cada renderização. Embora isso não seja um problema para os tipos de valor , isso faz com que os tipos de referência sejam diferentes em cada renderização. Quando você passa essas variáveis para componentes puros por meio de adereços, eles ainda renderizam novamente, mesmo que os adereços sejam logicamente os mesmos. Muitas vezes, essas variáveis passam por cima da ponte e tornam seu aplicativo lento.
Quando um componente puro se renderiza, ele compara os adereços anteriores aos adereços atuais e verifica se eles são iguais .
Números , cordas e booleanos são tipos de valor , o que significa que eles podem ser comparados pelo valor :
const i1 = 7 ;
const i2 = 7 ;
const equal = i1 === i2 ; // trueObjetos , matrizes e funções são tipos de referência , o que significa que eles não podem ser comparados por seu valor lógico, mas precisam ser comparados por referência :
const o1 = { x : 7 } ;
const o2 = { x : 7 } ;
const equal = o1 === o2 ; // false As comparações de referência simplesmente comparam o endereço de memória da variável; portanto, apenas o1 === o1 seria true no exemplo de código acima.
'
froma melhor prática react-nativa para comparar objetos por igualdade real, mas isso não é mais uma igualdade superficial .
Se você criar objetos em sua função de renderização, eles serão recriados em cada renderização. Isso significa que, quando você cria um objeto na primeira renderização, ele não é igual ao objeto na segunda renderização. Por esse mesmo motivo, existe memórias.
useMemo para memórias e objetos que manterão sua igualdade de referência (e não serão recriados em cada renderização), desde que as dependências (segundo argumento) permaneçam as mesmas. Use também useMemo para cache cache cálculos pesados, como operações de matriz, filtragem etc.useCallback para mempore uma função.useDeepEffect , useDeepCallback , useDeepImperativeHandle e useDeepLayoutEffect FROM import {useDeepEffect, ...} from 'react-native-best-practice'Em geral, os componentes da função podem ser otimizados mais facilmente devido ao conceito de ganchos. No entanto, você pode aplicar técnicas semelhantes para os componentes da classe, apenas saiba que isso resultará em muito mais código.
Embora as animações e tarefas intensivas em desempenho estejam agendadas em threads nativos, toda a sua lógica de negócios é executada em um único thread JavaScript, portanto, certifique -se de fazer o mínimo de trabalho possível lá. Fazer muito trabalho no tópico JavaScript pode ser comparado a um ping alto em um videogame - você ainda pode olhar em volta sem problemas, mas não pode jogar o jogo porque toda interação leva muito tempo.
Os componentes nativos ( <View> , <Text> , <Image> , <Blurhash> , ...) precisam passar adereços para nativos através da ponte. Eles podem ser memorizados, portanto, o React compara os adereços para a igualdade rasa e apenas os passa sobre a ponte se forem diferentes dos adereços da última renderização. Se você não memorar corretamente, poderá passar adereços sobre a ponte para cada renderização, fazendo com que a ponte esteja muito ocupada. Veja o exemplo de estilos - os estilos serão enviados sobre a ponte em cada renderização!
Aqui estão alguns exemplos para ajudar a evitar fazer muito trabalho no seu tópico JavaScript:
return < View style = { [ styles . container , { backgroundColor : 'red' } ] } /> ; const style = useMemo ( ( ) => [ styles . container , { backgroundColor : 'red' } ] , [ ] ) ;
return < View style = { style } /> ;useAnimatedStyle , como esses precisam ser dinâmicos. O uso de operações filter , map ou outra matriz em renderizadores executará toda a operação novamente para cada renderização.
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 > ; Você também pode aplicar isso para renderizar várias visualizações de reação com .map . Eles também podem ser memorizados com useMemo .
return < View onLayout = { ( layout ) => console . log ( layout ) } /> ; const onLayout = useCallback ( ( layout ) => {
console . log ( layout ) ;
} , [ ] ) ;
return < View onLayout = { onLayout } /> ; Certifique -se de pensar também em outras chamadas no renderizador, por exemplo, useSelector , useComponentDidAppear - embrulhe o retorno de chamada lá também!
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 } /> ;
} Isso se aplica a objetos e funções que não dependem do estado ou adereços do componente. Sempre use isso, se puder, pois é ainda mais eficiente que useMemo e useCallback .
const [ me , setMe ] = useState ( users . find ( ( u ) => u . id === myUserId ) ) ; const [ me , setMe ] = useState ( ( ) => users . find ( ( u ) => u . id === myUserId ) ) ; O gancho useState aceita uma função inicializadora. Enquanto o primeiro exemplo ("Bad") executa o .find Encontre cada renderização, o segundo exemplo executa apenas a função aprovada uma vez para inicializar o estado.
Ao escrever novos componentes, sempre coloco uma declaração de log na minha função de renderização para assistir passivamente com que frequência meu componente renderiza enquanto estou trabalhando nela. Em geral, os componentes devem render-se o mínimo possível, e se eu vir muitos troncos aparecendo no meu console, sei que fiz algo errado. É um bom pacto para colocar essa função no seu componente depois de começar a trabalhar nela e removê -la uma vez.
function ComponentImWorkingOn ( ) {
// code
console . log ( 're-rendering ComponentImWorkingOn!' ) ;
return < View /> ;
}Você também pode usar a biblioteca de porquê-de-você para descobrir por que um componente renderizou novamente (mudanças de suporte, mudanças de estado, ...) e possivelmente erram erros desde o início.
React.memo export const MyComponent = ( props ) => {
return ...
} const MyComponentImpl = ( props ) => {
return ...
}
export const MyComponent = React . memo ( MyComponentImpl ) ; Se o seu componente renderizar o mesmo resultado, dado os mesmos adereços, você poderá envolvê -lo em uma chamada para React.memo(...) para um impulso de desempenho em alguns casos, memorando o resultado. Isso significa que o React ignorará o componente e reutilizará o último resultado renderizado. Consulte os documentos oficiais para React.memo e use React.memo(...) sabiamente.
Se o seu aplicativo parecer lento, experimente a biblioteca de desempenho de reação-nativo e o plug-in Flipper para perfilar o desempenho do seu aplicativo em vários aspectos, como tempo para interativos , tempo de renderização de componentes , execução de scripts e muito mais.
Não otimize prematuramente. Alguns exemplos usados aqui (por exemplo, o useMemo ) são muito pequenos e apenas demonstram a idéia. Um gancho como o `useMemo também vem com um custo (alocando a função e a matriz de DEPS, chamando o gancho real e executando uma comparação de matriz); portanto, lembre -se de que geralmente é melhor passar em objetos ou matrizes diretamente se o próprio componente for otimizado. Após uma certa complexidade do componente ou com um certo gráfico de dependência, as funções de memórias podem ser uma grande vitória de desempenho, mas também há casos em que ele leva a um código desnecessariamente complexo e às vezes ainda pior. Sempre benchmark antes e depois!
npm i react-native-best-practice
Todos os argumentos que passam como em React Hooks nativos como
import {useDeepEffect} from 'react-native-best-practice'
useDeepEffect(()=>{
},[recreatedDeepObject])
useDeepEffect => useEffectuseDeepMemo => useMemouseDeepCallback => useCallbackuseDeepImperativeHandle => useImperativeHandleuseDeepLayoutEffect => useLayoutEffectisEqual => verificará profundamente o isEqualcloneDeep => clonará o objeto e a matriz profundamente Sempre ligue o Monitor Pref enquanto desenvolve o aplicativo, pois ele dirá quadros da interface do usuário e quadros JS, se algum quadro cair, você poderá verificar qual novo código está causando para soltar o quadro e fazer com que seu tempo interativo (TTI) seja baixo, você pode abrir o Dev Menu em seu aplicativo e alternar Show Perf Monitor . 
Nunca use a lista plana, sempre use a lista de flash, pois usa o conceito de vistas de reciclagem, que apenas criam e tornam um número limitado de visualizações que são visíveis na tela
Crie uma instância de logger personalizada e aplique emojis para categorizar logs. Dessa forma, é mais fácil identificar linhas relevantes em seu console e parece mais amigável em geral. Faça muitos logs para se salvar de longas noites de depuração posteriormente! 
Sempre use a pilha nativa do @ReactNavigation. Como utiliza primitivas de tela nativas da plataforma, quase sempre vale a pena os ganhos de desempenho sobre a pilha baseada em JS. 
Redux Se você já estiver usando o Redux, use as funções de seleção de seleção para funções "seletor" memorizadas
O contexto do React , se você já estiver usando o contexto do React, deve usar o seletor de uso-contexto para funções "seletor" memorizadas, caso contrário um valor de contexto será alterado, todos os componentes que o UseContext renderá novamente.
Recomendado para usar esses Libs recuo, Jotai Zustand para gerenciamento de estado
Se você precisar fazer algo no componente filho do componente pai, use ref e useimperativehandle para chamar funções de componentes filhos do componente pai em vez de brincar com o estado que passa para o componente infantil
Use o garfo de buffer react-nativo do @craftzdog, ao lidar com muitos buffers para acelerar seu aplicativo. Ele usa implementações apoiadas em C ++ expostas através do JSI, que é aproximadamente 4x mais rápido que a implementação baseada em JS. 
Use o react-native-mmkv para armazenar e recuperar síncronemente dados do armazenamento local, que persistem mesmo no próximo lançamento do aplicativo. Comparado ao LocalStorage na Web, o MMKV também permite criptografar seus dados e ter várias instâncias! 
Use o React-native-Blurhash para mostrar lindos espaços reservados embaçados para suas imagens e vídeos. Gere uma string curta que represente uma versão embaçada do seu conteúdo ("Blurhash") servidor e envie-a junto com seus dados para o aplicativo! 
Ao apresentar números ao usuário, você deve formatá -los na localidade correta (vírgulas, sinais de moeda, ..) enquanto .Tolocalestring (..) faz seu trabalho, você pode realmente construir sua própria instância de número de formação para melhorar o desempenho em ~ 2x! 
Sempre lidar com a área segura inserções adequadamente. Em vez de embrulhar a tela inteira em A, você pode trabalhar com remadores para criar UIs mais limpas.
Aqui, passamos por contentContainerStyle={{ paddingBottom: safeAreaBottom }} para o:
Leia "C ++ moderno eficaz". Mesmo se você não é um desenvolvedor de C ++, este livro o ajudará a entender como o gerenciamento de memória funciona e acredita ou não, afeta como você pensa sobre o React (nativo). Na verdade, esse é o único livro de programação que eu já li
Você entenderá por que {} === {} é falso, como a igualdade de identidade funciona, como os renderizadores são toneladas de alocações, como evitar cópias e muitas outras coisas sobre desempenho que apenas fazem você pensar um pouco diferente ao escrever código. Só não otimize prematuramente?
E se você quiser entrar no desenvolvimento do C ++ com o JSI, é ainda melhor ler este livro - C ++ não é tão perdoador quanto JS. Se você criar uma biblioteca com código C ++ ruim, os usuários o odiarão por fazer o aplicativo Sigabrt?
Nunca use o componente diretamente. Em vez disso, crie sua própria abstração para não se repetir com o nome da fonte, tamanho da fonte ou cores a cada vez e é mais fácil alterar as propriedades a qualquer momento.
Além disso, crie uma regra de Eslint para avisá -lo toda vez que você está tentando usar em vez de ️ 
Ao lidar com grandes números, use o React-native-bigber em vez de qualquer uma das bibliotecas baseadas em JS. ⚡️ É apoiado por uma implementação pura de C ++ e é ~ 330x mais rápido que o BN.js em determinadas aplicações (por exemplo, aplicativos de Crypto, Ethers.js, elípticos, bitcoin) 
Ao trabalhar com #Crypto / Cryptography, use o React-native-Quick-Crypto em vez de qualquer uma das bibliotecas baseadas em JS. ⚡️ É apoiado por uma implementação pura de C ++ e é até 58x mais rápido que o react-nativo-cristão ou a cripto-navegação em certos cenários.
Você pode usar a lanterna para gerar uma pontuação de desempenho para o seu aplicativo Android
Você pode fazer perfil para otimização de desempenho.
Você deve remover console.log do aplicativo Prod como usando declarações console.log reduz o FPS, você pode remover o console.log lendo isso
Graças a Marc Rousavy e Margelo, pois principalmente as melhores práticas são as suas