Redux 애플리케이션 스토어를 분할하여 애플리케이션 성능을 향상시키는 방법
24947 단어 reactperformancereduxjavascript
사용자가 전자상거래 사이트의 홈 페이지(react &redux)에 접근하고 있다고 가정하십시오.최상의 효과time to interactive를 얻기 위해javascript 패키지는 홈 페이지의 접는 부분에 필요한 UI 구성 요소만 포함해야 합니다.우리는 이 페이지에 접근하기 전에 제품 목록이나 결산 코드를 불러와서는 안 된다.
이를 위해 다음을 수행할 수 있습니다.
구성 요소와 달리 메인 패키지는 홈 페이지에 필요한 복원기만 있는 것이 아니라 모든 복원기를 가지고 있다.저희가 못하는 이유는요. -
store.js -imports-> rootReducer.js -imports-> reducer.js(files)
따라서 저장된 데이터가 주 구성 요소나 수요에 따라 사용되더라도 상점의 의존 관계 트리는 응용 프로그램의 모든 축소기를 포함한다.mapStateToProps
는 런타임 함수입니다.하지만 잠시만요. 개발 과정에서 Reducer 코드를 업데이트할 때마다 제 상점은 웹 팩의 열 모듈을 통해 업데이트합니다.이게 어떻게 된 일입니까?네, 이 때문에 루트 리덕터를 다시 만들고 store를 사용합니다.Reducer API를 대체합니다.그것은 단일 감속기를 전환하거나 새 감속기를 추가하는 것처럼 간단하지 않다.
moduleB
가져오기moduleA
의 경우 moduleB
는 moduleA
의 의존 항목이고, moduleC
가져오기moduleB
의 경우 생성된 의존 트리는 - moduleA -> moduleB -> moduleC
. 웹 팩과 같은 귀속기는 이 의존 트리를 돌아다니며 코드 라이브러리를 귀속합니다.Webpack은 코드 라이브러리의 모듈을 훑어보고 브라우저에서 불러올 패키지를 생성합니다.
reactredux 응용 프로그램의 전형적인 구조를 봅시다 -
// rootReducer.js
export default combineReducers({
home: homeReducer,
productList: productListReducer
});
// store.js
export default createStore(rootReducer/* , initialState, enhancer */);
// Root.js
import store from './store';
import AppContainer from './AppContainer';
export default function Root() {
return (
<Provider store={store}>
<AppContainer />
</Provider>
);
}
먼저 rootReducer와redux 저장소를 만들고 루트 구성 요소를 가져옵니다.이것은 다음과 같은 의존 관계 트리를 생성할 것이다RootComponent.js
|_store.js
| |_rootReducer.js
| |_homeReducer.js
| |_productListReducer.js
|_AppContainer.js
|_App.js
|_HomePageContainer.js
| |_HomePage.js
|_ProductListPageContainer.js
|_ProductListPage.js
우리의 목표는 store와 AppContainer의 의존 트리를 통합하는 것이다 -따라서 하나의 구성 요소가 코드로 분리될 때 웹팩은 이 구성 요소와 해당하는 축소기를 필요에 따라 블록에 묶는다.필요한 의존 관계 트리가 어떤 모습일지 봅시다. -
RootComponent.js
|_AppContainer.js
|_App.js
|_HomePageContainer.js
| |_HomePage.js
| |_homeReducer.js
|_ProductListPageContainer.js
|_ProductListPage.js
|_productListReducer.js
니가 관찰하면의존 관계 트리에 저장이 없다는 것을 알 수 있습니다!위의 종속성 트리에서
ProductListPageContainer
이 AppContainer
에서 동적으로 가져옵니다.웹팩은 현재 주 블록이 아니라 수요에 따라 구축되고 있다.이제 이 점을 어떻게 실현할지 생각해 봅시다!
Redux store는
productListReducer
을 rootReducer
의 첫 번째 매개 변수로 기대합니다.이 제한이 생기면 우리는 두 가지 일이 필요해-createStore
전에 컨테이너에 이경관 바인딩rootReducer
-// HomePageContainer.js
import storeManager from 'react-store-manager';
import homeReducer from './homeReducer';
storeManager.registerReducers({ home: homeReducer });
export default connect(/* mapStateToProps, mapDispatchToProps */)(HomePage);
// ProductListPageContainer.js
import storeManager from 'react-store-manager';
import productListReducer from './productListReducer';
storeManager.registerReducers({ productList: productListReducer });
export default connect(/* mapStateToProps, mapDispatchToProps */)(ProductListPage);
// AppContainer.js
import storeManager from 'react-store-manager';
const HomeRoute = Loadable({
loader: import('./HomePageContainer'),
loading: () => <div>Loading...</div>
});
const ProductListRoute = Loadable({
loader: import('./ProductListPageContainer'),
loading: () => <div>Loading...</div>
});
function AppContainer({login}) {
return (
<App login={login}>
<Switch>
<Route exact path="/" component={HomeRoute} />
<Route exact path="/products" component={ProductListRoute} />
</Switch>
</App>
);
}
export default connect(/* mapStateToProps, mapDispatchToProps */)(AppContainer);
// Root.js
import storeManager from 'react-store-manager';
import AppContainer from './AppContainer';
export default function Root() {
return (
<Provider store={storeManager.createStore(/* initialState, enhancer */)}>
<AppContainer />
</Provider>
);
}
RootComponent를 설치할 때 Reducer를 등록하고 저장소를 만들면 됩니다.이제 필요한 의존 나무가 생겼어요.RootComponent.js
|_AppContainer.js
|_App.js
|_HomePageContainer.js
| |_HomePage.js
| |_homeReducer.js
|_ProductListPageContainer.js
|_ProductListPage.js
|_productListReducer.js
이제 동적 가져오기 온디맨드 로딩 rootReducer
을 사용하면 storeManager
도 온디맨드 블록으로 이동합니다.만세!임무 완수?...거의.
문제는 수요에 따라 블록을 불러올 때 -
ProductListPageContainer
수요에 따라 블록에 존재하는 호출은store Manager에 복원기를 등록하지만 새로운 등록 복원기를 포함하는 새로운 productListReducer
리셋 저장소를 사용하지 않습니다.따라서 저장된 루트 Reducer를 업데이트하려면 Redux의 저장을 사용해야 합니다.Reducer API를 대체합니다.따라서 동적으로 하위 세대 (
sm.registerReducers()
의 부모 세대 (rootReducer
를 불러올 때 AppContainer.js
호출만 실행합니다.따라서 ProductListPageContainer.js
데이터에 접근하거나 sm.refreshStore()
데이터 포인트에 대한 조작을 시작하기 전에 이 저장소는 productListReducer
를 가지고 있다.// AppContainer.js
import {withRefreshedStore} from 'react-store-manager';
const HomeRoute = Loadable({
loader: withRefreshedStore(import('./HomePageContainer')),
loading: () => <div>Loading...</div>
});
const ProductListRoute = Loadable({
loader: withRefreshedStore(import('./ProductListPageContainer')),
loading: () => <div>Loading...</div>
});
function AppContainer({login}) {
return (
<App login={login}>
<Switch>
<Route exact path="/" component={HomeRoute} />
<Route exact path="/products" component={ProductListRoute} />
</Switch>
</App>
);
}
우리는 ProductListPageContainer
어떻게 우리의 목표를 실현하는 데 도움을 줄 수 있는지 보았다.구현 -import { createStore, combineReducers } from 'redux';
const reduceReducers = (reducers) => (state, action) =>
reducers.reduce((result, reducer) => (
reducer(result, action)
), state);
export const storeManager = {
store: null,
reducerMap: {},
registerReducers(reducerMap) {
Object.entries(reducerMap).forEach(([name, reducer]) => {
if (!this.reducerMap[name]) this.reducerMap[name] = [];
this.reducerMap[name].push(reducer);
});
},
createRootReducer() {
return (
combineReducers(Object.keys(this.reducerMap).reduce((result, key) => Object.assign(result, {
[key]: reduceReducers(this.reducerMap[key]),
}), {}))
);
},
createStore(...args) {
this.store = createStore(this.createRootReducer(), ...args);
return this.store;
},
refreshStore() {
this.store.replaceReducer(this.createRootReducer());
},
};
export const withRefreshedStore = (importPromise) => (
importPromise
.then((module) => {
storeManager.refreshStore();
return module;
},
(error) => {
throw error;
})
);
export default storeManager;
상술한 코드 세그먼트를 코드 라이브러리의 모듈로 사용할 수도 있고, 아래에 열거한 npm 패키지를 사용할 수도 있습니다 - 사지비나시 / redux 상점 매니저
redux 메모리 관리자를 사용하여 redux 메모리를 성명적으로 분할하고 용기에 전체 redux 흐름을 가지도록 합니다
redux 상점 매니저
redux 메모리 관리자를 사용하여 redux 메모리를 성명적으로 분할하고 용기에 전체 redux 흐름을 가지도록 합니다
설치
실 추가 redux 상점 매니저
문제
솔루션
이것은 용기가 링크를 통해 전체redux 흐름을 가지게 한다
mapDispatchToProps를 통해 구성 요소 도구로 사용하는 동작
Reducer는 storeManager를 통해 데이터를 업데이트합니다.레지스트리 삭제기
mapStateToProps를 통해 데이터를 구성 요소 도구로 사용
아직 개발되지 않은 구축 최적화 분야에 대한 인사:)
이 콘셉트 좋아해요? - 글을 공유하고 git 환매에 별을 추가하십시오:)
Reference
이 문제에 관하여(Redux 애플리케이션 스토어를 분할하여 애플리케이션 성능을 향상시키는 방법), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/websavi/how-to-code-split-redux-store-to-further-improve-your-apps-performance-4gg9텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)