3 tools giúp bạn tăng hiệu năng của React App một cách bất ngờ

React rất đơn giản để học và làm, nhưng đôi khi vì quá dễ mà chúng ta hay mắc những lỗi nhỏ nhặt nhưng lại gây ảnh hưởng đến hiệu năng của chúng. Component mounts chậm, component trees quá rối rắm, cũng như những render cycle thừa thãi khiến cho user cảm thấy ứng dụng chạy chậm.

Thật may là có rất nhiều tool giúp phân tích và xách định vấn đề về hiệu năng trong React. Trong bài viết này tôi sẽ liệt kê ra những tool và mánh khóe để cải thiện tốc độ xử lí của các ứng dụng React.

Tool #1: Performance Timeline

React 15.4.0 vừa tích hợp vào tính năng mới là “performance timeline feature” cho phép bạn biết được chính xác khi nào components được mounted, updated, và unmounted. Nó còn có khả năng hiển thị component lifecycle cũng như mối quan hệ giữa chúng.

Note: Hiện tại tính năng này chỉ dành cho Chrome, Edge, và IE.

Cách nó hoạt động

  1. Vào app và nối đoạn query param sau: react_perf. Như thế này: http://localhost:3000?react_perf
  2. Mở Chrome DevTools Performance tab và chọn Record
  3. Thực hiện hành động mà bạn muốn được phân tích
  4. Dừng record
  5. Kiểm tra kết quả từ User Timing

Hiểu rõ kết quả (output)

Từng cột màu cho ta thấy thời điểm mà từng component hoạt động. Bởi vì JavaScript là single-threaded nên khi một component đang mount hoặc render, nó sẽ được chạy trong thread chính và các code phải ngưng lại cho đến khi quá trình trên hoàn thành.

Phần thông tin trong mục  [update] cho ta biết đang trong giai đoạn nào của component lifecycle. Cũng nhu thời gian cho từng bước để giúp bạn có thể so sánh giữa các phương pháp như  [componentDidMount], [componentWillReceiveProps] [ctor] (constructor) và[render].

Các cột được xếp với nhau nhằm tượng trưng cho component trees. Mặc dù theo thông thường thì chúng ta sẽ có component tree khá lớn trong React, nếu bạn đang tinh chỉnh một component thương xuyên được mounted, nó sẽ giúp làm giảm số lượng của wrapper component và kết quả là cải thiện hiệu năng của app.

Điều cần lưu ý là thời gian xử lí trong quá trình phát triển app luôn sẽ chậm hơn so với thông số thật. Tuy là bạn không nên quá dựa vào những thông số trên nhưng sự khác biệt cũng không nhiều và nó cho ta cái nhìn rõ hơn về chất lượng và hiệu năng của sản phẩm đang ở đâu.

Demo #1

Để cho vui, tôi thử phá TodoMVC app để khiến nó có những vấn đề nghiêm trọng về hiệu năng. bạn cũng có thể thử chúng tại đây.

Để xem timeline, mở Chrome dev tools, vào “Performance” tab, chọn Record. Sau đó thêm TODOs vào trong app, dừng record, và xem timeline. Hãy thử xem bạn có thể biết được component chính là nguyên nhân khiến cho hiệu năng bị ảnh hưởng không.

Tool #2: why-did-you-update

Một trong những nguyên nhân chính khiến cho các ứng dụng trên React chạy chậm là bởi có quá nhiều render cycle không cần thiết. Khi để ở chế độ mặc định, React components sẽ re-render khi ba mẹ chúng (component chứa chúng) reder cho dù là không có thay đổi bất cứ thứ gì.

Một ví dụ đơn giản là với component sau:

class DumbComponent extends Component {
  render() {
    return <div> {this.props.value} </div>;
  }
}

Tham khảo việc làm lập trình React lương cao cho bạn

Với một component mẹ như thế này:

class Parent extends Component {
  render() {
    return <div>
      <DumbComponent value={3} />
    </div>;
  }
}

Mỗi khi component mẹ render thì DumbComponent re-render cho dù props của nó chả thay đổi gì.

Nói cách khác  render chạy nhưng DOM ảo vẫn không thay đổi gì và một render cycle bị phí phạm. Với một app lớn thì việc xác định ra nguồn ngọn sẽ rất khó khăn, may thay chúng ta đã có một tool cho trường hợp này.

Sử dụng why-did-you-update

why-did-you-update là một library dành cho React với chức năng phát hiện ra những component render không cần thiết. Nó sẽ theo dõi và ngay lập tức phát hiện ra những component’s  render mà prop lại không có thay đổi.

Setup

  1. Cài đặt với npm:  npm i --save-dev why-did-you-update
  2. Thêm phần dưới đâu vào bất kì đâu của app của bạn:
import React from 'react'
if (process.env.NODE_ENV !== 'production') {
  const {whyDidYouUpdate} = require('why-did-you-update')
  whyDidYouUpdate(React)
}

Demo #2

Để cho bạn thấy khả năng why-did-you-update, tôi cài library đó vào TodoMVC app trên Code Sandbox, một online React playground. Mở trình duyệt console và thêm một số TODOs để xem kết quả.

Bạn có thể lấy bản Demo tại đây.

Bạn sẽ thấy một số component trong app render một cách không cần thiết. Hãy thử dùng kĩ thuật trên để khắc phục chúng.

Tool #3: React Developer Tools

React Developer Tools Chrome extension có một tính năng là hiển thị component updates. Nó cực kì tiện lỡi cho việc phát hiện ra những render cycles không cần thiết. Để sử dụng nó trước hết bạn cần phải cài extension đấy.

Sau đó mở extension bằng bấm vào “React” tab của Chrome DevTools và chọn phần “Highlight Updates”.

Giờ thì chỉ việc dùng app, tương tác với compopnent và chứng kiến DevTool thực hiện phép thuật của nó.

Hiểu rõ kết quả (output)

React Developer Tools sẽ highlights các components có redering. Nó còn cho màu sắc khác nhau như xanh, vàng, đỏ tùy thuộc vào việc component có render thường xuyên hay không.  

Vàng và đỏ không có nghĩa là xấu bởi đôi khi ta update hoặc chạy nhiều tính năng nên khiến cho render diễn ra nhiều. Tuy nhiên nếu chỉ nhấn một nút đơn giản mà đã ra mà đỏ rồi thì khá là có vấn đề đấy. Mục đích của tool này là để chúng ta biết được update nào là không cần thiết. Và là một App developer, bạn sẽ biết khi nào thì enn6 update component.

Demo #3

Để bạn hiểu rõ hơn về tính năng component highlight, tôi đã sửa cho TodoMVC app update không cần thiết một số component.

Bạn có thể download bản Demo tại đây.

Vào đường link trên, mở React Developer Tools và chọn update highlighting. Khi bạn type trong text input, ta sẽ thấy toàn bộ TODOs highlight không cần thiết. Và khi bạn type nhanh hơn thì màu sắc cùa hightlight cũng sẽ biến đổi liên tục nhằm ám chỉ việc update thường xuyên.

Khắc phục renders thừa thãi

Sau khi bạn đã xác định được components nào re-rendering thừa thãi thì ta sẽ tìm cách khác phục chúng. Sau đây là một số phương pháp khá đơn giản.

Sử dụng PureComponent

Trong ví dụ trên,  DumbComponent là một pure function cho props của nó. Nói cách khác, component chỉ re-render khi Prop thay đổi. Có thể nói tính năng `PureComponent` trong React chính là để dùng cho trường hợp đặc biệt này.

Bạn có thể dùng React.PureComponent như sau:

class DumbComponent extends PureComponent {
  render() {
    return <div> {this.props.value} </div>;
  }
}

Và thế là xong rồi đấy.

Tuy vậy, PureComponent chỉ quét sơ Props để phát hiện ra những thay đổi. Thế nên nếu trong trường hợp là một app phức tạp với nhiều Props khác nhau thì PureComponent đôi khi bỏ qua một số và sẽ không thay đổi.

Áp dụng shouldComponentUpdate

shouldComponentUpdate là một phương pháp của component khi ta call trước khi render  nếuprops or state có thay đổi hay không. Nếu  shouldComponentUpdate cho kết quả là true, thì render sẽ diễn ra còn nếu là false thì mọi thứ đều được giữ nguyên.

Với phương pháp trên, bạn có thể chỉ React cách tránh re-rendering thừa thãi với component mà props của nó không có thay đổi.

Chúng ta có thể áp dụng shouldComponentUpdate vào ví dụ trên như sau:

class DumbComponent extends Component {
  shouldComponentUpdate(nextProps) {
    if (this.props.value !== nextProps.value) {
      return true;
    } else {
      return false;
    }
  }
render() {
    return <div>foo</div>;
  }
}

Debugging vấn đề về hiệu năng

The React Developer Tools chỉ hoạt động với app của bạn trong máy của bạn. Thế nên nếu bạn muốn biết những vấn đề hiệu năng khi khách hàng sử dụng sản phẩm của mình thì hãy thử LogRocket.

LogRocket giống như DVR dành cho web apps, nó record lại tất cả mọi thứ xảy ra trên website của bạn. Nhờ đó thay vì phỏng đoán một cách mơ hồ thì giờ bạn đã có thể nhanh chóng replay lại và xác định được ngay vấn đề dẫn đến việc hiệu năng bị giảm sút.

LogRocket sẽ khiến App của bạn record thông tin về hiệu năng, Redux actions/state, logs, errors, network requests/responses với headers + bodies, và browser metadata. Không chỉ thế, nó còn record cả HTML và CSS trên trang, tạo lại videos chính xác tới từng pixel của các app một trang phức tạp nhất có thể.

Cảm ơn vì đã đọc bài viết này và hi vọng nó sẽ giúp ích cho các bạn trong project React tiếp theo.

Nguồn: topdev via Medium

Tham khảo thêm vị trí việc làm ngành IT tại đây