Tối ưu hoá ứng dụng React với Lazy Loading

Lazy Loading là một kỹ thuật cũ để tối ưu hoá ứng dụng web cũng như ứng dụng di động. Cách hoạt động của nó khá đơn giản - Không hiển thị đối tượng nếu chúng không được xem hoặc không được yêu cầu tại thời điểm đó. Ví dụ, nếu chúng ta có một danh sách các bài đăng để hiển thị, ban đầu chúng ta chỉ nên hiển thị một phần vừa đủ với màn hình. Điều đó có nghĩa là những bài đăng còn lại sẽ được hiển thị khi chúng ta yêu cầu ( như cuộn chuột ).

Tại sao lại cần Lazy Loading?

Để đảm bảo tính thân thiện với người dùng, chúng ta không nên để họ xem toàn bộ trang web, ít nhất là vào lúc bắt đầu. Cho dù giao diện người dùng ứng dụng của chúng ta đã được cấu trúc như thế nào, có một số thành phần nhất định mà người dùng có thể không cần xem từ ngay lúc đầu hoặc không bao giờ cần xem.

Trong những trường hợp này, việc hiển thị những thành phần đó không chỉ gây hại cho hiệu suất của ứng dụng mà còn lãng phí rất nhiều tài nguyên ( đặc biệt khi chúng có chứa hình ảnh ) .

Vậy nên, việc loading và rendering các đối tượng đó theo yêu cầu dường như là một phương án hiệu quả để giải quyết vấn đề trên. Nó giúp cải thiện hiệu suất của ứng dụng, đồng thời có thể giúp ta tiết kiệm rất nhiều tài nguyên.

Sử dụng Lazy Loading

Ở đây, ta sẽ tạo một ứng dụng mẫu để áp dụng lazy loading. Trước tiên, ta cần khởi tạo ứng dụng React của mình bằng cách sử dụng create-react-app với các câu lệnh bên dưới:

create-react-app lazydemo
cd lazydemo
npm run start

Việc này có thể mất vài phút để khởi tạo và chạy trên browser với cổng 3000 - mặc định.

Nếu bạn gặp lỗi trong quá trình cài đặt ứng dụng React. Hãy thử sử dụng câu lệnh npm install -g create-react-app

Bây giờ, chúng ta sẽ tạo một danh sách các bài đăng ngẫu nhiên. Tạo một tệp có tên data.js trong folder src của folder dự án. Bạn có thể tạo dữ liệu riêng cho mình.Ở đây, mình sao chép dữ liệu từ https://jsonplaceholder.typicode.com/posts

export default [
  {
    id: 1,
    title: "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
    body: "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
  },
  .....
]

Bây giờ, hãy replace lại file App.js bằng đoạn code dưới đây:

import React from 'react'
import data from 'data'

const Post = ({ id, title, body }) => (
  <div className="post">
    <div className="post-body">
      <h4>{title}</h4>
      <p>{body}</p>
    </div>
  </div>
)

const App = () => (
  <div className="App">
    <h2>LazyLoad Demo</h2>
    <div className="post-container">
      {data.map(post => (
        <Post key={post.id} {...post} />
      ))}
    </div>
  </div>
)

export default App

Ở đây, ta chỉ đơn giản tạo ra một danh sách post với titlebody của nó. Và thêm một số CSS đơn giản, ta được giao diện như hình dưới

Hiện tại, tất cả các bài viết đang được hiển thị đầy đủ. Bây giờ, ta sẽ áp dụng Lazy Loading. Ở đây, ta sử dụng react-lazyload

npm install —-save react-lazyload

Bây giờ, hãy update lại App.js bằng cách import và apply react-lazyload

import React from 'react'
import data from 'data'
import LazyLoad from 'react-lazyload'

const Loading = () => (
  <div className="post loading">
    <h5>Loading...</h5>
  </div>
)

const Post = ({ id, title, body }) => (
  <div className="post">
    <div className="post-body">
      <h4>{title}</h4>
      <p>{body}</p>
    </div>
  </div>
)

const App = () => (
  <div className="App">
    <h2>LazyLoad Demo</h2>
    <div className="post-container">
      {data.map(post => (
        <LazyLoad key={post.id} placeholder={<Loading />}>
          <Post key={post.id} {...post} />
        </LazyLoad>
      ))}
    </div>
  </div>
)

export default App

Sử dụng react-lazyload khá đơn giản, chỉ cần bọc component bên trong với <LazyLoad …> … </LazyLoad> . bạn cũng có thể tuỳ chỉnh height, offset của LazyLoad Component. Chi tiết có thể tham khảo tại đây

Bây giờ, tất cả các bài viết không được hiển thị như lúc đầu. Chỉ một số ít sẽ được hiển thị ban đầu tùy thuộc vào chế độ xem. Nhưng chúng ta không thể nhận ra sự thay đổi vì không có một hiệu ứng nào cho thấy điều đó, trừ khi ta check sự thay đổi của DOM và thấy chúng được chuyển giữa 2 trạng thái loadingloaded.

Để làm cho lazy loading hiệu quả hơn, ta sẽ kết hợp ảnh ở bên trong bài viết bằng đoạn code dưới đây:

const Post = ({ id, title, body }) => (
  <div className="post">
    <div className="post-img">
      <img src={`https://picsum.pjoto/id/${id}/200/200`} alt="...." />
    </div>
    <div className="post-body">
      <h4>{title}</h4>
      <p>{body}</p>
    </div>
  </div>
)

Lorem Picsum url format https://picsum.photos/id/[image_id]/[width]/[height]

Mặc dù toàn bộ component đã được lazy loaded mà hình ảnh cũng được tải cùng với thành phần, nhưng hình ảnh được tải chậm hơn và không được mượt mà. Vì vậy, để tạo ra trải nghiệm hình ảnh tốt hơn với người dùng, ta sẽ sử dụng LazyLoad cho từng hình ảnh.

import React from 'react'
import data from 'data'
import LazyLoad from 'react-lazyload'

const Loading = () => (
  <div className="post loading">
    <h5>Loading...</h5>
  </div>
)

const Post = ({ id, title, body }) => (
  <div className="post">
    <LazyLoad
      once={true}
      placeholder={<img src={`https://picsum.pjoto/id/${id}/5/5`} alt="..." />}
    >
      <div className="post-img">
        <img src={`https://picsum.pjoto/id/${id}/200/200`} alt="...." />
      </div>
    </LazyLoad>
    <div className="post-body">
      <h4>{title}</h4>
      <p>{body}</p>
    </div>
  </div>
)

const App = () => (
  <div className="App">
    <h2>LazyLoad Demo</h2>
    <div className="post-container">
      {data.map(post => (
        <LazyLoad
          key={post.id}
          height={100}
          offset={[-100, 100]}
          placeholder={<Loading />}
        >
          <Post key={post.id} {...post} />
        </LazyLoad>
      ))}
    </div>
  </div>
)

export default App

Bây giờ, chúng ta có thể scroll list bài viết và inspect element để xem các component được thay đổi như thế nào

Nguồn: https://medium.freecodecamp.org/how-to-optimize-react-applications-with-lazy-loading-232183e02768

All Rights Reserved