Giới thiệu về API ngân sách

API Thông báo đẩy cho phép chúng ta gửi thông báo đến người dùng ngay cả khi trình duyệt đã đóng. Nhiều nhà phát triển muốn có thể sử dụng thông báo này để cập nhật và đồng bộ hoá nội dung mà không cần mở trình duyệt, nhưng API có một hạn chế quan trọng: bạn phải luôn hiển thị thông báo cho mọi thông báo đẩy riêng lẻ nhận được.

Việc có thể gửi thông báo đẩy để đồng bộ hoá dữ liệu trên thiết bị của người dùng hoặc ẩn thông báo bạn đã hiển thị trước đó có thể cực kỳ hữu ích đối với người dùng và nhà phát triển, nhưng việc cho phép một ứng dụng web hoạt động trong nền mà người dùng không biết là họ có thể bị lạm dụng.

Ngân sách API là một API mới được thiết kế để cho phép nhà phát triển thực hiện một số thao tác trong nền mà không cần thông báo cho người dùng, chẳng hạn như tìm nạp ở chế độ im lặng hoặc tìm nạp trong nền. Trong Chrome 60 trở lên, bạn có thể bắt đầu sử dụng API này. Nhóm Chrome rất mong nhận được ý kiến phản hồi của các nhà phát triển.

Để cho phép nhà phát triển sử dụng tài nguyên của người dùng ở chế độ nền, nền tảng web sẽ giới thiệu khái niệm về ngân sách bằng cách sử dụng API Ngân sách mới. Mỗi trang web sẽ được cấp một lượng tài nguyên dựa trên mức độ tương tác của người dùng mà trang web đó có thể sử dụng cho các hành động trong nền, chẳng hạn như lệnh đẩy ngầm, trong đó mỗi thao tác sẽ làm cạn kiệt ngân sách. Khi chi tiêu hết ngân sách, các thao tác trong nền sẽ không còn được thực hiện khi người dùng không nhìn thấy. Tác nhân người dùng sẽ chịu trách nhiệm xác định ngân sách được chỉ định cho một ứng dụng web dựa trên thông tin phỏng đoán của ứng dụng đó, ví dụ: mức ngân sách được cấp có thể được liên kết với mức độ tương tác của người dùng. Mỗi trình duyệt có thể tự quyết định đó là phương pháp phỏng đoán của riêng mình.

Tóm tắt: API ngân sách cho phép bạn đặt trước ngân sách, sử dụng ngân sách, nhận danh sách ngân sách còn lại và tìm hiểu chi phí của các hoạt động ở chế độ nền

Ngân sách đặt trước

Trong Chrome 60 trở lên, phương thức navigator.budget.reserve() sẽ hoạt động mà không có bất kỳ cờ nào.

Phương thức reserve() cho phép bạn yêu cầu ngân sách cho một thao tác cụ thể và phương thức này sẽ trả về một giá trị boolean cho biết có thể đặt trước ngân sách hay không. Nếu ngân sách đã được đặt trước, thì bạn không cần thông báo cho người dùng về công việc trong nền.

Trong ví dụ về thông báo đẩy, bạn có thể thử đặt trước ngân sách cho thao tác "đẩy im lặng" và nếu reserve() phân giải bằng giá trị true, thao tác này sẽ được cho phép. Nếu không, kết quả sẽ trả về là false và bạn cần phải hiển thị thông báo

self.addEventListener('push', event => {
 const promiseChain = navigator.budget.reserve('silent-push')
   .then((reserved) => {
     if (reserved) {
       // No need to show a notification.
       return;
     }

     // Not enough budget is available, must show a notification.
     return registration.showNotification(...);
   });
 event.waitUntil(promiseChain);
});

Trong Chrome 60, "silent-push" là loại thao tác duy nhất hiện có sẵn, nhưng bạn có thể tìm thấy danh sách đầy đủ các loại hoạt động trong phần thông số kỹ thuật. Ngoài ra, không có cách nào dễ dàng để tăng ngân sách cho mục đích thử nghiệm hoặc gỡ lỗi sau khi sử dụng. Tuy nhiên, giải pháp tạm thời là bạn có thể tạo một hồ sơ mới trong Chrome. Tiếc là bạn không thể sử dụng chế độ ẩn danh cho chế độ này vì API Ngân sách sẽ trả về ngân sách bằng 0 ở chế độ Ẩn danh (mặc dù có một lỗi dẫn đến lỗi trong quá trình thử nghiệm của tôi).

Bạn chỉ nên gọi reserve() khi có ý định thực hiện thao tác mà bạn đang đặt trước tại một thời điểm nào đó trong tương lai. Xin lưu ý rằng nếu bạn đã gọi đặt trước trong ví dụ trên nhưng vẫn hiển thị thông báo, thì ngân sách sẽ vẫn được sử dụng.

Một trường hợp sử dụng phổ biến mà riêng reserve() không hỗ trợ, đó là khả năng lên lịch cho lệnh đẩy ở chế độ im lặng từ một phần phụ trợ. API ngân sách có API để bật trường hợp sử dụng này nhưng các API đó vẫn đang được xử lý trong Chrome và hiện chỉ hoạt động sau cờ và / hoặc Bản dùng thử theo nguyên gốc.

Bản dùng thử theo nguyên gốc và API ngân sách

Ứng dụng web có thể dùng 2 phương thức là getBudget()getCost() để lập kế hoạch sử dụng ngân sách.

Trong Chrome 60, cả hai phương thức này đều có sẵn nếu bạn đăng ký bản dùng thử theo nguyên gốc. Tuy nhiên, nếu không muốn kiểm thử, bạn có thể sử dụng cục bộ bằng cách bật cờ các tính năng của Nền tảng web thử nghiệm (Mở chrome://flags/#enable-experimental-web-platform-features trong Chrome).

Hãy xem cách sử dụng các API này.

Xem ngân sách của bạn

Bạn có thể xem ngân sách hiện có bằng phương thức getBudget(). Một số trình duyệt (như Chrome) sẽ có ngân sách "giảm dần" theo thời gian. Vì vậy, để bạn có thể nhìn thấy toàn bộ, trình duyệt sẽ trả về một mảng BudgetStates, cho biết ngân sách của bạn sẽ là bao nhiêu vào các thời điểm khác nhau trong tương lai.

Để liệt kê các mục nhập ngân sách, chúng tôi có thể chạy:

navigator.budget.getBudget()
.then((budgets) => {
  budgets.forEach((element) => {
    console.log(\`At '${new Date(element.time).toString()}' \` +
      \`your budget will be '${element.budgetAt}'.\`);
  });
});

Mục đầu tiên là ngân sách hiện tại và các giá trị bổ sung sẽ cho biết ngân sách của bạn ở các thời điểm khác nhau trong tương lai.

At 'Mon Jun 05 2017 12:47:20' you will have a budget of '3'.
At 'Fri Jun 09 2017 10:42:57' you will have a budget of '2'.
At 'Fri Jun 09 2017 12:31:09' you will have a budget of '1'.

Một trong những lợi ích của việc thêm các khoản dự phòng ngân sách trong tương lai là nhà phát triển có thể chia sẻ thông tin này với phần phụ trợ của họ để điều chỉnh hành vi phía máy chủ (tức là chỉ gửi thông báo đẩy để kích hoạt bản cập nhật khi máy khách có ngân sách cho một lệnh đẩy ngầm).

Xem chi phí vận hành

Để biết chi phí của một thao tác, việc gọi getCost() sẽ trả về một số cho biết số tiền ngân sách tối đa sẽ được chi tiêu nếu bạn gọi reserve() cho thao tác đó.

Ví dụ: chúng ta có thể tìm ra chi phí của việc không hiển thị thông báo khi bạn nhận được thông báo đẩy (tức là chi phí của lệnh đẩy ngầm ẩn) với mã sau:

navigator.budget.getCost('silent-push')
.then((cost) => {
  console.log('Cost of silent push is:', cost);
})
.catch((err) => {
  console.error('Unable to get cost:', err);
});

Tại thời điểm viết, Chrome 60 sẽ in:

Cost of silent push is: 2

Một điều cần làm nổi bật với phương thức reserve()getCost() là chi phí thực tế của một hoạt động có thể thấp hơn chi phí mà getCost() trả về. Bạn vẫn có thể đặt trước một hoạt động nếu ngân sách hiện tại thấp hơn chi phí được chỉ định. Thông tin chi tiết cụ thể trong quy cách như sau:

Đó là API hiện tại trong Chrome và vì web tiếp tục hỗ trợ các API mới yêu cầu khả năng thực hiện tác vụ trong nền, chẳng hạn như tìm nạp trong nền, nên bạn có thể sử dụng API Ngân sách để quản lý số lượng thao tác bạn có thể thực hiện mà không cần thông báo cho người dùng.

Khi bạn sử dụng API, vui lòng đưa ra ý kiến phản hồi trên GitHub Repo hoặc báo cáo lỗi với Chrome tại crbug.com.