Bài viết trước, mình đã chia sẻ một số thủ thuật nhỏ để cải thiện performance của Javascript. Tất cả những thủ thuật đó bạn đều có thể áp dụng để hiệu năng ứng dụng react native. Vì vậy, nếu bạn chưa đọc nó, hãy đọc lại ngay bây giờ nhé!
Riêng với React Native, mình còn có một số thủ thuật khác nữa để tiếp tục tối ưu performance ứng dụng, cải thiện tốc độ ứng dụng React Native hơn nữa. Qua đó, ứng dụng của bạn sẽ mượt mà hơn, trải nghiệm người dùng luôn được đảm bảo.
Hãy cùng tìm hiểu nhé!
Nội dung chính của bài viết
- Cải thiện hiệu năng ứng dụng React Native bằng cách nào?
- #1. Nên sử dụng PureComponent hoặc shouldComponentUpdate khi có thể
- #2. Sử dụng key attribute khi duyệt Array/List
- #3. Bind ngay khi có thể và đừng tạo functions bên trong hàm render
- #4. Không cập nhật state hoặc gửi actions bên trong componentWillUpdate
- #5. Sử dụng VirtualizedList, FlatList và SectionList cho các tập dữ liệu lớn làm cho tốc độ React Native được tối ưu
- #6. Sử dụng Perf monitor để theo dõi FPS
- #Tạm kết
Cải thiện hiệu năng ứng dụng React Native bằng cách nào?
Thông thường, khi bắt tay vào dự án thì việc code chạy đúng yêu cầu của khách hàng là quan trọng nhất. Việc tối ưu hiệu năng ngay từ đầu làm được thì tốt nhưng nếu quá sa đà vào nó thì sẽ làm chậm tiến độ dự án.
Do vậy, việc tối ưu hiệu suất ứng dụng thường sẽ được tiến hành ở giai đoạn sau của dự án.
Tuy nhiên, dưới đây là những lỗi rất đơn giản, mình nghĩ bạn có thể lưu ý và tránh nó ngay từ đầu, nhằm tối ưu tốc độ cho ứng dụng.
#1. Nên sử dụng PureComponent hoặc shouldComponentUpdate khi có thể
Mình sẽ giải thích qua nguyên lý hoạt động của 2 tính năng này:
PureComponent
trong React không có state, chúng chỉ render các component dựa trên dữ liệu được truyền qua props. Nó chỉ được render lại khi và chỉ khi props bị thay đổi.shouldComponentUpdate
được sử dụng trong Component React để hủy việc render lại bằng cách trả về false trong một số tình huống nhất định.
Để dễ hình dùng hơn, chúng ta cùng xem ví dụ dưới đây:
class MyComponent extends React.PureComponent { // } class MyComponent extends React.Component { // shouldComponentUpdate(nextProps, nextState) { if(this.props.firstProp === nextProps. firstProp && this.props.secondProp === nextProps.secondProp) { return false; } return true } // }
Ở ví dụ này, chúng ta ra điều kiện chỉ render lại component khi giá trị của props bị thay đổi.
Tương tự, ta có thể làm nhiều hơn thế:
class MyComponent extends React.Component { shouldComponentUpdate(nextProps, nextState) { if(this.state.isLoading === nextState. isLoading) { return false; } return true } }
Ở ví dụ thứ hai này, bạn kiểm soát điều kiện để render lại component nhiều hơn một chút. Bạn có thể duy trì state trong component và ngừng việc render lại nếu state này không thay đổi.
❤ Đừng bỏ qua:Top 3 cuốn sách học React Native hay nhất 2018
#2. Sử dụng key attribute khi duyệt Array/List
Array/List là thứ được sử dụng phổ biến nhất trong mọi ứng dụng. Với ứng dụng native trong android, chúng ta cũng làm việc với Array/List để hiển thị ra ListView, RecyclerView…
Khi duyệt Array/List, nếu bạn không chỉ định unique key cho mỗi item trong list, React sẽ render lại tất cả item mỗi khi một item nào được thêm vào hoặc bị xóa khỏi list. Đọc đến đây, chắc hẳn bạn cũng thấy được sự lãng phí tài nguyên rồi đúng không?
Ngược lại, nếu bạn có một unique key cho mỗi item, bạn sẽ không phải tốn tài nguyên để render lại những item không có thay đổi.
class MyComponent extends React.PureComponent { render() { return this.props.data.map((item, i) => { return <Text key={item.id}>{item.title}</Text> }); } }
#3. Bind ngay khi có thể và đừng tạo functions bên trong hàm render
Kiểu như sau:
class MyComponent extends React.PureComponent { constructor(props) { super(props); this.doWork = this.doWork.bind(this); } doWork() { // doing some work here. // this.props.dispatch.... } render() { return <Text onPress={this.doWork}>Do Some Work</Text> } }
Không nên thực hiện trong hàm render
<Text onPress={ () => this.doWork() }>Do Some Work</Text>
Hoặc
<Text onPress={ this.doWork.bind(this) }>Do Some Work</Text>
Bởi vì render được gọi thường xuyên và mỗi khi bạn gọi một trong hai thứ trên, một hàm mới sẽ được tạo ra => dẫn đến tốn tài nguyên không cần thiết.
Nếu bạn phải truyền giá trị cho hàm doWork
, bạn có thể sử dụng một closure như thế này
doWork = (param) => () => { console.log(param) } <Text onPress={this.doWork(someVarParam)}Do Some Work With Args</Text>
#4. Không cập nhật state hoặc gửi actions bên trong componentWillUpdate
componentWillUpdate là hàm được sử dụng để chuẩn bị cho bản cập nhật nào đó.
Nếu bạn muốn đặt state hoặc gửi bất kỳ actions nào, hãy thực hiện chúng trong hàm componentWillReceiveProps.
#5. Sử dụng VirtualizedList, FlatList và SectionList cho các tập dữ liệu lớn làm cho tốc độ React Native được tối ưu
Theo tài liệu chính thức của React Native: VirtualizedList, FlatList và SectionList là những API dùng cho việc hiển thị list và sử dụng rất ít bộ nhớ.
Vì vậy nếu bạn có một danh sách với hàng trăm items, thì không phải tất cả chúng đều được tải lên màn hình cho đến khi bạn cuộn xuống.
Cả FlatList và SectionList đều dựa trên VirtualizedList. Lời khuyên của mình là nếu bạn có tập dữ liệu lớn, ít thay đổi khi ứng dụng chạy (Ví dụ: danh sách các thành phố trên thế giới, danh sách đất nước…), bạn nên sử dụng trực tiếp VirtualizedList thay vì FlatList hay SectionList.
#6. Sử dụng Perf monitor để theo dõi FPS
Bật developer tools và enable tính năng perf monitor.Tính năng này cho phép bạn theo dõi FPS (tốc độ khung hình hiển thị) của ứng dụng.
Từ đây, bạn có thể tìm kiếm những lỗi khiến FPS đang giảm. Có thể state bị thiết lập sai hoặc gửi các actions ở sai chỗ… Cũng có thể là bạn đang thực hiện quá nhiều công việc đồng bộ(synchronous) trên Javascript thread.
Nói chung, có rất nhiều nguyên nhân có thể khiến ứng dụng của bạn bị chậm. Nếu cảm thấy cần thiết, hãy sử dụng Perf monitor để kiểm tra và phát hiện nguyên nhân. Hoặc bạn có thể tiến hành debug trên các thiết bị thật xem vấn đề có xuất hiện không. Đây là cách debug React Native
#Tạm kết
Trên là 6 lỗi mà bạn nên tránh để hiệu năng ứng dụng react native. Những lỗi này rất phổ biến, đặc biệt là các bạn mới tiếp xúc và làm việc với React Native. Tuy nhiên, may mắn là cách khắc phục cũng đơn giản, chỉ cần lưu tâm là được.
Hy vọng bài viết này sẽ hữu ích với bạn trong việc cải thiện tốc độ React Native. Chắc chắn mình sẽ chia sẻ các kỹ thuật nâng cao hơn trong bài viết tiếp theo về ứng dụng React Native. Đừng quên đăng ký để nhận những bài viết mới nhé.
Nếu bạn có bất kì thắc mắc hãy để comment bên dưới nhé, mình luôn luôn lắng nghe (^_^)
Bạn ơi, bạn có code ví dụ về mấy cái hàm liên quan đến Life Cycle của component ko ạ ?
Nếu Không cập nhật state ở trong componentWillUpdate thì mình có nên update ở componentDidMount được ko nhỉ ?
Hoàn toàn được bạn nhé. Ngoại trừ việc gọi hàm setState trong componentDidMount làm cho render() bị gọi 2 lần. Còn lại thì OK.
Ngay cả tài liệu chính thức họ cũng nó là không vấn đề gì.
“You may call setState() immediately in componentDidMount(). It will trigger an extra rendering, but it will happen before the browser updates the screen. This guarantees that even though the render() will be called twice in this case, the user won’t see the intermediate state. Use this pattern with caution because it often causes performance issues…”
Nếu k setState() trong componentDidMount() thì set trong đâu ạ?? Khi vào màn hình mà muốn get Data thì xử lý trong hàm nào để tối ưu ạ