Ngày xuất bản: 14 tháng 10 năm 2025
Lượt tương tác đến nội dung hiển thị tiếp theo (INP) là một chỉ số quan trọng trong Chỉ số quan trọng chính của trang web để đo lường khả năng phản hồi. Tại Fotocasa, Google Search Console đã làm nổi bật một số lượng đáng kể các trang chuyển sang trạng thái "Cần cải thiện" và "Kém" khi INP thay thế Thời gian phản hồi lần tương tác đầu tiên (FID) vào năm 2024. Nghiên cứu điển hình này trình bày các công cụ và chiến lược được sử dụng để chẩn đoán và giải quyết những vấn đề này, từ đó cải thiện đáng kể chỉ số INP.
Nơi đội ngũ Fotocasa bắt đầu
Trước khi chuyển từ FID sang INP, hầu hết mọi trang trên cả máy tính và thiết bị di động đều nằm trong ngưỡng "Tốt", tức là tất cả Các chỉ số quan trọng về trang web tại thời điểm đó (LCP, CLS và FID) đều hoạt động tốt. Tuy nhiên, sau khi chuyển sang INP, gần như tất cả các trang đều chuyển sang trạng thái "Cần cải thiện" và một số trang thậm chí chuyển sang trạng thái "Kém", vì giá trị INP luôn vượt quá 200 mili giây đối với hầu hết các lượt tương tác của người dùng.
Thay đổi này đã giúp nhóm Fotocasa nhận ra rằng họ đang bỏ qua một khía cạnh quan trọng của trải nghiệm người dùng. Trong khi FID chỉ đo lường độ trễ của lượt tương tác đầu tiên, thì INP đánh giá khả năng phản hồi của tất cả các lượt tương tác, tính đến độ trễ xử lý và trình bày dữ liệu đầu vào. Chỉ số đo lường rộng hơn này là một chỉ số đại diện tốt hơn nhiều cho mức độ tương tác thực (như Google đã nêu) và làm nổi bật những cơ hội bị bỏ lỡ.
Mặc dù Google Search Console cung cấp dữ liệu về hiệu suất của các trường, nhưng không cung cấp thông tin chi tiết theo thời gian thực. Dữ liệu của chỉ số này được tổng hợp trong khoảng thời gian 28 ngày, nên khó xác định chính xác những lượt tương tác nào đang gây ra vấn đề tại thời điểm đó.
Chúng tôi cần một cách để theo dõi INP theo thời gian thực nhằm xác định những lượt tương tác chậm nhất và được người dùng sử dụng thường xuyên nhất, đồng thời tái tạo những lượt tương tác đó một cách đáng tin cậy trong môi trường phát triển của nhóm. Điều quan trọng không kém là phải hiểu được tác động của những thay đổi đã thực hiện, không chỉ là những bản sửa lỗi hữu ích mà còn là những tinh chỉnh vô tình khiến mọi thứ trở nên tồi tệ hơn.
Vì những lý do này, chúng tôi đã sử dụng một bộ công cụ để giúp chẩn đoán và giải quyết các vấn đề. Những vấn đề quan trọng nhất là:
- Công cụ của Chrome cho nhà phát triển, cụ thể là thẻ Hiệu suất.
- Một hệ thống RUM (Giám sát người dùng thực) tuỳ chỉnh do nhóm Fotocasa xây dựng trong Datadog bằng thư viện web-vitals.
- React Developer Tools.
Công cụ chẩn đoán vấn đề
Để chẩn đoán và gỡ lỗi các vấn đề về hiệu suất INP, chúng tôi đã sử dụng các công cụ sau.
Công cụ của Chrome cho nhà phát triển
Một cách hiệu quả để phát hiện và tái tạo các vấn đề liên quan đến Các chỉ số quan trọng chính của trang web trong một ứng dụng web là sử dụng thẻ Hiệu suất trong Công cụ của Chrome cho nhà phát triển. Thẻ Hiệu suất tự động đo lường các chỉ số quan trọng chính của trang web, cung cấp ý kiến phản hồi tức thì về các chỉ số tải, khả năng tương tác và sự thay đổi bố cục. Chỉ số này thường nhất quán với cách các chỉ số này được báo cáo cho các công cụ khác của Google.
Để xác định và giải quyết các vấn đề về INP, nhóm Fotocasa thường bắt đầu bằng cách điều tiết CPU để mô phỏng hiệu suất của các thiết bị cấp thấp và tầm trung. Điều này cho phép nhóm Fotocasa quan sát cách trang hoạt động trong điều kiện bị hạn chế hơn. Sau đó, phiên hoạt động được ghi lại bằng trình phân tích tài nguyên và các dấu vết được phân tích cẩn thận, tập trung vào hoạt động tương tác của người dùng để xác định chính xác các vấn đề về hiệu suất.
Khi xác định các điểm tắc nghẽn, bạn nên xem xét các phần phụ của INP và những tác vụ mà trình duyệt thực hiện trong mỗi phần đó. Ví dụ: trong hình ảnh sau, bạn có thể thấy INP khá cao do 2 lần tính toán lại kiểu gây ra bởi các thay đổi về kiểu trong nội dung của tài liệu.
Fotocasa đã thiết lập một hệ thống để theo dõi INP và các chỉ số quan trọng chính khác của trang web, đảm bảo rằng mọi vấn đề về hiệu suất đều được xác định và giải quyết nhanh chóng. Khi một chỉ số vượt quá một ngưỡng cụ thể (dựa trên các phạm vi do Google xác định), hoạt động phân bổ sẽ được ghi lại để có thể phân tích và giải quyết vấn đề.
Đối với hệ thống đó, thư viện web-vitals được dùng để thu thập các chỉ số này từ người dùng thực tế theo cách khớp chính xác với cách Chrome đo lường và báo cáo các chỉ số này cho những công cụ khác của Google (chẳng hạn như Báo cáo trải nghiệm người dùng trên Chrome, PageSpeed Insights, Báo cáo tốc độ của Search Console và những công cụ khác).
Để có cái nhìn toàn diện và theo dõi tập trung, Fotocasa đã sử dụng Datadog để thu thập và trực quan hoá dữ liệu, giúp nhóm đưa ra các quyết định sáng suốt dựa trên dữ liệu. Các chỉ số tuỳ chỉnh giúp tiết kiệm chi phí và có khả năng theo dõi hầu hết người dùng trên trang web Fotocasa.
Hệ thống này giúp nhóm Fotocase nhanh chóng theo dõi xem các nội dung sửa đổi của họ có ảnh hưởng đến các chỉ số hay không hoặc có những thay đổi không lường trước nào xảy ra hay không, có khả năng ảnh hưởng đến các chỉ số đó. Sau đó, bạn có thể phân tích chỉ số INP thành các phần như độ trễ đầu vào, thời lượng xử lý và độ trễ trình bày để xác định chính xác phần nào của hoạt động tương tác chịu trách nhiệm chính cho thời gian tương tác dài.
Khi phát hiện các điểm bất thường, chẳng hạn như điểm bất thường minh hoạ trong hình 7 và 8, Fotocasa đã nhanh chóng phản hồi và sử dụng OpenSearch, một công cụ khác giúp xác định chính xác vị trí có thể xảy ra sự thay đổi. Dữ liệu do thư viện web-vitals cung cấp đã hỗ trợ xác định mục tiêu (phần tử DOM có thể chịu trách nhiệm về giá trị chỉ số cao) và giúp nhóm tập trung hơn vào việc khắc phục vấn đề.
Ngoài ra, bạn có thể xác định nhiều bộ lọc, chẳng hạn như loại trang, thiết bị hoặc trạng thái tải để đơn giản hoá các trường hợp và hiểu rõ hơn về mức độ ảnh hưởng của INP.
React Developer Tools
React Developer Tools được dùng để tăng cường khả năng gỡ lỗi của Fotocasa, cung cấp một tính năng mạnh mẽ cho phép bạn làm nổi bật các thành phần đã được kết xuất lại một cách trực quan.
Bạn có thể bật tính năng này bằng cách chuyển đến thẻ Profiler (Trình phân tích tài nguyên). Từ đó, hãy nhấp vào biểu tượng bánh răng ở bên phải thanh trên cùng, chuyển đến thẻ Chung rồi đánh dấu vào hộp Highlight updates when components render (Làm nổi bật nội dung cập nhật khi các thành phần hiển thị). Khi tính năng này được kích hoạt, các thành phần sẽ được làm nổi bật khi kết xuất lại, mang đến một hình ảnh trực quan linh động.
Tìm hiểu nguyên nhân của việc kết xuất lại
Sau khi xác định được thành phần đã kết xuất lại, câu hỏi tiếp theo là "tại sao điều đó lại xảy ra?" React DevTools trả lời câu hỏi này bằng một chú thích hữu ích trong chế độ xem biểu đồ dạng ngọn lửa.
Để truy cập vào thông tin này, hãy ghi lại một phiên hồ sơ. Bằng cách phân tích đầu ra của trình phân tích tài nguyên, bạn sẽ tìm thấy thông tin hữu ích:
- Ở góc trên cùng bên phải, số lượng lệnh cam kết React sẽ xuất hiện.
- Biểu đồ ngọn lửa biểu thị trực quan cây thành phần, trong đó màu xám cho biết những thành phần không kết xuất lại. Mỗi thanh đại diện cho một thời điểm mà cây thành phần React thay đổi và khi một thay đổi tương ứng được xác nhận với DOM.
- Khi di chuột lên từng thành phần trong biểu đồ ngọn lửa, bạn sẽ thấy lý do khiến thành phần đó kết xuất lại trong phần phụ đề Why did this render? (Tại sao thành phần này kết xuất?).
Sau đây là một số lý do khiến thành phần được kết xuất lại:
- Đây là lần đầu tiên thành phần này được kết xuất
- Đã thay đổi bối cảnh
- Đã thay đổi các hook
- Đã thay đổi các thành phần
- Bang đã thay đổi
- Thành phần mẹ được kết xuất
Tìm hiểu thời gian kết xuất
Màu sắc trong biểu đồ ngọn lửa truyền tải thông tin có ý nghĩa. Các màu như nhiều sắc độ của màu xanh dương cho biết một thành phần cần thời gian kết xuất tương đối ngắn so với các thành phần khác. Ngược lại, các màu như cam và đỏ cho biết một thành phần đã mất nhiều thời gian kết xuất hơn.
Cách nhóm Fotocasa khắc phục vấn đề
Xoá các lần kết xuất lại không cần thiết
Quá trình kết xuất lại xảy ra bất cứ khi nào React cần cập nhật giao diện người dùng bằng dữ liệu mới. Điều này thường đến từ một hành động của người dùng, một phản hồi API hoặc các sự kiện quan trọng khác yêu cầu cập nhật giao diện người dùng. Vì mỗi lần kết xuất lại đều chạy JavaScript, nên quá nhiều lần kết xuất lại cùng một lúc (đặc biệt là trong một cây thành phần lớn) có thể chặn luồng chính và gây ra các vấn đề về hiệu suất.
Có hai loại kết xuất lại:
- Cần thiết phải kết xuất lại: Khi một thành phần thực sự cần cập nhật vì thành phần đó sở hữu hoặc sử dụng dữ liệu mới.
- Kết xuất lại không cần thiết: Khi một thành phần cập nhật mà không có bất kỳ thay đổi nào đáng kể, thường là do việc quản lý trạng thái không hiệu quả hoặc xử lý prop không đúng cách.
Một vài lần kết xuất lại không cần thiết thường không phải là vấn đề lớn, vì React đủ nhanh để người dùng thường không nhận thấy. Tuy nhiên, nếu xảy ra quá thường xuyên hoặc trên một cây thành phần lớn, thì những sự kiện này có thể gây ảnh hưởng xấu đến trải nghiệm người dùng và ảnh hưởng tiêu cực đến INP của trang.
Đây là trường hợp của nhóm Fotocasa. Họ nhận ra rằng trang web có nhiều lần kết xuất lại không cần thiết. Những trường hợp này xảy ra trong 2 tình huống chính:
- Trong quá trình tải trang: Tăng số lượng tác vụ dài trên luồng chính và trì hoãn lượt tương tác đầu tiên, điều này ảnh hưởng tiêu cực đến chỉ số INP của trang.
- Trong các hoạt động tương tác của người dùng: Tăng thời gian xử lý của hầu hết các hoạt động tương tác, điều này cũng làm ảnh hưởng đến INP.
Nhiều lần kết xuất lại không cần thiết đã được tối ưu hoá trên trang web Fotocasa. Một trong những điểm tối ưu hoá lớn nhất mà chúng tôi nhận thấy là trên trang Tìm kiếm. Có 3 lần kết xuất lại không cần thiết khi tải trang. Sau khi xoá các mục này, chúng tôi nhận thấy những kết quả sau:
- Giảm số lượng tác vụ dài (xem hình sau)
- Tổng thời gian chặn ít hơn (so sánh hình 14 và 15)
Đồng vị trí theo trạng thái
Việc đặt trạng thái React không đúng cách có thể làm chậm ứng dụng và khiến giao diện người dùng có vẻ không phản hồi. Khi trạng thái của một thành phần thay đổi, các thành phần con của thành phần đó sẽ kết xuất lại theo mặc định, trừ phi bạn sử dụng một giải pháp thay thế (ví dụ: ghi nhớ).
Như đã giải thích trong phần trước, việc kết xuất lại không phải là điều xấu, nhưng việc kết xuất lại toàn bộ trang do một bản cập nhật trạng thái cụ thể có thể dẫn đến các hoạt động tương tác diễn ra chậm hơn, vì các bản cập nhật DOM diễn ra sau quá trình kết xuất.
Ví dụ: trên trang Tìm kiếm, có một hộp thoại cho thấy tất cả các bộ lọc khi người dùng nhấp vào một nút.
Trạng thái kiểm soát trạng thái mở của hộp thoại trong trường hợp này được đặt trong trang Tìm kiếm. Khi trạng thái này thay đổi, toàn bộ trang sẽ được kết xuất lại, gây ra INP kém, đặc biệt là trên các thiết bị có tốc độ chậm hơn như khi sử dụng tính năng điều tiết CPU trong Công cụ cho nhà phát triển:
Việc thay đổi trạng thái càng gần với thành phần kích hoạt thay đổi càng tốt sẽ giải quyết vấn đề này. Trong trường hợp cụ thể này, trạng thái có thể được đặt trong thành phần nút của bộ lọc, vì vậy, khi trạng thái thay đổi, chỉ nút sẽ được kết xuất lại.
Xoá các trạng thái không cần thiết
Các trạng thái không được chứa thông tin dư thừa hoặc trùng lặp. Nếu có, việc này có thể dẫn đến việc kết xuất lại không cần thiết và gây ra vấn đề.
Ví dụ: trong thanh bộ lọc của Fotocasa, có văn bản thể hiện số lượng bộ lọc được áp dụng cho một lượt tìm kiếm nhất định:
Số lượng bộ lọc được áp dụng được tính từ trạng thái của ứng dụng. Tuy nhiên, điều này không chỉ dẫn đến việc kết xuất lại không cần thiết toàn bộ thành phần mà trong một số trường hợp còn dẫn đến sự thay đổi bố cục vì thành phần này được kết xuất phía máy chủ:
const [filtersCount, setFiltersCount] = useState(DEFAULT_COUNTER)
useEffect(() => {
const counter = filters
? Object.keys(filters)
?.reduce(reducerCounter, [])
?.filter((param) => searchParams?.[param]).length
: DEFAULT_COUNTER
setFiltersCount(counter)
}, [searchParams]);
Để giải quyết vấn đề này, giá trị được lấy từ đối tượng bộ lọc bằng cách sử dụng một biến thay vì sử dụng trạng thái:
const counter = filters
? Object.keys(filters)
?.reduce(reducerCounter, [])
?.filter((param) => searchParams?.[param]).length
: DEFAULT_COUNTER;
Giảm số lượng khung hình tốn kém
Khi một hoạt động tương tác xảy ra trong ứng dụng React, hoạt động đó thường kích hoạt một thay đổi về trạng thái. Như đã giải thích trước đó, khi trạng thái của một thành phần thay đổi, thành phần đó sẽ được kết xuất lại cùng với tất cả thành phần con của nó.
Nếu một trong các hàm kết xuất thành phần này chạy chậm, thì INP của trang sẽ bị ảnh hưởng tiêu cực vì có thể một tác vụ dài sẽ được tạo và DOM sẽ mất nhiều thời gian hơn để cập nhật.
Nhóm Fotocasa đã cố gắng giảm thiểu tối đa các phép tính tốn thời gian trong hàm kết xuất của các thành phần. Công cụ dành cho nhà phát triển Chrome và Công cụ dành cho nhà phát triển React khá hữu ích trong việc phát hiện các thao tác kết xuất chậm.
Trì hoãn việc thực thi mã
Ngoài việc tối ưu hoá hàm kết xuất của các thành phần, các hàm khác cũng được tối ưu hoá để giảm thiểu tối đa các tác vụ dài. Tuy nhiên, một số tác vụ không thể tối ưu hoá vì chúng phụ thuộc vào mã của bên thứ ba.
Một ví dụ là số liệu phân tích. Trong trường hợp này, chúng tôi quyết định trì hoãn việc thực thi mã phân tích và ưu tiên các bản cập nhật DOM khi người dùng tương tác. Để đạt được điều này, nhóm Fotocasa đã sử dụng một thư viện có tên là idlefy. Thư viện này cũng đảm bảo rằng mã phân tích vẫn sẽ chạy ngay cả khi trình duyệt bị đóng ngay sau đó.
Văn hoá hiệu suất
Công việc cải thiện hiệu suất không phải là nỗ lực một lần, mà là việc bạn phải cân nhắc với mọi tính năng được phát hành cho sản xuất. Mọi người trong nhóm cần phải có cùng quan điểm, nếu không, việc giảm sút Các chỉ số quan trọng về trang web là điều khó tránh khỏi.
Để nắm bắt được vấn đề này, nhóm Fotocasa đã tích cực chia sẻ kiến thức trong nhóm và thiết lập một khung hình rõ ràng để xác định các vấn đề về hiệu suất dựa trên dữ liệu RUM của Datadog của Fotocasa, bao gồm cả cách tái tạo các vấn đề đó. Cảnh báo về Các chỉ số quan trọng chính của trang web (đặc biệt là INP) được thiết lập trong hệ thống RUM, được định cấu hình để thông báo trực tiếp cho nhóm Fotocasa trong Slack. Cách tiếp cận này giúp bạn luôn chú ý đến hiệu suất và phát hiện các vấn đề trước khi chúng trở thành lỗi hồi quy.
Kết quả
Để cải thiện INP tại Fotocasa, chúng tôi phải kết hợp các hoạt động tối ưu hoá về kỹ thuật và thay đổi về văn hoá. Bằng cách loại bỏ các lần kết xuất không cần thiết, tối ưu hoá việc đặt trạng thái, giảm các lần kết xuất tốn kém và trì hoãn mã không quan trọng, nhóm Fotocasa đã chuyển thành công tất cả các trang trên máy tính từ "cần cải thiện" sang "tốt" và cải thiện đáng kể các trang trên thiết bị di động bằng cách nâng cấp hầu hết các trang "kém" và "cần cải thiện" lên "tốt".
Những thay đổi này đã cải thiện trải nghiệm người dùng tổng thể của Fotocasa và cùng với các sáng kiến khác, đã giúp tăng 27% số lượt liên hệ và quảng cáo tạo khách hàng tiềm năng qua điện thoại, từ đó trực tiếp củng cố các chỉ số kinh doanh chính của công ty.
Nhờ tính năng giám sát theo thời gian thực của Datadog, nhóm Fotocasa có thể xác thực các điểm cải thiện về INP, nhanh chóng phát hiện điểm bất thường và ngăn chặn sự cố tái diễn. Ngoài những thành tựu này, Fotocasa cũng đã đưa hiệu suất trang web vào văn hoá phát triển của họ, đảm bảo rằng INP và Các chỉ số quan trọng về trang web vẫn là ưu tiên trong mọi bản phát hành.