source

React-Redux 앱은 Backbone과 같이 확장할 수 있습니까?재선택을 해도.온모바일

ittop 2023. 3. 28. 22:34
반응형

React-Redux 앱은 Backbone과 같이 확장할 수 있습니까?재선택을 해도.온모바일

마다 Redx가 .notify접속되어 있는 모든 컴포넌트.이를 통해 개발자는 매우 단순해지지만 N개의 컴포넌트가 연결된 애플리케이션이 있고 N개의 컴포넌트가 매우 크면 어떻게 될까요?

모든 됩니다.shouldComponentUpdate===reselect가게의 ed 경로.빠르죠?네, 한 번쯤은요.하지만 모든 변화에 대해 N배?설계의 근본적인 변화는 Redux의 진정한 확장성을 의심하게 합니다.

더 최적화하기 , 것을 할 수 .notify를 한 콜, " "_.debounce해도 을 있다===모든 스토어 변경 및 기타 로직(예: 뷰 로직)에 대한 테스트는 목적을 위한 수단처럼 보입니다.

저는 수백만 명의 사용자를 가진 건강 & 피트니스 소셜 모바일 웹 하이브리드 애플리케이션을 개발하고 있으며 Backbone에서 Redux로 전환 입니다.이 응용 프로그램에서는 사용자에게 Snapchat과 유사한 다양한 뷰 스택 사이를 이동할 수 있는 스와이핑 가능한 인터페이스가 제공됩니다. 단, 각 스택의 깊이는 무한합니다.가장 일반적인 형태에서는 엔드리스 스크롤러가 포스트와 같은 피드 아이템의 로드, 렌더링, 탈부착을 효율적으로 처리합니다.참여 사용자에게는 수백, 수천 개의 게시물을 스크롤하여 사용자의 피드, 다른 사용자의 피드 등을 입력하는 것이 일반적입니다.높은 최적화를 실시해도 접속하는 컴포넌트의 수는 매우 많아질 수 있습니다.

한편, Backbone의 디자인은 모든 뷰가 Backbone에 영향을 미치는 모델을 정확하게 들을 수 있도록 하여 N을 일정하게 줄입니다.

제가 뭔가를 놓쳤나요? 아니면 Redux가 큰 앱에 근본적으로 결함이 있나요?

이것은 Redux IMHO 고유의 문제가 아닙니다.

덧붙여서 100k 컴포넌트를 동시에 렌더링하는 것이 아니라 react-infinite와 같은 lib로 위장하고 목록의 보이는(또는 가까운) 항목만 렌더링해야 합니다.100k 목록을 렌더링 및 업데이트해도 성능이 떨어지고 메모리도 많이 필요합니다.Linked In 어드바이스를 몇 가지 소개합니다.

개의 하고 , 의 리스너anwser' DOM' 10)는 원하지 않는 합니다.store.subscribe()이치노


두 학교

UI 앱을 기능적으로 개발할 때는 기본적으로 두 가지 선택지가 있습니다.

항상 맨 위에서 렌더링

그것은 잘 작동하지만 더 많은 보일러 플레이트를 필요로 한다.이 방법은 권장되는 Redux 방법은 아니지만 달성할 수 있지만 몇 가지 단점도 있습니다.단일 리덕스 접속을 유지하더라도 여전히 많은 리덕스 접속을 위해shouldComponentUpdate많은 곳에서요.) 의 무한 , 와 ('재귀'와 같은) 가상 돔을 합니다.shouldComponentUpdate아, 네, 네, 네, 네요.따라서 1개의 접속이 있어도 이 방법은 그다지 효율적이지 않습니다.

React 라이프 사이클 메서드를 사용하지 않고 순수 렌더 기능만 사용하는 경우 decu(Redux와 함께 사용할 수 있음)와 같이 해당 작업에만 집중하는 다른 유사한 옵션을 고려해야 합니다.

제 경험상 React를 사용하는 것은 오래된 모바일 디바이스(Nexus4 등)에서는 충분한 퍼포먼스가 없습니다.특히 텍스트 입력을 atom 상태에 링크하는 경우에는 더욱 그렇습니다.

하위 구성 요소에 데이터 연결

리액트 리덕스가 제안하는 것은connect상태가 변경되어 하위 하위 항목에만 관련된 경우 해당 하위 항목만 렌더링하고 컨텍스트 공급자(redux/intl/custom...)나 메인 앱 레이아웃처럼 매번 최상위 구성 요소를 렌더링할 필요가 없습니다..shouldComponentUpdate듣는 사람에게 이미 전달된 내용이기 때문에 다른 아이에게도 전달될 수 있습니다.매우 빠른 청취자에게 전화를 거는 것은 중간 반응 컴포넌트를 매번 렌더링하는 것보다 빠를 수 있습니다.또한 소품 통과 보일러 플레이트를 많이 줄일 수 있기 때문에 React와 함께 사용하면 의미가 있습니다.

또한 아이덴티티 비교는 매우 빠르고 변경 시에도 많은 작업을 쉽게 수행할 수 있습니다.Angular의 더러운 체크에 대해 기억하라: 어떤 사람들은 그것을 사용하여 실제 앱을 만들 수 있었다!아이덴티티 비교가 훨씬 빠릅니다.


문제의 이해

당신의 개 정도의 있습니다.또, 10개의 아이템을 에 대해서도 하고 있습니다.connect10만 명의 청취자에게 전화할 때마다 비용이 많이 들기 때문에 10만일 변경 시마다 10만 명의 청취자를 호출하는 것은 비용이 많이 들기 때문입니다.

이 문제는 UI를 사용한 기능 프로그래밍의 본질에 기인하는 것으로 보입니다.목록이 갱신되었기 때문에 목록을 재렌더해야 합니다만, 유감스럽게도 리스트는 매우 길고 효율적이지 않은 것 같습니다.Backbone을 사용하면 아이를 렌더링하기 위해 무언가를 해킹할 수 있습니다.React를 사용하여 하위 항목을 렌더링하더라도 "목록이 변경될 때 다시 렌더링"을 선언하는 대신 반드시 렌더링을 트리거할 수 있습니다.


문제 해결

10만 리액트 리덕스 청취자를 호출하여 10만 리액트 리덕스 항목을 연결하는 것은 분명 편리해 보이지만 성능은 떨어집니다.

각 항목이 아닌 10만 개 항목의 큰 목록을 연결할 경우 단일 react-redux 리스너만 호출하고 해당 목록을 효율적으로 렌더링해야 합니다.


순진한 해결법

개 됩니다.shouldComponentUpdate 단 만 다시 1개만 더 하다.

list.map(item => this.renderItem(item))

커스텀1: 커스텀1: 커스텀connect + store enhancer + store enhancer

connectReact-Redux 방법은 랩된 컴포넌트에 데이터를 주입하는 고차 컴포넌트(HOC)일 뿐입니다.이를 위해 A가 등록한다.store.subscribe(...)모든 접속 컴포넌트의 리스너.

단일 리스트의 10만 아이템을 연결하려면 최적화할 가치가 있는 앱의 중요한 경로입니다.의 「」를 에, 「」를 합니다.connect직접 만들 수도 있어요

  1. 스토어 인핸서

메서드 「」를 공개합니다.store.subscribeItem(itemId,listener)

dispatch따라서 항목과 관련된 액션이 발송될 때마다 해당 항목의 등록된 리스너를 호출할 수 있습니다.

이 구현에 대한 좋은 영감의 원천은 redex-batched-subscribe입니다.

  1. 커스텀 커넥트

다음과 같은 API를 사용하여 상위 컴포넌트를 만듭니다.

Item = connectItem(Item)

는 HOC를 할 수 .itemId할 수 .리액션 리덕스store.subscribeItem(itemId,callback) 소스 ★★★★★★★★★★★★★★★★★★★★★★★★★★★★」connect기본 영감이 될 수 있습니다.

  1. HOC는 항목이 변경된 경우에만 재렌더링을 트리거합니다.

관련 답변: https://stackoverflow.com/a/34991164/82609

관련 react-paramx 문제: https://github.com/rackt/react-redux/issues/269

퍼포먼스 솔루션 2: 자 컴포넌트 내부의 이벤트 듣기

또한 redex-dispatch-subscribe 등을 사용하여 구성 요소에서 Redux 작업을 직접 들을 수 있으므로 첫 번째 목록을 렌더링한 후 항목 구성 요소에 대한 업데이트를 직접 수신하고 상위 목록의 원래 데이터를 재정의할 수 있습니다.

class MyItemComponent extends Component {
  state = {
    itemUpdated: undefined, // Will store the local
  };
  componentDidMount() {
    this.unsubscribe = this.props.store.addDispatchListener(action => {
      const isItemUpdate = action.type === "MY_ITEM_UPDATED" && action.payload.item.id === this.props.itemId;
      if (isItemUpdate) {
        this.setState({itemUpdated: action.payload.item})
      }
    })
  }
  componentWillUnmount() {
    this.unsubscribe();
  }
  render() {
    // Initially use the data provided by the parent, but once it's updated by some event, use the updated data
    const item = this.state.itemUpdated || this.props.item;
    return (
      <div>
        {...}
      </div>
    );
  }
}

경우, 「 」redux-dispatch-subscribe아직 10만 개의 서브스크립션을 생성하기 때문에 퍼포먼스가 그다지 높지 않을 수 있습니다. 보는 것 같습니다.redux-dispatch-subscribe【API】【와 같은 store.listenForItemChanges(itemId)항목 리스너를 맵으로 저장하여 실행할 올바른 리스너를 빠르게 검색...


퍼포먼스 솔루션 3: 벡터 시행

보다 성능적인 접근방식은 벡터 트라이와 같은 영속적인 데이터 구조를 사용하는 것을 고려합니다.

트리

각 더 수 많은 의 아이템목록을 할 수 .shouldComponentUpdate아이일 때.

이 기술은 불변과 함께 사용할 수 있습니다.JS와 당신은 내가 불변으로 한 실험을 찾을 수 있다.리액트 퍼포먼스: PureRenderMixin을 사용한 빅리스트 렌더링 단점이 있지만 ImputableJs와 같은 libs는 아직 공개 API/안정 API를 공개하지 않고(문제 발생), 내 솔루션은 DOM을 쓸모없는 중간 매개체로 오염시킵니다.<span>노드(문제)

여기 JsFiddle이 있습니다. 불변의 법칙이JS의 10만 항목 목록을 효율적으로 렌더링할 수 있습니다.초기 렌더링은 꽤 길지만(단, 10만 아이템으로 앱을 초기화하지 않는 것 같습니다!) 업데이트마다 소량만 발생한다는 것을 알 수 있습니다.shouldComponentUpdate마다 첫개의 항목이 .목록에 10만 개의 항목이 있어도110개의 콜만 있으면 됩니다.shouldComponentUpdate더 받아들여질까 :) which which which which which which which which which which which which which which which which which which which which which : )

편집: 불변인 것 같다JS는 랜덤 인덱스에서 항목을 삽입/삭제하는 것과 같은 일부 작업에서 불변의 구조를 유지하는 데 그다지 적합하지 않습니다.여기 JsFiddle이 있습니다.목록의 조작에 따라 기대할 수 있는 퍼포먼스를 나타냅니다.의외로 많은 항목을 큰 목록의 끝에 추가하려면list.push(value) 나무 를 더 .list.concat(values).

덧붙여서, 가장자리를 수정할 때 List가 효율적이라는 것은 문서화되어 있습니다.특정 인덱스에서 추가/삭제 시 이러한 나쁜 성능은 내 기술과 관련이 있는 것이 아니라 기본 UnmutableJs List 구현과 관련이 있다고 생각합니다.

엔드(푸시, 팝)와 시작(비시프트, 시프트) 모두에서 효율적인 추가 및 제거 기능을 갖춘 구현 Deque를 나열합니다.

이것은 여러분이 찾고 있는 것보다 더 일반적인 답변일 수 있지만, 대략적으로 다음과 같습니다.

  1. Redux 문서에서는 컴포넌트 계층에서 상당히 높은 위치에 React 컴포넌트를 연결할 것을 권장합니다.이 섹션을 참조하십시오.이렇게 하면 연결 수를 관리할 수 있으며 업데이트된 소품을 하위 구성요소로 전달할 수 있습니다.
  2. React의 성능과 확장성의 일부는 보이지 않는 컴포넌트의 렌더링을 회피하는 데서 비롯됩니다.를 들어, '하다'를 ,invisibleDOM 요소의 클래스는 리액트에서는 컴포넌트를 전혀 렌더링하지 않습니다.가상 DOM 확산 프로세스는 낮은 수준의 DOM 상호 작용을 최적화하므로 변경되지 않은 컴포넌트의 재렌더링도 전혀 문제가 되지 않습니다.

언급URL : https://stackoverflow.com/questions/34782249/can-a-react-redux-app-really-scale-as-well-as-say-backbone-even-with-reselect

반응형