Dự đoán prefetch giúp điều hướng truy cập nhanh hơn

Trong bài viết này bạn sẽ học cách dự đoán tìm nạp trước / prefetch hiệu quả hơn và cách sử dụng Guess.js để triển khai nó.

Trong video mà tôi nói về việc điều hướng truy cập web nhanh hơn thông qua dự đoán chính xác prefetch tại Google I/O 2019, tôi bắt đầu với việc đề cập đến tối ưu hóa ứng dụng web bằng biện pháp phân tách mã (code splitting) và ý nghĩa của việc cải thiện hiệu suất/tốc độ tiềm năng cho các truy cập (điều hướng) kế tiếp của người dùng (subsequent page navigation), tôi thảo luận về cách cải thiện tốc độ truy cập website bằng cách sử dụng thư viện Guess.js để thiết lập việc dự đoán prefetch chính xác hơn:

Phân chia mã để ứng dụng web tải nhanh hơn

Ứng dụng web thường chậm, và JavaScript là một trong các tài nguyên gây chậm trễ nhất mà website của bạn gửi cho người dùng. Việc phải đợi chờ ứng dụng web tải về có thể làm người dùng của bạn cảm thấy chán nản, bực dọc và ít nhiều làm giảm tỷ lệ chuyển đổi (decrease conversions).

thống kê về thời gian tải trên mạng kết nối di động 3G
Thống kê về thời gian tải trên mạng kết nối di động 3G

Lazy-loading (tải lười) là kỹ thuật hiệu quả để giảm dung lượng JavaScritp mà bạn phải truyền đến trình duyệt của người dùng tại một thời điểm. Bạn có thể sử dụng một số kỹ thuật lazy-load JavaScript, bao gồm:

  • Tách mã cấp độ thành phần (component-level)
  • Tách mã cấp độ tuyến (route-level)

Với tách mã cấp độ thành phần, bạn có thể chuyển các thành phần cụ thể vào các đoạn mã JavaScript riêng rẽ. Trên một sự kiện cụ thể, bạn có thể tải các đoạn mã liên quan và render các thành phần đó.

Với tách mã cấp độ tuyến, bạn có thể chuyển toàn bộ các tuyến vào các đoạn mã độc lập. Khi người dùng di chuyển từ tuyến này sang tuyến khác, họ có thể phải tải JavaScript liên quan và khởi động lại yêu cầu phải thực hiện của trang. Các hoạt động này có thể dẫn đến độ trễ đáng kể, đặc biệt trên các mạng có kết nối chậm.

Prefetch JavaScript

Prefetch cho phép trình duyệt tải và cache các tài nguyên mà người duyệt web có thể sử dụng trong tương lai gần. Phương thức phổ biến là thông qua sử dụng thẻ <link rel=’prefetch’>, nhưng có hai cạm bẫy phổ biến mà bạn cần lưu ý:

  • Prefetch gây tiêu thụ rất nhiều tài nguyên, có thể gọi là quá mức về mặt dữ liệu, băng thông và gia tăng gánh nặng cho máy chủ gốc.
  • Một số tài nguyên mà người sử dụng cần, có thể không bao giờ được prefetch.

Việc dự đoán prefetch (predictive prefetching) giúp giải quyết các vấn đề này bằng cách sử dụng các báo cáo dựa trên lịch sử của những phiên truy cập trước để đưa ra mẫu hành vi của người dùng, nhờ vậy nó sẽ xác định chính xác hơn tài nguyên cần prefetch.

mô hình prefetch JS
Mô hình prefetch JS: Bước 1 – mở trang web. Bước 2 – Xác định file JavaScript có khả năng cao được yêu cầu. Bước 3 – Tải file đó về. Bước 4 – Lưu trữ file đó trong cache trình duyệt.

Dự đoán các tài nguyên, liên kết cần prefetch bằng Guess.js

Guess.js là một thư viện JavaScript cung cấp khả năng dự đoán các liên kết nên prefetch. Guess.js sử dụng báo cáo từ Google Analytics hoặc các công cụ phân tích tương tự khác để xây dựng mô hình dự đoán (predictive model)- cái sẽ đem lại kết quả prefetch thông minh hơn tập trung vào nội dung mà người dùng có thể cần (thay vì tìm nạp trước tất cả nội dung, nó chỉ tìm nạp các nội dung có xác suất được dùng nhiều nhất trong tương lai nhờ biết được thói quen của người dùng trên trang của bạn).

Guess.js có khả năng tích hợp với Angular, Next.js, Nuxt.jsGatsby. Để sử dụng nó trong ứng dụng của bạn, bạn cần thêm những dòng sau vào tùy chỉnh webpack để chỉ định cụ thể Google Analytics view ID:

const { GuessPlugin } = require('guess-webpack');

// ...
plugins: [
   // ...
   new GuessPlugin({ GA: 'XXXXXX' })
]
// ...

Nếu bạn không sử dụng Google Analytics, bạn có thể chỉ định một reportProvider (báo cáo của công cụ phân tích khác) và tải dữ liệu về từ dịch vụ ưu thích của bạn.

Tích hợp với các framework

Để biết cách tích hợp Guess.js với các framework, bạn hãy tìm hiểu qua các liên kết sau:

Để có hướng dẫn nhanh về cách tích hợp với Angular, hãy xem video dưới đây:

Cách Guess.js hoạt động?

Dưới đây là cách Guess.js triển khai thực hiện nhiệm vụ dự đoán prefetch:

  1. Đầu tiên nó trích xuất dữ liệu cho các mẫu điều hướng của người dùng (user navigations patterns) từ thông tin mà nhà cung cấp dịch vụ phân tích website ưa thích của bạn thu thập được.
  2. Nó sau đó ánh xạ (maps) các URL từ báo cáo đến các đoạn mã JavaScript được tạo ra bởi webpack.
  3. Dựa trên dữ liệu đã trích xuất, nó tạo ra một mô hình dự đoán đơn giản các trang mà người dùng có khả năng điều hướng đến từ bất kỳ trang cho trước nào (any given page).
  4. Nó gọi mô hình cho từng đoạn mã JavaScript, dự đoán các đoạn mã khác có khả năng cao được sử dụng trong phiên kế tiếp.
  5. Nó thêm các hướng dẫn dự đoán prefetch cho từng đoạn mã.

Khi Guess.js được thực hiện, từng đoạn mã sẽ bao gồm các hướng dẫn prefetch tương tự như thế này:

__GUESS__.p(
  ['a.js', 0.2],
  ['b.js', 0.8]
)

Guess.js này tạo ra mã để nói cho trình duyệt biết nên cân nhắc prefetch các đoạn mã a.js với xác suất (cơ hội) 0,2 và đoạn mã b.js với xác suất (probability) 0,8.

Một khi trình duyệt thực thi đoạn mã, Guess.js sẽ kiểm tra tốc độ kết nối mạng của người dùng. Nếu tốc độ đủ đáp ứng yêu cầu, Guess.js sẽ chèn hai thẻ <link rel=’prefetch’> trong header của trang, mỗi cái cho từng đoạn mã. Nếu người dùng nằm trên mạng kết nối tốc độ cao, Guess.js sẽ prefetch cả hai đoạn mã. Nếu người dùng trên mạng kết chậm, Guess.js sẽ chỉ prefetch đoạn mã b.js vì nó có xác suất cần dùng cao hơn so với a.js.

(Dịch từ bài viết Faster web navigation with predictive prefetching, tác giả: Minko Gechev, website: web[.]dev)