Tại sao Tối ưu hóa Gọi API là Quan trọng
Trong lĩnh vực phát triển ứng dụng web, việc tối ưu hóa các gọi API là một yêu cầu cấp thiết, đặc biệt là khi làm việc với React. Các lập trình viên thường đối mặt với thách thức khi người dùng thực hiện nhiều thay đổi trạng thái liên tiếp, thiếp lập trạng thái và đồng bộ hóa dữ liệu với server thông qua API. Nếu không được quản lý tốt, mỗi thay đổi trạng thái lại gửi một yêu cầu API, gây tốn kém tài nguyên và gây quá tải cho máy chủ. Dưới đây, chúng ta sẽ tìm hiểu cách tối ưu hóa quá trình này lên đến 40% bằng cách sử dụng các kỹ thuật debouncing và tích lũy trạng thái.
Vấn Đề Thường Gặp Khi Gọi API
Khi người dùng tương tác với giao diện, chẳng hạn như khi nhập liệu hay chỉnh sửa cài đặt, mỗi thao tác có thể kích hoạt một gọi API. Điều này dẫn đến những bất cập như:
- Sử dụng tài nguyên mạng không hiệu quả.
- Xuất hiện race conditions gây ra lỗi không mong muốn.
- Tải quá mức lên server, ảnh hưởng đến hiệu suất toàn bộ ứng dụng.
Giải Pháp Hiệu Quả: Debouncing và useRef
Để khắc phục vấn đề này, chúng ta sẽ áp dụng hai kỹ thuật hiệu quả: debouncing và sử dụng hook useRef
trong React. Dưới đây là các bước thực hiện:
1. Debouncing: Giới Hạn Tốc Độ Gọi API
Debouncing là kỹ thuật giúp giảm tần suất kích hoạt một hàm, chỉ cho phép hàm này chạy sau một khoảng thời gian không hoạt động nhất định. Ví dụ, bạn có thể chỉ gửi yêu cầu API khi người dùng ngừng nhập liệu sau 300ms.
Tại Sao Nên Sử Dụng Debouncing?
- Cải Thiện Hiệu Suất: Giảm thiểu số lượng yêu cầu không cần thiết đến server.
- Tối Ưu Hóa Tài Nguyên: Giảm tải cho server và băng thông mạng.
- Nâng Cao Trải Nghiệm Người Dùng: Giúp giao diện mượt mà và phản hồi nhanh hơn.
2. Sử Dụng useRef: Duy Trì Trạng Thái Giữa Các Lần Render
Hook useRef
cho phép lưu trữ các giá trị có thể thay đổi mà không làm tăng số lần render của component, rất hữu ích để giữ lại các bản cập nhật từ nhiều đợt thay đổi mà không gây ra hoạt động không cần thiết.
Lợi Ích Khi Sử Dụng useRef
- Duy Trì Thông Tin Tích Lũy: Theo dõi các bản cập nhật liên tiếp mà không làm tăng số lần render.
- Truy Cập Giá Trị Mới Nhất:
useRef
cung cấp thuộc tính.current
để thao tác với dữ liệu.
Xây Dựng Hook useDebouncedUpdate
Chúng ta sẽ xây dựng một hook tùy chỉnh nhằm thực hiện tích lũy các gọi cập nhật API, kết hợp với debouncing để tối ưu hóa hiệu suất:
javascript
import { debounce } from "@mui/material";
import { useCallback, useEffect, useRef } from "react";
type DebouncedUpdateParams = {
id: string;
params: Record<string, any>;
};
function useDebouncedUpdate(apiUpdate: (params: DebouncedUpdateParams) => void,
delay: number = 300) {
const accumulatedUpdates = useRef<DebouncedUpdateParams | null>(null);
const processUpdates = useRef(
debounce(() => {
if (accumulatedUpdates.current) {
apiUpdate(accumulatedUpdates.current);
accumulatedUpdates.current = null;
}
}, delay)
).current;
const handleUpdate = useCallback(
(params: DebouncedUpdateParams) => {
accumulatedUpdates.current = {
id: params.id,
params: {
...(accumulatedUpdates.current?.params || {}),
...params.params,
},
};
processUpdates();
},
[processUpdates]
);
useEffect(() => {
return () => {
processUpdates.clear();
};
}, [processUpdates]);
return handleUpdate;
}
export default useDebouncedUpdate;
Phân Tích Hook useDebouncedUpdate
- Tích lũy Bản Cập Nhật: Sử dụng
useRef
để lưu trữ các tham số đã được hợp nhất. - Debounce Lệnh Gọi API: Xây dựng hàm xử lý debounced để gửi yêu cầu chỉ khi không có thao tác nào trong khoảng thời gian quy định.
- Xử Lý Bản Cập Nhật: Sử dụng
useCallback
để đảm bảo hàm này không bị tạo lại trong mỗi lần render, giúp quản lý các bản cập nhật hiệu quả. - Dọn Dẹp Tài Nguyên: Ngăn chặn rò rỉ bộ nhớ bằng cách xóa hàm debounced khi component unmount.
Ví Dụ Cụ Thể về Sử Dụng
Dưới đây là một ví dụ về cách sử dụng hook useDebouncedUpdate
trong một component React:
javascript
import React from "react";
import useDebouncedUpdate from "./useDebouncedUpdate";
function SettingsComponent() {
const debouncedUpdate = useDebouncedUpdate(updateSettingsApi, 500);
const handleChange = (settingName, value) => {
debouncedUpdate({
id: "user-settings",
params: { [settingName]: value },
});
};
return (
<div>
<input
type="text"
onChange={(e) => handleChange("username", e.target.value)}
/>
<input
type="checkbox"
onChange={(e) => handleChange("notifications", e.target.checked)}
/>
</div>
);
}
function updateSettingsApi({ id, params }) {
console.log("Updating settings:", params);
}
- Hành Động của Người Dùng: Mỗi khi người dùng sửa đổi cài đặt, hàm
handleChange
được kích hoạt. - Bản Cập Nhật Debounced: Các thay đổi sẽ được gửi đến API chỉ sau khi ngừng thao tác trong khoảng thời gian 500ms.
Kết Luận
Hook useDebouncedUpdate
là một giải pháp hữu hiệu cho các thách thức trong việc tối ưu hóa gọi API trong ứng dụng React. Việc tích hợp debouncing giúp giảm thiểu số lượng gọi API không cần thiết, đảm bảo rằng các thay đổi được gom lại với nhau, từ đó cải thiện đáng kể hiệu suất ứng dụng. Bằng cách áp dụng những kỹ thuật này, lập trình viên có thể xây dựng những ứng dụng thân thiện với người dùng và hiệu quả hơn.
source: viblo