javascript - Hur sparar man en renderad komponent i minnet?


Jag utvecklar en React Native-applikation (även om jag tror att mitt problem gäller React i allmänhet) som består av flera skärmar.

Så jag har skapat en enkel komponent för att byta mellan skärmarna:

import React, { Component } from 'react';
import { connect } from 'react-redux'
import { View } from 'react-native';

class AppNavComponent extends Component {

    constructor() {
        super();
        this.screenCache_ = {};
    }

    render() {
        if (!this.props.route) throw new Error('Route must not be null');
        let route = this.props.route;
        if (this.screenCache_[route.routeName]) return this.screenCache_[route.routeName];
        let Screen = this.props.screens[route.routeName].screen;

        this.screenCache_[route.routeName] = (
            <View>
                <Screen/>
            </View>
        );

        return this.screenCache_[route.routeName];
    }

}

const AppNav = connect(
    (state) => {
        return {
            route: state.route,
        };
    }
)(AppNavComponent)

export { AppNav };

this.props.screens innehåller listan över skärmar, och this.props.route den rutt som behöver visas. Komponent fungerar bra, men mitt problem är att jag skulle vilja cacha vissa skärmar i minnet eftersom de är långsamma att rendera (en stor lista) och de tappar scrollpositionen varje gång React renderar om dem.

I exemplet ovan har jag försökt spara renderingen till this.screenCache_ men det är förmodligen inte rätt tillvägagångssätt eftersom skärmarna fortfarande renderas om när jag laddar dem, går till en annan sida och går tillbaka till dem.

Jag antar att det är ett vanligt problem men jag kan inte hitta någon information på Google. Några förslag på hur man gör detta?

Svar #1

Det finns inget sätt att effektivt cachelagra komponenten på det sätt du gör, eftersom DOM fortfarande skulle behöva måla om den senare, vilket är den tunga delen.

En enklare lösning, och jag tror att Slack gör det bakom kulisserna, är att istället använda display: none.

<View style={shouldDisplayScreen ? {} : { display: none }} />

PS. Du kanske vill ställa in shouldComponentUpdate till false om komponenten för närvarande inte visas för att undvika prestandaproblem.

Svar #2

Ditt första svar bör inte vara att cachea saker i React. Det finns många andra sätt att öka prestandan. Börja med att läsa prestandasektionen i deras dokumentation. Det finns några väldigt enkla lösningar för att öka prestandan direkt.

React Native-dokumentation: Prestanda

Några andra saker du kan göra för att öka prestandan:

  1. Ta bort console.loggarna och andra loggare.
  2. Använd componentShouldUpdate för att säkerställa att du bara renderar om när det behövs.
  3. Om du använder redux, ta en titt på Selectors. Om du har data som behöver beräknas och du gör onödiga repetitiva beräkningar kan du memorera den datan.

Jag tror att ditt problem kommer från något i React Native-dokumentationen, så gå igenom de sakerna först innan du försöker göra saker överdrivet komplicerade.

Som en referenspunkt, en av mina kompisar gjorde nyligen en VR-applikation som gjorde flera beräkningar som uppdaterade redux-tillståndet varje gång gyroskopet rörde sig och renderade om objekt på DOM:en hundratals gånger per sekund. React Native kan hantera mycket, så oroa dig inte för caching än.