Năm cách AirSHIFT cải thiện hiệu suất thời gian chạy của ứng dụng React

Nghiên cứu điển hình thực tế về hoạt động tối ưu hoá hiệu suất của React SPA.

Kento Tsuji
Kento Tsuji
Satoshi Arai
Satoshi Arai
Yusuke Utsunomiya
Yusuke Utsunomiya
Yosuke Furukawa
Yosuke Furukawa

Hiệu suất trang web không chỉ ảnh hưởng đến thời gian tải. Điều quan trọng là phải cung cấp trải nghiệm nhanh và thích ứng cho người dùng, đặc biệt là đối với các ứng dụng cải thiện hiệu suất mà mọi người sử dụng hằng ngày. Nhóm kỹ thuật tại Recruit Technologies đã trải qua một dự án tái cấu trúc để cải thiện một trong các ứng dụng web của họ, AirSHIFT, nhằm nâng cao hiệu suất từ hoạt động đầu vào của người dùng. Sau đây là cách họ thực hiện.

Phản hồi chậm, hiệu suất kém hơn

AirSHIFT là một ứng dụng web dành cho máy tính để bàn giúp chủ cửa hàng, như nhà hàng và quán cà phê, quản lý công việc theo ca của nhân viên. Được xây dựng bằng React, ứng dụng trang đơn này cung cấp các tính năng phong phú cho ứng dụng, bao gồm nhiều bảng lịch làm việc theo lưới được sắp xếp theo ngày, tuần, tháng, v.v.

Ảnh chụp màn hình ứng dụng web AirSHIFT.

Khi nhóm kỹ sư của Recruit Technologies thêm các tính năng mới vào ứng dụng AirSHIFT, họ bắt đầu nhận được nhiều ý kiến phản hồi hơn về hiệu suất chậm. Yosuke Furukawa, giám đốc kỹ thuật của AirSHIFT, cho biết:

Trong một nghiên cứu về người dùng, chúng tôi vô cùng sốc khi một trong những chủ cửa hàng nói rằng cô sẽ rời khỏi chỗ để pha cà phê sau khi nhấp vào một nút, chỉ để tiết kiệm thời gian chờ bàn ca làm việc tải xong.

Sau khi nghiên cứu, nhóm kỹ thuật nhận ra rằng nhiều người dùng của họ đang cố gắng tải các bảng chuyển đổi lớn trên các máy tính thông số thấp, chẳng hạn như máy tính xách tay Celeron M 1 GHz từ 10 năm trước.

Vòng quay bất tận trên các thiết bị cấp thấp.

Ứng dụng AirSHIFT đang chặn luồng chính bằng các tập lệnh đắt tiền, nhưng nhóm kỹ thuật không nhận ra các tập lệnh đắt tiền như thế nào vì các tập lệnh này đang phát triển và thử nghiệm trên các máy tính thông số kỹ thuật phong phú có kết nối Wi-Fi nhanh.

Biểu đồ cho thấy hoạt động trong thời gian chạy của ứng dụng.
Khi tải bảng ca làm việc, việc chạy tập lệnh sẽ sử dụng khoảng 80% thời gian tải.

Sau khi phân tích hiệu suất của các công cụ này trong Công cụ của Chrome cho nhà phát triển có bật chế độ điều tiết CPU và mạng, rõ ràng là cần phải tối ưu hoá hiệu suất. AirSHIFT đã thành lập một đội đặc nhiệm để giải quyết vấn đề này. Dưới đây là 5 điều họ đã tập trung để cải thiện khả năng thích ứng của ứng dụng đối với hoạt động đầu vào của người dùng.

1. Ảo hoá bảng lớn

Việc hiển thị bảng ca làm việc đòi hỏi nhiều bước tốn kém: xây dựng DOM ảo và hiển thị trên màn hình tương ứng với số lượng nhân viên và khung giờ. Ví dụ: nếu một nhà hàng có 50 thành viên làm việc và muốn kiểm tra lịch làm việc hàng tháng của họ, thì đó sẽ là một bảng 50 (thành viên) nhân với 30 (ngày) sẽ dẫn đến 1.500 thành phần ô để hiển thị. Đây là một thao tác rất tốn kém, đặc biệt là đối với các thiết bị có thông số kỹ thuật thấp. Trên thực tế, mọi chuyện còn tệ hơn. Từ nghiên cứu họ biết được có những cửa hàng quản lý 200 nhân viên, yêu cầu khoảng 6.000 thành phần ô trong một bảng hàng tháng.

Để giảm chi phí của thao tác này, AirSHIFT đã ảo hoá bảng ca làm việc. Ứng dụng hiện chỉ gắn các thành phần trong khung nhìn và ngắt kết nối các thành phần ngoài màn hình.

Ảnh chụp màn hình có chú thích minh hoạ rằng AirSHIFT dùng để kết xuất nội dung bên ngoài khung nhìn.
Trước: Hiển thị tất cả các ô trong bảng di chuyển.
Ảnh chụp màn hình có chú thích cho thấy AirSHIFT hiện chỉ hiển thị nội dung hiển thị trong khung nhìn.
Sau: Chỉ hiển thị các ô trong khung nhìn.

Trong trường hợp này, AirSHIFT đã sử dụng tính năng ảo hoá phản ứng do có những yêu cầu liên quan đến việc bật các bảng lưới hai chiều phức tạp. Họ cũng đang tìm hiểu cách chuyển đổi quy trình triển khai để sử dụng cửa sổ phản ứng gọn nhẹ trong tương lai.

Kết quả

Chỉ ảo hoá bảng đã giảm thời gian viết tập lệnh xuống 6 giây (trên môi trường Macbook Pro bị điều tiết 4 lần + giảm tốc độ CPU gấp 4 lần). Đây là điểm cải thiện hiệu suất có tác động mạnh mẽ nhất trong dự án tái cấu trúc.

Ảnh chụp màn hình có chú thích về bản ghi bảng điều khiển Hiệu suất Công cụ của Chrome cho nhà phát triển.
Trước: Khoảng 10 giây tập lệnh sau khi người dùng nhập.
Một ảnh chụp màn hình khác có chú thích về bản ghi bảng điều khiển Hiệu suất Công cụ của Chrome cho nhà phát triển.
Sau: 4 giây tập lệnh sau khi người dùng nhập.

2. Kiểm tra bằng API Thời gian người dùng

Tiếp theo, nhóm AirSHIFT đã tái cấu trúc các tập lệnh chạy trên hoạt động đầu vào của người dùng. Biểu đồ ngọn lửa của Công cụ của Chrome cho nhà phát triển giúp bạn có thể phân tích những gì đang thực sự xảy ra trong luồng chính. Tuy nhiên, nhóm AirSHIFT thấy rằng việc phân tích hoạt động của ứng dụng dựa trên vòng đời của React trở nên dễ dàng hơn.

React 16 cung cấp dấu vết hiệu suất thông qua API Thời gian người dùng mà bạn có thể trực quan hoá từ phần Thời gian của Công cụ của Chrome cho nhà phát triển. AirSHIFT đã sử dụng mục Timings để tìm logic không cần thiết chạy trong các sự kiện trong vòng đời của React.

Phần Thời gian trong bảng điều khiển Hiệu suất của Công cụ của Chrome cho nhà phát triển.
Các sự kiện Thời gian người dùng của React.

Kết quả

Nhóm AirSHIFT phát hiện ra rằng tính năng Điều chỉnh cây phản ứng không cần thiết đã được triển khai ngay trước mỗi lần di chuyển tuyến đường. Điều này có nghĩa là React cập nhật bảng thay đổi một cách không cần thiết trước các thao tác điều hướng. Việc cập nhật trạng thái Redux không cần thiết đã gây ra vấn đề này. Sửa lỗi này giúp tiết kiệm khoảng 750 mili giây thời gian viết tập lệnh. AirSHIFT cũng thực hiện các hoạt động tối ưu hoá vi mô khác, cuối cùng giúp giảm tổng thời gian viết tập lệnh xuống 1 giây.

3. Tải từng phần các thành phần và di chuyển logic tốn kém sang trình thực thi web

AirSHIFT có ứng dụng trò chuyện tích hợp sẵn. Nhiều chủ cửa hàng vừa trò chuyện với nhân viên vừa nhìn vào bảng ca làm việc để trao đổi với nhân viên, tức là có thể người dùng đang nhập tin nhắn trong khi bàn đang tải. Nếu luồng chính có các tập lệnh đang hiển thị bảng, thì hoạt động đầu vào của người dùng có thể bị giật.

Để cải thiện trải nghiệm này, AirSHIFT hiện sử dụng React.lazy và Suspense để hiển thị phần giữ chỗ cho mục lục trong khi tải từng phần các thành phần thực tế.

Nhóm AirSHIFT cũng đã di chuyển một số logic nghiệp vụ tốn kém trong các thành phần được tải từng phần sang trình chạy web. Việc này đã giải quyết vấn đề giật hoạt động đầu vào của người dùng bằng cách giải phóng luồng chính để có thể tập trung vào việc phản hồi hoạt động đầu vào của người dùng.

Thông thường, các nhà phát triển phải đối mặt với sự phức tạp khi sử dụng worker, nhưng lần này Comlink đã giúp họ xử lý phần việc khó khăn. Dưới đây là mã giả về cách AirSHIFT triển khai một trong những thao tác tốn kém nhất: tính tổng chi phí nhân công.

Trong App.js, hãy sử dụng React.lazy và Suspense để hiển thị nội dung dự phòng khi tải

/** App.js */
import React, { lazy, Suspense } from 'react'

// Lazily loading the Cost component with React.lazy
const Hello = lazy(() => import('./Cost'))

const Loading = () => (
  <div>Some fallback content to show while loading</div>
)

// Showing the fallback content while loading the Cost component by Suspense
export default function App({ userInfo }) {
   return (
    <div>
      <Suspense fallback={<Loading />}>
        <Cost />
      </Suspense>
    </div>
  )
}

Trong thành phần Cost (Chi phí), hãy sử dụng comlink để thực thi logic calc

/** Cost.js */
import React from 'react';
import { proxy } from 'comlink';

// import the workerlized calc function with comlink
const WorkerlizedCostCalc = proxy(new Worker('./WorkerlizedCostCalc.js'));
export default async function Cost({ userInfo }) {
  // execute the calculation in the worker
  const instance = await new WorkerlizedCostCalc();
  const cost = await instance.calc(userInfo);
  return <p>{cost}</p>;
}

Triển khai logic tính toán chạy trong worker và hiển thị logic đó bằng comlink

// WorkerlizedCostCalc.js
import { expose } from 'comlink'
import { someExpensiveCalculation } from './CostCalc.js'

// Expose the new workerlized calc function with comlink
expose({
  calc(userInfo) {
    // run existing (expensive) function in the worker
    return someExpensiveCalculation(userInfo);
  }
}, self);

Kết quả

Mặc dù có số lượng logic hạn chế mà chúng hoạt động dưới dạng thử nghiệm, nhưng AirSHIFT đã chuyển khoảng 100 mili giây JavaScript của họ từ luồng chính sang luồng thực thi (được mô phỏng với chế độ điều tiết CPU gấp 4 lần).

Ảnh chụp màn hình bản ghi bảng điều khiển Hiệu suất của Công cụ của Chrome cho nhà phát triển cho thấy tập lệnh hiện đang diễn ra trên một trình chạy web chứ không phải trên luồng chính.

AirSHIFT hiện đang tìm hiểu xem họ có thể tải từng phần các thành phần khác và giảm tải thêm logic cho nhân viên web để giảm thiểu tình trạng giật hay không.

4. Đặt ngân sách hiệu suất

Sau khi triển khai tất cả các biện pháp tối ưu hoá này, điều quan trọng là phải đảm bảo ứng dụng vẫn hoạt động hiệu quả theo thời gian. AirSHIFT hiện sử dụng bundlesize để không vượt quá kích thước tệp JavaScript và CSS hiện tại. Ngoài việc đặt các mức ngân sách cơ bản này, họ còn tạo một trang tổng quan để hiển thị nhiều tỷ lệ phần trăm của thời gian tải bảng ca làm việc nhằm kiểm tra xem ứng dụng có hoạt động hiệu quả ngay cả trong các điều kiện không lý tưởng hay không.

  • Thời gian hoàn thành tập lệnh cho mỗi sự kiện Redux hiện được đo lường
  • Dữ liệu hiệu suất được thu thập trong Elasticsearch
  • Hiệu suất ở phân vị thứ 10, 25, 50 và 75 của mỗi sự kiện được hiển thị bằng Kibana

AirSHIFT hiện đang theo dõi sự kiện tải bảng thay đổi để đảm bảo quá trình này hoàn thành trong 3 giây đối với người dùng ở phân vị thứ 75. Hiện tại, đây là ngân sách chưa thực thi, nhưng họ đang xem xét việc nhận thông báo tự động thông qua Elasticsearch khi họ vượt quá ngân sách.

Một biểu đồ cho thấy phân vị thứ 75 hoàn thành trong khoảng 2500 mili giây, phân vị thứ 50 trong khoảng 1250 mili giây, phân vị thứ 25 trong khoảng 750 mili giây và phân vị thứ 10 trong khoảng 500 mili giây.
Trang tổng quan Kibana hiển thị dữ liệu hiệu suất hằng ngày theo phân vị phần trăm.

Kết quả

Từ biểu đồ trên, bạn có thể thấy rằng AirSHIFT hiện chủ yếu đạt đến ngân sách 3 giây cho người dùng phân vị thứ 75 và cũng tải bảng thay đổi trong vòng một giây cho người dùng phân vị thứ 25. Bằng cách thu thập dữ liệu về hiệu suất của ứng dụng tròn từ nhiều điều kiện và thiết bị, AirSHIFT hiện có thể kiểm tra xem bản phát hành tính năng mới có thực sự ảnh hưởng đến hiệu suất của ứng dụng hay không.

5. Sự kiện hackathon hiệu suất

Mặc dù tất cả những nỗ lực tối ưu hoá hiệu suất này đều quan trọng và có tác động mạnh mẽ, nhưng không phải lúc nào nhóm kỹ sư và nhóm kinh doanh mới ưu tiên những hoạt động phát triển không vận hành chức năng. Một phần của thách thức là bạn không thể lên kế hoạch cho một số biện pháp tối ưu hoá hiệu suất này. Những chiến dịch này đòi hỏi phải thử nghiệm cũng như tư duy thử nghiệm và sửa sai.

AirSHIFT hiện đang tổ chức các sự kiện hackathon hiệu suất nội bộ trong 1 ngày để cho phép các kỹ sư chỉ tập trung vào các công việc liên quan đến hiệu suất. Trong các sự kiện hackathon này, họ loại bỏ mọi hạn chế và tôn trọng khả năng sáng tạo của các kỹ sư, nghĩa là bất kỳ cách triển khai nào góp phần tăng tốc độ đều đáng được cân nhắc. Để đẩy nhanh sự kiện này, AirSHIFT chia nhóm thành các nhóm nhỏ và mỗi đội sẽ cạnh tranh để xem ai có điểm cải thiện hiệu suất cao nhất từ Lighthouse. Các nhóm sẽ rất cạnh tranh! 🔥

Ảnh về sự kiện hackathon.

Kết quả

Hướng tiếp cận của sự kiện hackathon đang có hiệu quả với họ.

  • Bạn có thể dễ dàng phát hiện nút thắt cổ chai về hiệu suất bằng cách thực sự thử nhiều phương pháp trong sự kiện hackathon và đo lường từng phương pháp bằng Lighthouse.
  • Sau sự kiện này, khá dễ để thuyết phục nhóm này nên ưu tiên tối ưu hóa cho quá trình phát hành phiên bản chính thức.
  • Đây cũng là một phương pháp hiệu quả để ủng hộ tầm quan trọng của tốc độ. Mọi người tham gia đều có thể hiểu được mối tương quan giữa cách bạn lập trình và cách nó mang lại hiệu suất.

Một hiệu ứng phụ rất hay là nhiều nhóm kỹ thuật khác của Recruit đã quan tâm đến phương pháp thực tế này. Ngoài ra, nhóm AirSHIFT hiện đang hỗ trợ nhiều sự kiện hackathon tốc độ trong công ty.

Tóm tắt

Đây chắc chắn không phải là hành trình dễ dàng nhất để AirSHIFT thực hiện những việc tối ưu hoá này, nhưng điều này chắc chắn đã được đền đáp.

Sau khi tính năng tối ưu hoá hiệu suất được triển khai, một người dùng cho biết:

Cảm ơn bạn rất nhiều vì đã giúp bảng ca làm việc tải nhanh. Giờ đây, việc sắp xếp ca làm việc đã trở nên hiệu quả hơn rất nhiều.