Yêu bộ nhớ đệm của bạn ❤️

Người dùng tải trang web của bạn lần thứ hai sẽ sử dụng bộ nhớ đệm HTTP, vì vậy, hãy đảm bảo bộ nhớ đệm hoạt động tốt.

Bài đăng này đồng hành với video Yêu thích bộ nhớ đệm, thuộc Nội dung mở rộng tại Hội nghị Nhà phát triển Chrome năm 2020. Hãy nhớ xem những video này:

Khi người dùng tải trang web của bạn lần thứ hai, trình duyệt của họ sẽ sử dụng tài nguyên bên trong bộ nhớ đệm HTTP để giúp tải trang web nhanh hơn. Tuy nhiên, các tiêu chuẩn để lưu vào bộ nhớ đệm trên web có từ năm 1999 và được định nghĩa khá rộng rãi. Việc xác định một tệp, chẳng hạn như CSS hoặc hình ảnh, có thể được tìm nạp lại từ mạng so với việc tải từ bộ nhớ đệm hay không là một khoa học chưa chính xác.

Trong bài đăng này, tôi sẽ nói về một mặc định hợp lý và hiện đại để lưu vào bộ nhớ đệm – một phương pháp thực sự không hề lưu vào bộ nhớ đệm. Nhưng đó chỉ là mặc định, và khoá học có nhiều sắc thái hơn so với việc chỉ "tắt chế độ cài đặt". Hãy đọc tiếp!

Bàn thắng

Khi một trang web được tải lần thứ hai, bạn có hai mục tiêu:

  1. Hãy đảm bảo rằng người dùng của bạn nhận được phiên bản mới nhất có sẵn — nếu bạn đã thay đổi nội dung nào đó, phiên bản đó sẽ được phản ánh nhanh chóng
  2. Làm #1 trong khi tìm nạp càng ít từ mạng càng tốt

Theo nghĩa rộng nhất, bạn chỉ nên gửi thay đổi nhỏ nhất cho khách hàng khi họ tải lại trang web của bạn. Đồng thời, việc cấu trúc trang web của bạn để đảm bảo việc phân phối hiệu quả nhất bất kỳ thay đổi nào cũng là một thách thức (bạn có thể tìm hiểu thêm về điều này ở bên dưới và trong video).

Tuy nhiên, bạn cũng có các nút khác khi cân nhắc việc lưu vào bộ nhớ đệm, có thể là bạn đã quyết định để bộ nhớ đệm HTTP của trình duyệt lưu giữ trang web của bạn trong một thời gian dài để không yêu cầu bất kỳ yêu cầu mạng nào để phân phát trang. Hoặc bạn đã tạo một trình chạy dịch vụ sẽ phân phát trang web hoàn toàn khi không có mạng trước khi kiểm tra xem trang web đó đã cập nhật hay chưa. Đây là một lựa chọn cực kỳ hợp lệ, và được sử dụng cho nhiều trải nghiệm web giống như ứng dụng có chế độ ngoại tuyến, nhưng web không nhất thiết phải ở chế độ cực kỳ chỉ dành cho bộ nhớ đệm hoặc thậm chí là hoàn toàn chỉ áp dụng cho mạng.

Thông tin khái quát

Là nhà phát triển web, tất cả chúng ta đã quen với ý tưởng có một "bộ nhớ đệm đã lỗi thời". Nhưng chúng tôi biết, gần như theo bản năng, các công cụ có sẵn để giải quyết vấn đề này: tiến hành "làm mới cứng" hoặc mở một cửa sổ ẩn danh, hoặc sử dụng tổ hợp nào đó các công cụ dành cho nhà phát triển của trình duyệt để xoá dữ liệu của trang web.

Những người dùng thường xuyên trên Internet cũng không có gì xa lạ đến thế. Vì vậy, mặc dù chúng tôi có một số mục tiêu cốt lõi là đảm bảo người dùng có khoảng thời gian tuyệt vời với lần tải thứ hai, nhưng chúng tôi cũng phải đảm bảo họ không có thời gian không vui hoặc bị mắc kẹt. (Hãy xem video nếu bạn muốn nghe tôi nói về cách chúng tôi gần như khiến trang web web.dev/live gặp sự cố!)

Đối với một chút thông tin cơ bản, một lý do thực sự phổ biến dẫn đến "bộ nhớ đệm đã lỗi thời" thực sự là chế độ mặc định từ năm 1999 để lưu vào bộ nhớ đệm. Tính năng này dựa vào tiêu đề Last-Modified:

Sơ đồ cho thấy thời lượng các thành phần khác nhau được lưu vào bộ nhớ đệm trên trình duyệt của người dùng
Những thành phần được tạo tại các thời điểm khác nhau (màu xám) sẽ được lưu vào bộ nhớ đệm vào những thời điểm khác nhau. Vì vậy, lần tải thứ 2 có thể kết hợp thành phần đã lưu vào bộ nhớ đệm và tài sản mới vào bộ nhớ đệm

Mỗi tệp bạn tải sẽ được lưu giữ trong thêm 10% thời gian tồn tại hiện tại, vì trình duyệt của bạn sẽ nhìn thấy tệp đó. Ví dụ: nếu index.html được tạo một tháng trước, thì tệp đó sẽ được trình duyệt của bạn lưu vào bộ nhớ đệm trong khoảng 3 ngày nữa.

Đây là ý tưởng có chủ đích trước đó, nhưng với bản chất tích hợp chặt chẽ của các trang web hiện nay, hành vi mặc định này có nghĩa là người dùng có thể rơi vào trạng thái có các tệp được thiết kế cho các bản phát hành khác nhau của trang web (ví dụ: JS của bản phát hành vào thứ Ba và CSS của bản phát hành thứ Sáu), tất cả vì những tệp đó không được cập nhật vào đúng thời điểm.

Đường đi có đủ ánh sáng

Một chế độ mặc định hiện đại để lưu vào bộ nhớ đệm là thực sự không lưu vào bộ nhớ đệm và sử dụng CDN để đưa nội dung đến gần người dùng hơn. Mỗi khi người dùng tải trang web của bạn, họ sẽ vào mạng để xem liệu trang web đó có cập nhật hay không. Yêu cầu này sẽ có độ trễ thấp vì sẽ do một CDN ở gần mỗi người dùng cuối cung cấp.

Bạn có thể định cấu hình nhà cung cấp dịch vụ lưu trữ web để phản hồi các yêu cầu web có tiêu đề này:

Cache-Control: max-age=0,must-revalidate,public

Về cơ bản, điều này cho thấy tệp này hoàn toàn hợp lệ và bạn phải xác thực tệp từ mạng trước khi có thể sử dụng lại tệp (nếu không, tệp chỉ được "đề xuất").

Quá trình xác thực này tương đối rẻ về số lượng byte được truyền (nếu tệp hình ảnh lớn không thay đổi, trình duyệt của bạn sẽ nhận được một phản hồi 304 nhỏ), nhưng sẽ gây ra độ trễ vì người dùng vẫn phải vào mạng để tìm hiểu. Và đây là nhược điểm chính của phương pháp này. Dịch vụ này có thể hoạt động rất hiệu quả đối với những người sử dụng kết nối nhanh ở thế giới thứ nhất, khi CDN mà bạn lựa chọn có phạm vi phủ sóng rộng, nhưng không phải đối với những người có kết nối di động chậm hơn hoặc sử dụng cơ sở hạ tầng kém.

Dù vậy, đây là một phương pháp hiện đại là phương pháp mặc định trên một CDN phổ biến, Netlify, nhưng có thể định cấu hình trên hầu hết mọi CDN. Đối với tính năng Lưu trữ Firebase, bạn có thể đưa tiêu đề này vào phần lưu trữ của tệp firebase.json:

"headers": [
  // Be sure to put this last, to not override other headers
  {
    "source": "**",
    "headers": [ {
      "key": "Cache-Control",
      "value": "max-age=0,must-revalidate,public"
    }
  }
]

Vì vậy, mặc dù tôi vẫn đề xuất đây là một chế độ mặc định hợp lý, nhưng đó chỉ là mặc định! Đọc tiếp để tìm hiểu cách bước vào và nâng cấp các chế độ mặc định.

URL được đặt dấu vân tay

Bằng cách thêm hàm băm của nội dung tệp vào tên thành phần, hình ảnh, v.v. được phân phát trên trang web của bạn, bạn có thể đảm bảo rằng các tệp này sẽ luôn có nội dung riêng biệt — điều này sẽ tạo ra các tệp có tên là sitecode.af12de.js chẳng hạn. Khi máy chủ của bạn phản hồi yêu cầu về những tệp này, bạn có thể hướng dẫn trình duyệt của người dùng cuối lưu những tệp đó vào bộ nhớ đệm trong thời gian dài một cách an toàn bằng cách định cấu hình các tệp đó bằng tiêu đề sau:

Cache-Control: max-age=31536000,immutable

Giá trị này là năm, tính bằng giây. Và theo thông số kỹ thuật, điều này thực sự tương đương với "mãi mãi".

Quan trọng là bạn không nên tạo thủ công các hàm băm này vì sẽ mất quá nhiều công sức! Bạn có thể sử dụng các công cụ như Webpack, Rollup, v.v. để giải quyết vấn đề này. Hãy nhớ đọc thêm về các báo cáo này trong Báo cáo về công cụ.

Hãy nhớ rằng không chỉ JavaScript có thể hưởng lợi từ các URL được tạo vân tay số; các thành phần như biểu tượng, CSS và các tệp dữ liệu không thể thay đổi khác cũng có thể được đặt tên theo cách này. (Và hãy nhớ xem video ở trên để tìm hiểu thêm một chút về cách phân tách mã, giúp bạn gửi ít mã hơn mỗi khi trang web của bạn thay đổi.)

Bất kể trang web của bạn sử dụng phương pháp lưu vào bộ nhớ đệm như thế nào, những loại tệp có vân tay số này đều cực kỳ có giá trị đối với mọi trang web mà bạn có thể xây dựng. Hầu hết các trang web sẽ không thay đổi trên mỗi bản phát hành.

Tất nhiên, chúng tôi không thể đổi tên các trang "thân thiện" dành cho người dùng theo cách sau: đổi tên tệp index.html thành index.abcd12.html – điều đó không khả thi, bạn không thể yêu cầu người dùng chuyển đến một URL mới mỗi khi tải trang web của bạn! Tôi không thể đổi tên và lưu các URL "thân thiện" này vào bộ nhớ đệm theo cách này. Việc này sẽ đưa tôi đến một nền tảng phù hợp.

Nền tảng

Rõ ràng là vẫn còn chỗ cần thiết khi lưu vào bộ nhớ đệm. Tôi đã trình bày hai lựa chọn cực kỳ quan trọng: lưu vào bộ nhớ đệm không bao giờ hoặc lưu vào bộ nhớ đệm vĩnh viễn. Và sẽ có một số tệp mà có thể bạn muốn lưu vào bộ nhớ đệm một thời gian, chẳng hạn như các URL "thân thiện" mà tôi đã đề cập ở trên.

Nếu muốn lưu những URL "thân thiện" này và HTML của các URL đó vào bộ nhớ đệm, bạn nên xem xét những phần phụ thuộc chứa những URL này, cách các URL đó có thể được lưu vào bộ nhớ đệm và mức độ ảnh hưởng của việc lưu URL vào bộ nhớ đệm trong một thời gian đối với bạn. Hãy xem trang HTML có chứa một hình ảnh như sau:

<img src="/images/foo.jpeg" loading="lazy" />

Nếu bạn cập nhật hoặc thay đổi trang web bằng cách xoá hoặc thay đổi hình ảnh tải từng phần này, thì người dùng xem phiên bản HTML đã lưu vào bộ nhớ đệm có thể nhận được hình ảnh không chính xác hoặc bị thiếu vì họ vẫn đã lưu vào bộ nhớ đệm /images/foo.jpeg gốc khi truy cập lại trang web của bạn.

Nếu bạn cẩn thận, việc này có thể không ảnh hưởng đến bạn. Nhưng nhìn chung, bạn cần nhớ rằng trang web của bạn (khi được người dùng cuối lưu vào bộ nhớ đệm) không còn tồn tại trên máy chủ của bạn nữa. Thay vào đó, tệp có thể tồn tại trong các phần bên trong bộ nhớ đệm trên trình duyệt của người dùng cuối.

Nhìn chung, hầu hết các hướng dẫn về việc lưu vào bộ nhớ đệm sẽ nói về loại chế độ cài đặt này, tức là bạn có muốn lưu vào bộ nhớ đệm trong một giờ, vài giờ, v.v. hay không. Để thiết lập loại bộ nhớ đệm này, hãy sử dụng tiêu đề như sau (lưu vào bộ nhớ đệm trong 3600 giây hoặc một giờ):

Cache-Control: max-age=3600,immutable,public

Một điểm cuối cùng. Nếu bạn đang tạo nội dung kịp thời mà thường chỉ người dùng mới có thể truy cập một lần — như tin bài! — ý kiến của tôi là những nội dung này không nên được lưu vào bộ nhớ đệm và bạn nên sử dụng chế độ mặc định hợp lý của chúng tôi ở trên. Tôi nghĩ chúng ta thường đánh giá cao giá trị của việc lưu vào bộ nhớ đệm đối với việc người dùng luôn muốn xem những nội dung mới nhất và hay nhất, chẳng hạn như nội dung cập nhật quan trọng về một bản tin hoặc sự kiện hiện tại.

Tuỳ chọn không phải HTML

Ngoài HTML, một số tuỳ chọn khác cho các tệp nằm trong nền tảng trung gian bao gồm:

  • Nhìn chung, hãy tìm những thành phần không ảnh hưởng đến người khác

    • Ví dụ: tránh sử dụng CSS vì CSS này làm thay đổi cách hiển thị HTML của bạn
  • Hình ảnh lớn được dùng trong các bài viết hợp thời

    • Người dùng có thể không truy cập một bài viết nào nhiều hơn vài lần, vì vậy, đừng lưu ảnh hoặc hình ảnh chính vào bộ nhớ đệm mãi mãi và lãng phí bộ nhớ
  • Một thành phần đại diện cho một nội dung nào đó luôn có giá trị vòng đời

    • Dữ liệu JSON về thời tiết có thể chỉ được xuất bản mỗi giờ một lần. Vì vậy, bạn có thể lưu kết quả trước đó vào bộ nhớ đệm trong một giờ — dữ liệu này sẽ không thay đổi trong cửa sổ của bạn
    • Các bản dựng của một dự án nguồn mở có thể bị giới hạn tốc độ, vì vậy, hãy lưu hình ảnh trạng thái bản dựng vào bộ nhớ đệm cho đến khi trạng thái có thể thay đổi

Tóm tắt

Khi người dùng tải trang web của bạn lần thứ hai, tức là bạn đã có phiếu tin tưởng—họ muốn quay lại và nhận thêm sản phẩm bạn cung cấp. Tại thời điểm này, không phải lúc nào bạn cũng giảm được thời gian tải. Bạn có rất nhiều tuỳ chọn để đảm bảo rằng trình duyệt chỉ thực hiện công việc cần thiết để mang lại cả trải nghiệm nhanh và mới nhất.

Lưu vào bộ nhớ đệm không phải là một khái niệm mới trên web, nhưng có lẽ cần một mặc định hợp lý. Hãy cân nhắc sử dụng một chiến lược lưu vào bộ nhớ đệm hiệu quả hơn khi cần. Cảm ơn bạn đã đọc!

Xem thêm

Để biết hướng dẫn chung về bộ nhớ đệm HTTP, hãy xem bài viết Ngăn chặn các yêu cầu không cần thiết về mạng nhờ bộ nhớ đệm HTTP.