ScrollView
API
ScrollView是其中最簡單的一個組件,它只是以列表的方式來顯示子組件,并且只會render一次。對于很多應用場景而言這是不好的,當我需要渲染的數(shù)據(jù)data特別大,比如5000條數(shù)據(jù)的時候,我需要等待許久才能看到ScrollView中的東西,并且在我想要進行滑動的時候會感受到明顯的卡頓。嚴重的時候android會ANR。
所以這一特點使得ScrollView一般只有在渲染數(shù)據(jù)量少的情況下才會使用。
應用場景:幻燈片,部分GridView,廣告列表欄...
但有個場景ScrollView非常合適,當item中有很復雜的繪制,比如說有一個View的數(shù)組,那使用
ScrollView在滑動的時候就不會出現(xiàn)VIew數(shù)組重新render的情況,避免一些意想不到的UI問題
ListView
API
這個組件的設(shè)計思路和ScrollView完全不同,ListView基于一個數(shù)據(jù)源,對數(shù)據(jù)源中的每一項數(shù)據(jù)調(diào)用renderRow進行render。并且不會一次性render所有數(shù)據(jù),而是首先render屏幕上能看到的數(shù)據(jù)(假實現(xiàn))。這樣對于內(nèi)存消耗和當數(shù)據(jù)量過大時避免卡頓有所幫助?;谶@種設(shè)計,我們可以在renderRow中使用rowData為數(shù)據(jù)源再嵌套一個子ListView
應用場景:數(shù)據(jù)量多的list
缺點
1.該組件對于render數(shù)據(jù)的優(yōu)化并不完全,一般而言,當數(shù)據(jù)量超過500+后且已經(jīng)滑動到500+行,繼續(xù)滑動屏幕會有明顯卡頓,這是因為ListView的內(nèi)部實現(xiàn)還是ScrollView,react-native的Listview確實就是在scrollView里面不斷添加row,但row移出可見范圍之外后依然還在scrollview里面,不像安卓和ios的在移出視野之外后可以繼續(xù)被后面出來的row復用。。
2.需要繪制分隔線的時候,第一個元素的上面不會繪制分隔線。
3.當數(shù)據(jù)結(jié)構(gòu)比較復雜的時候,比如[{"key":[{},{}...]}, {}...]的時候,默認的section解析方式就不能正確解析出你需要的數(shù)據(jù),需要自己去定義getRowData()和getSectionHeader()來解析數(shù)據(jù)。
有SectionHeader的默認數(shù)據(jù)結(jié)構(gòu):

4.性能問題參考鏈接:
ListView renders all rows?
ListView 性能問題
5.因為FlatList的出世,ListView基本上就是過去式了。
FlatList
API
核心原理 : 用戶看不到的 items,就用空白代替,這樣既節(jié)約內(nèi)存,渲染又快。缺點就是,用戶可能滾動太快,空白還沒被渲染成真的 items,就被看見了。
在官方api中首先強調(diào)的就是這是一個高性能的組件。FlatList應該是實現(xiàn)了 真 ·只 render所見內(nèi)容。因為FlatList是基于 <VirtualizedList>組件進行的封裝。所以有下面的問題需要注意
- 當某行滑出渲染區(qū)域之外后,其內(nèi)部狀態(tài)將不會保留。請確保你在行組件以外的地方保留了數(shù)據(jù)。
- 為了優(yōu)化內(nèi)存占用同時保持滑動的流暢,列表內(nèi)容會在屏幕外異步繪制。這意味著如果用戶滑動的速度超過渲染的速度,則會先看到空白的內(nèi)容。這是為了優(yōu)化不得不作出的妥協(xié),而我們也在設(shè)法持續(xù)改進。
- 本組件繼承自PureComponent而非通常的Component,這意味著如果其props在淺比較中是相等的,則不會重新渲染。所以請先檢查你的renderItem函數(shù)所依賴的props數(shù)據(jù)(包括data
屬性以及可能用到的父組件的state),如果是一個引用類型(Object或者數(shù)組都是引用類型),則需要先修改其引用地址(比如先復制到一個新的Object或者數(shù)組中),然后再修改其值,否則界面很可能不會刷新。 - 默認情況下每行都需要提供一個不重復的key屬性。也可以提供一個keyExtractor函數(shù)來生成key。
由于上述Flatist做出的優(yōu)化而會導致一個問題,如果在每個Item中有個從網(wǎng)絡拿的Image,那么在list很長的情況下,底部的部分數(shù)據(jù)的Image可能永遠都無法顯示。
注意 : 這里可以看到FlatList特性的解釋和一個官方的例子 FlatList Features & Example
為什么使用FlatList而非ListView
首先是在大數(shù)據(jù)量的情況下,F(xiàn)latList性能更好。其次,ListView和FlatList的使用方式基本一致,ListView很容易轉(zhuǎn)換為FlatList。最后,F(xiàn)latList對于app而言具有良好的擴展性