React ile büyük liste performansı


86

React ile filtrelenebilir bir liste oluşturma sürecindeyim. Listenin yapısı aşağıdaki resimde gösterildiği gibidir.

görüntü açıklamasını buraya girin

ÖNCÜL

İşte nasıl çalışması gerektiğine dair bir açıklama:

  • Devlet, en üst düzey bileşen olan Searchbileşende bulunur.
  • Durum şu şekilde açıklanmaktadır:
{
    görünür: boole,
    dosyalar: dizi,
    filtrelenmiş: dizi,
    sorgu: dize,
    şu andaSelectedIndex: tamsayı
}
  • files dosya yolları içeren potansiyel olarak çok büyük bir dizidir (10000 giriş makul bir sayıdır).
  • filteredkullanıcı en az 2 karakter yazdıktan sonra filtrelenen dizidir. Türev verilerinin olduğunu biliyorum ve bu nedenle, eyalette saklamakla ilgili bir argüman yapılabilir, ancak
  • currentlySelectedIndex bu, filtrelenmiş listeden seçili öğenin dizinidir.

  • Kullanıcı Inputbileşene 2'den fazla harf yazarsa, dizi filtrelenir ve filtrelenmiş dizideki her giriş için bir Resultbileşen oluşturulur

  • Her Resultbileşen, sorguyla kısmen eşleşen tam yolu görüntüler ve yolun kısmi eşleşme kısmı vurgulanır. Örneğin, bir Sonuç bileşeninin DOM'si, kullanıcı 'le' yazmış olsaydı, şöyle bir şey olurdu:

    <li>this/is/a/fi<strong>le</strong>/path</li>

  • Kullanıcı, Inputbileşene odaklanırken yukarı veya aşağı tuşlarına basarsa , currentlySelectedIndexdeğişiklikler filtereddiziye göre değişir . Bu Result, dizinle eşleşen bileşenin yeniden oluşturmaya neden olacak şekilde seçili olarak işaretlenmesine neden olur

SORUN

Başlangıçta bunu filesReact'in geliştirme sürümünü kullanarak yeterince küçük bir dizi ile test ettim ve hepsi iyi çalıştı.

files10000 giriş kadar büyük bir diziyle uğraşmak zorunda kaldığımda sorun ortaya çıktı . Giriş'e 2 harf yazmak büyük bir liste oluşturur ve gezinmek için yukarı ve aşağı tuşlarına bastığımda çok gecikmeli olurdu.

İlk başta elemanlar için tanımlı bir bileşene sahip Resultdeğildim ve listeyi yalnızca Searchbileşenin her renderında anında yapıyordum, şöyle ki:

results  = this.state.filtered.map(function(file, index) {
    var start, end, matchIndex, match = this.state.query;

     matchIndex = file.indexOf(match);
     start = file.slice(0, matchIndex);
     end = file.slice(matchIndex + match.length);

     return (
         <li onClick={this.handleListClick}
             data-path={file}
             className={(index === this.state.currentlySelected) ? "valid selected" : "valid"}
             key={file} >
             {start}
             <span className="marked">{match}</span>
             {end}
         </li>
     );
}.bind(this));

Anlayabileceğiniz gibi, her currentlySelectedIndexdeğiştiğinde, yeniden oluşturmaya neden olur ve liste her seferinde yeniden oluşturulur. keyHer bir lielemente bir değer koyduğum için, React'in değişikliğe uğramamış her diğer lielementi yeniden oluşturmaktan kaçınacağını düşündüm className, ama görünüşe göre öyle değildi.

ResultÖğeler için bir sınıf tanımlamayı bitirdim, burada her Resultöğenin daha önce seçilip seçilmediğine ve mevcut kullanıcı girdisine göre yeniden oluşturulup oluşturulmayacağını açıkça kontrol ediyor :

var ResultItem = React.createClass({
    shouldComponentUpdate : function(nextProps) {
        if (nextProps.match !== this.props.match) {
            return true;
        } else {
            return (nextProps.selected !== this.props.selected);
        }
    },
    render : function() {
        return (
            <li onClick={this.props.handleListClick}
                data-path={this.props.file}
                className={
                    (this.props.selected) ? "valid selected" : "valid"
                }
                key={this.props.file} >
                {this.props.children}
            </li>
        );
    }
});

Liste artık şu şekilde oluşturulmuştur:

results = this.state.filtered.map(function(file, index) {
    var start, end, matchIndex, match = this.state.query, selected;

    matchIndex = file.indexOf(match);
    start = file.slice(0, matchIndex);
    end = file.slice(matchIndex + match.length);
    selected = (index === this.state.currentlySelected) ? true : false

    return (
        <ResultItem handleClick={this.handleListClick}
            data-path={file}
            selected={selected}
            key={file}
            match={match} >
            {start}
            <span className="marked">{match}</span>
            {end}
        </ResultItem>
    );
}.bind(this));
}

Bu, performansı biraz daha iyi hale getirdi , ancak yine de yeterince iyi değil. React'in üretim versiyonunu test ettiğimde işler sorunsuz çalıştı, hiç gecikme olmadı.

SONUÇ OLARAK

React'in geliştirme ve üretim sürümleri arasında bu kadar belirgin bir tutarsızlık normal mi?

React'in listeyi nasıl yönettiğini düşündüğümde anlıyor muyum / yanlış bir şey yapıyor muyum?

GÜNCELLEME 14-11-2016

Michael Jackson'ın buna çok benzer bir sorunu ele aldığı bu sunumunu buldum: https://youtu.be/7S8v8jfLb1Q?t=26m2s

Çözüm, AskarovBeknar'ın aşağıdaki cevabının önerdiği çözümle çok benzer.

GÜNCELLEME 14-4-2018

Bu görünüşe göre popüler bir soru olduğundan ve asıl soru sorulduğundan beri işler ilerlediğinden, sanal bir düzeni kavramak için yukarıda bağlantısı verilen videoyu izlemenizi öneririm, ayrıca sizi React Virtualized'i kullanmanızı tavsiye ederim tekerleği yeniden icat etmek istemiyorsanız kitaplık.


React'in geliştirme / üretim versiyonu ile neyi kastediyorsunuz?
Dibesjr


Ah anlıyorum, teşekkürler. Yani sorularınızdan birini yanıtlamak için, sürümler arasında optimizasyonda bir tutarsızlık olduğunu söylüyor. Büyük listelerde dikkat edilmesi gereken bir şey, render'ınızda işlevler oluşturmaktır. Dev listelere girdiğinizde bir performans vuruşu olacak. Mükemmel araçlarını kullanarak bu listeyi oluşturmanın ne kadar sürdüğünü görmeye
çalışırdım

2
Redux kullanmayı yeniden düşünmeniz gerektiğini düşünüyorum çünkü burada tam olarak ihtiyacınız olan şey (veya herhangi bir tür akı uygulaması). Bu sunuma kesinlikle bir göz atmalısınız: Büyük Liste Yüksek Performanslı React & Redux
Pierre Criulanscy

2
Bir kullanıcının 10000 sonuç arasında gezinmenin herhangi bir yararı olduğundan şüpheliyim. Peki ya sadece ilk 100 sonucu oluşturursanız ve bunları sorguya göre güncellerseniz.
Koen.

Yanıtlar:


18

Bu soruya verilen diğer yanıtların çoğunda olduğu gibi, temel sorun, filtreleme yaparken ve anahtar olayları işlerken DOM'da bu kadar çok öğeyi oluşturmanın yavaş olacağı gerçeğinde yatmaktadır.

Soruna neden olan React ile ilgili olarak doğası gereği yanlış bir şey yapmıyorsunuz, ancak performansla ilgili birçok sorun gibi kullanıcı arabirimi de suçun büyük bir yüzdesini alabilir.

Kullanıcı arabiriminiz verimlilik göz önünde bulundurularak tasarlanmadıysa, performans için tasarlanmış React gibi araçlar bile zarar görür.

Sonuç kümesini filtrelemek, @Koen tarafından belirtildiği gibi harika bir başlangıçtır

Bu fikirle biraz oynadım ve bu tür problemlerle nasıl başa çıkabileceğimi gösteren örnek bir uygulama oluşturdum.

Bu kesinlikle bir production readykod değildir, ancak kavramı yeterince açıklar ve daha sağlam olması için değiştirilebilir, koda bir göz atmaktan çekinmeyin - umarım en azından size bazı fikirler verir ...;)

react-large-list-example

görüntü açıklamasını buraya girin


1
Sadece tek bir cevap seçmek zorunda olduğum için gerçekten üzülüyorum, hepsinde çaba sarf edilmiş gibi görünüyor, ancak şu anda PC'siz tatildeyim ve hak ettikleri ilgiyi gerçekten kontrol edemiyorum. Bunu seçtim çünkü yeterince kısa ve bir telefondan okurken bile anlamak için. Bildiğim kötü sebep.
Dimitris Karagiannis

Ana bilgisayar dosyasını düzenlemekle ne demek istiyorsun 127.0.0.1 * http://localhost:3001?
stackjlei

@stackjlei 127.0.0.1'i localhost'a eşlemeyi kastettiğini düşünüyorum : 3001 / etc / hosts
Maverick

16

Çok benzer bir sorunla ilgili deneyimim, DOM'da aynı anda 100-200'den fazla bileşen varsa tepki vermenin gerçekten zarar görmesidir. shouldComponentUpdateYalnızca yeniden oluşturmada bir veya iki bileşeni değiştirmek için çok dikkatli olsanız (tüm anahtarlarınızı ayarlayarak ve / veya bir yöntem uygulayarak ) bile, yine de canınız yanacak.

Şu anda reaksiyonun yavaş olan kısmı, sanal DOM ile gerçek DOM arasındaki farkı karşılaştırmasıdır. Binlerce bileşene sahipseniz ancak yalnızca bir çiftini güncelliyorsanız, önemli değil, react'in DOM'lar arasında yine de büyük bir fark işlemi vardır.

Sayfaları şimdi yazdığımda, onları bileşenlerin sayısını en aza indirecek şekilde tasarlamaya çalışıyorum, bunu büyük bileşen listelerini oluştururken yapmanın bir yolu, büyük bileşen listelerini oluşturmamaktır.

Demek istediğim şu: yalnızca şu anda görebildiğiniz bileşenleri oluşturun, aşağı kaydırdıkça daha fazlasını oluşturun, kullanıcının binlerce bileşen arasında herhangi bir şekilde aşağı kaydırma olasılığı yoktur ... Umarım.

Bunu yapmak için harika bir kütüphane:

https://www.npmjs.com/package/react-infinite-scroll

Burada harika bir nasıl yapılır:

http://www.reactexamples.com/react-infinite-scroll/

Korkarım sayfanın üst kısmında olmayan bileşenleri kaldırmaz, bu nedenle yeterince uzun süre kaydırırsanız performans sorunları yeniden ortaya çıkmaya başlayacaktır.

Cevap olarak bir bağlantı sağlamanın iyi bir uygulama olmadığını biliyorum, ancak verdikleri örnekler bu kütüphaneyi burada yapabileceğimden çok daha iyi nasıl kullanabileceğimi açıklayacak. Umarım büyük listelerin neden kötü olduğunu açıkladım, ama aynı zamanda bir çalışma.


2
Güncelleme: Bu cevaptaki paket korunmuyor. Npmjs.com/package/react-infinite-scroller
Ali Al Amine

11

Her şeyden önce, React'in geliştirme ve üretim versiyonu arasındaki fark çok büyük çünkü üretimde birçok baypas edilmiş akıl sağlığı kontrolü var (örneğin pervane türlerinin doğrulanması).

Ardından, Redux kullanmayı yeniden düşünmeniz gerektiğini düşünüyorum çünkü ihtiyacınız olan şey (veya herhangi bir tür akı uygulaması) için burada son derece yararlı olacaktır. Bu sunuma kesinlikle bir göz atmalısınız: Büyük Liste Yüksek Performanslı React & Redux .

Ancak yeniden düzenlemeye geçmeden önce, bileşenlerinizi daha küçük bileşenlere bölerek React kodunuzda bazı düzeltmeler yapmanız gerekir çünkü shouldComponentUpdate çocukların oluşturmasını tamamen atlayacaksınız, bu yüzden bu çok büyük bir kazanç .

Daha ayrıntılı bileşenlere sahip olduğunuzda, veri akışını daha iyi organize etmek için durumu yeniden düzenleme ve tepki-yeniden düzenleme ile halledebilirsiniz.

Geçenlerde bin satır oluşturmam ve her satırı içeriğini düzenleyerek değiştirebilmem gerektiğinde benzer bir sorunla karşı karşıyaydım. Bu mini uygulama, olası yinelenen konserlere sahip konserlerin bir listesini görüntüler ve potansiyel kopyayı, onay kutusunu işaretleyerek orijinal bir konser (kopya değil) olarak işaretlemek ve gerekirse, konserin adı. Belirli bir potansiyel yinelenen öğe için hiçbir şey yapmazsam, yinelenmiş olarak kabul edilecek ve silinecektir.

İşte böyle görünüyor :

görüntü açıklamasını buraya girin

Temel olarak 4 ana bileşen vardır (burada yalnızca bir satır vardır, ancak örnek için bu):

görüntü açıklamasını buraya girin

: İşte (CodePen çalışan tam kodudur Tepki & Redux ile Büyük Liste kullanarak) redux , -redux tepki , değişmez , yeniden seçin ve recompose :

const initialState = Immutable.fromJS({ /* See codepen, this is a HUGE list */ })

const types = {
    CONCERTS_DEDUP_NAME_CHANGED: 'diggger/concertsDeduplication/CONCERTS_DEDUP_NAME_CHANGED',
    CONCERTS_DEDUP_CONCERT_TOGGLED: 'diggger/concertsDeduplication/CONCERTS_DEDUP_CONCERT_TOGGLED',
};

const changeName = (pk, name) => ({
    type: types.CONCERTS_DEDUP_NAME_CHANGED,
    pk,
    name
});

const toggleConcert = (pk, toggled) => ({
    type: types.CONCERTS_DEDUP_CONCERT_TOGGLED,
    pk,
    toggled
});


const reducer = (state = initialState, action = {}) => {
    switch (action.type) {
        case types.CONCERTS_DEDUP_NAME_CHANGED:
            return state
                .updateIn(['names', String(action.pk)], () => action.name)
                .set('_state', 'not_saved');
        case types.CONCERTS_DEDUP_CONCERT_TOGGLED:
            return state
                .updateIn(['concerts', String(action.pk)], () => action.toggled)
                .set('_state', 'not_saved');
        default:
            return state;
    }
};

/* configureStore */
const store = Redux.createStore(
    reducer,
    initialState
);

/* SELECTORS */

const getDuplicatesGroups = (state) => state.get('duplicatesGroups');

const getDuplicateGroup = (state, name) => state.getIn(['duplicatesGroups', name]);

const getConcerts = (state) => state.get('concerts');

const getNames = (state) => state.get('names');

const getConcertName = (state, pk) => getNames(state).get(String(pk));

const isConcertOriginal = (state, pk) => getConcerts(state).get(String(pk));

const getGroupNames = reselect.createSelector(
    getDuplicatesGroups,
    (duplicates) => duplicates.flip().toList()
);

const makeGetConcertName = () => reselect.createSelector(
    getConcertName,
    (name) => name
);

const makeIsConcertOriginal = () => reselect.createSelector(
    isConcertOriginal,
    (original) => original
);

const makeGetDuplicateGroup = () => reselect.createSelector(
    getDuplicateGroup,
    (duplicates) => duplicates
);



/* COMPONENTS */

const DuplicatessTableRow = Recompose.onlyUpdateForKeys(['name'])(({ name }) => {
    return (
        <tr>
            <td>{name}</td>
            <DuplicatesRowColumn name={name}/>
        </tr>
    )
});

const PureToggle = Recompose.onlyUpdateForKeys(['toggled'])(({ toggled, ...otherProps }) => (
    <input type="checkbox" defaultChecked={toggled} {...otherProps}/>
));


/* CONTAINERS */

let DuplicatesTable = ({ groups }) => {

    return (
        <div>
            <table className="pure-table pure-table-bordered">
                <thead>
                    <tr>
                        <th>{'Concert'}</th>
                        <th>{'Duplicates'}</th>
                    </tr>
                </thead>
                <tbody>
                    {groups.map(name => (
                        <DuplicatesTableRow key={name} name={name} />
                    ))}
                </tbody>
            </table>
        </div>
    )

};

DuplicatesTable.propTypes = {
    groups: React.PropTypes.instanceOf(Immutable.List),
};

DuplicatesTable = ReactRedux.connect(
    (state) => ({
        groups: getGroupNames(state),
    })
)(DuplicatesTable);


let DuplicatesRowColumn = ({ duplicates }) => (
    <td>
        <ul>
            {duplicates.map(d => (
                <DuplicateItem
                    key={d}
                    pk={d}/>
            ))}
        </ul>
    </td>
);

DuplicatessRowColumn.propTypes = {
    duplicates: React.PropTypes.arrayOf(
        React.PropTypes.string
    )
};

const makeMapStateToProps1 = (_, { name }) => {
    const getDuplicateGroup = makeGetDuplicateGroup();
    return (state) => ({
        duplicates: getDuplicateGroup(state, name)
    });
};

DuplicatesRowColumn = ReactRedux.connect(makeMapStateToProps1)(DuplicatesRowColumn);


let DuplicateItem = ({ pk, name, toggled, onToggle, onNameChange }) => {
    return (
        <li>
            <table>
                <tbody>
                    <tr>
                        <td>{ toggled ? <input type="text" value={name} onChange={(e) => onNameChange(pk, e.target.value)}/> : name }</td>
                        <td>
                            <PureToggle toggled={toggled} onChange={(e) => onToggle(pk, e.target.checked)}/>
                        </td>
                    </tr>
                </tbody>
            </table>
        </li>
    )
}

const makeMapStateToProps2 = (_, { pk }) => {
    const getConcertName = makeGetConcertName();
    const isConcertOriginal = makeIsConcertOriginal();

    return (state) => ({
        name: getConcertName(state, pk),
        toggled: isConcertOriginal(state, pk)
    });
};

DuplicateItem = ReactRedux.connect(
    makeMapStateToProps2,
    (dispatch) => ({
        onNameChange(pk, name) {
            dispatch(changeName(pk, name));
        },
        onToggle(pk, toggled) {
            dispatch(toggleConcert(pk, toggled));
        }
    })
)(DuplicateItem);


const App = () => (
    <div style={{ maxWidth: '1200px', margin: 'auto' }}>
        <DuplicatesTable />
    </div>
)

ReactDOM.render(
    <ReactRedux.Provider store={store}>
        <App/>
    </ReactRedux.Provider>,
    document.getElementById('app')
);

Büyük veri kümesiyle çalışırken bu mini uygulamayı yaparak öğrenilen dersler

  • React bileşenleri en iyi şekilde küçük tutulduğunda çalışır
  • Yeniden seçim, yeniden hesaplamayı önlemek ve aynı argümanlara verilen aynı referans nesnesini (immutable.js kullanırken) korumak için çok yararlı hale gelir.
  • connectBileşenin yalnızca kullanmadıkları sahne öğelerini aktarmasını önlemek için ihtiyaç duydukları verilere en yakın olan bileşen için ed bileşeni oluşturun
  • MapDispatchToProps oluşturmak için kumaş işlevinin kullanılması, yalnızca verilen ilk pervaneye ihtiyaç duyduğunuzda ownProps, gereksiz yeniden oluşturmayı önlemek için gereklidir.
  • React & redux kesinlikle birlikte rock!

2
OP'nin sorununu çözmek için yeniden düzenlemeye bir bağımlılık eklemenin gerekli olduğunu düşünmüyorum, sonuç kümesini filtrelemek için daha fazla gönderme eylemi yalnızca sorunu daha da karmaşık hale getirir, gönderiler düşündüğünüz kadar ucuz değildir, bu özel durumu yerel bileşenle ele alır. devlet en etkili yaklaşımdır
deowk

4
  1. Geliştirme sürümünde tepki, geliştirme sürecini kolaylaştırmak için her bileşenin mülkiyet tipini kontrol ederken, üretimde bu ihmal edilir.

  2. Dizge listesinin filtrelenmesi, her anahtarlama için çok pahalı bir işlemdir. JavaScript'in tek iş parçacıklı yapısı nedeniyle performans sorunlarına neden olabilir. Çözüm kullanmak olabilir filtreleme gecikme süresi kadar filtre fonksiyonunun gecikme yürütme yöntemini.

  3. Başka bir sorun da büyük listenin kendisi olabilir. Sanal düzen oluşturabilir ve yalnızca verileri değiştirerek oluşturulan öğeleri yeniden kullanabilirsiniz. Temel olarak, içine liste kabı yerleştireceğiniz sabit yükseklikte kaydırılabilir kap bileşeni oluşturursunuz. Liste kapsayıcısının yüksekliği, bir kaydırma çubuğunun çalışması için, görünür listenin uzunluğuna bağlı olarak manuel olarak ayarlanmalıdır (öğeYüksekliği * sayıÖğeler). Ardından, kaydırılabilir kapların yüksekliğini doldurmaları ve belki fazladan bir veya iki mimik sürekli liste efekti eklemeleri için birkaç öğe bileşeni oluşturun. onları mutlak bir konuma getirin ve kaydırıldığında, sürekli listeyi taklit etmesi için konumlarını hareket ettirin (Sanırım bunu nasıl uygulayacağınızı öğreneceksiniz :)

  4. Bir şey daha DOM'a yazmak, özellikle yanlış yaparsanız pahalı bir işlemdir. Listeleri görüntülemek için tuvali kullanabilir ve kaydırmada sorunsuz bir deneyim oluşturabilirsiniz. React-canvas bileşenlerini kontrol edin. Listeler üzerinde bazı çalışmalar yaptıklarını duydum.


Hakkında herhangi bir bilgi React in development? ve neden her bir bileşenin protoytiplerini kontrol ediyor?
Liuuil

4

React Virtualized Select'e göz atın, bu sorunu çözmek için tasarlanmıştır ve deneyimimde etkileyici bir performans sergiliyor. Açıklamadan:

Bir açılır menüde büyük seçenek listelerini görüntülemek için react-sanallaştırılmış ve react-select kullanan HOC

https://github.com/bvaughn/react-virtualized-select


4

Sanki geçen benim yorumum , ben kullanıcılar aynı anda tarayıcıda tüm bu 10000 sonuçlarını ihtiyaç şüpheliyim.

Ya sonuçları gözden geçirirseniz ve her zaman sadece 10 sonuçtan oluşan bir liste gösterirseniz.

Ben ettik bir örnek oluşturdu Redux Başka bir kitaplık kullanmadan, bu teknik kullanılarak. Şu anda yalnızca klavye gezintisi var, ancak kaydırmada da çalışmak için kolayca genişletilebilir.

Örnek 3 bileşenden oluşur, konteyner uygulaması, bir arama bileşeni ve bir liste bileşeni. Neredeyse tüm mantık, konteyner bileşenine taşındı.

İşin özü start, selectedsonucu ve sonucunu takip etmek ve bunları klavye etkileşiminde değiştirmektir.

nextResult: function() {
  var selected = this.state.selected + 1
  var start = this.state.start
  if(selected >= start + this.props.limit) {
    ++start
  }
  if(selected + start < this.state.results.length) {
    this.setState({selected: selected, start: start})
  }
},

prevResult: function() {
  var selected = this.state.selected - 1
  var start = this.state.start
  if(selected < start) {
    --start
  }
  if(selected + start >= 0) {
    this.setState({selected: selected, start: start})
  }
},

Tüm dosyaları bir filtreden geçirirken:

updateResults: function() {
  var results = this.props.files.filter(function(file){
    return file.file.indexOf(this.state.query) > -1
  }, this)

  this.setState({
    results: results
  });
},

Ve dayanan sonuçlar dilimleme startve limitiçinde renderyöntemle:

render: function() {
  var files = this.state.results.slice(this.state.start, this.state.start + this.props.limit)
  return (
    <div>
      <Search onSearch={this.onSearch} onKeyDown={this.onKeyDown} />
      <List files={files} selected={this.state.selected - this.state.start} />
    </div>
  )
}

Tam bir çalışma örneği içeren Fiddle: https://jsfiddle.net/koenpunt/hm1xnpqk/


3

React bileşenine yüklemeden önce filtreyi deneyin ve bileşende yalnızca makul miktarda öğe gösterin ve talep üzerine daha fazlasını yükleyin. Bu kadar çok öğeyi aynı anda kimse görüntüleyemez.

Öyle olduğunu sanmıyorum, ama dizinleri anahtar olarak kullanmayın .

Geliştirme ve üretim sürümlerinin farklı olmasının gerçek nedenini bulmak profilingiçin kodunuzu deneyebilirsiniz .

Sayfanızı yükleyin, kayda başlayın, bir değişiklik yapın, kaydı durdurun ve ardından zamanlamaları kontrol edin. Chrome'da performans profili oluşturma talimatları için buraya bakın .


2

Bu problemle mücadele eden herkes için bir bileşen yazdım react-big-list için 1 milyona kadar kaydı içeren listeleri işleyen .

Üstelik, aşağıdaki gibi bazı süslü ekstra özelliklerle birlikte gelir:

  • Sıralama
  • Önbelleğe almak
  • Özel filtreleme
  • ...

Bazı uygulamalarda üretimde kullanıyoruz ve harika çalışıyor.


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.