Có thực tế không khi sử dụng bộ nhớ cục bộ HTML5 để lưu trữ CSS và JavaScript


22

Ý tưởng là sử dụng bộ nhớ cục bộ HTML5 để lưu trữ CSS và JavaScript được truy cập thường xuyên.

Ví dụ: mã giả):

var load_from_cdn = true;
if (phát hiện lưu trữ cục bộ)  
{
  if (bộ nhớ cache của css, tìm thấy js)
  {
     tải bộ nhớ cache cục bộ
     load_from_cdn = false;
  }
}
if (load_from_cdn)
{
   document.write ('<script> ...');
}

Điều này có thể hay thực tế?

Tôi biết bộ nhớ cache của trình duyệt, vẫn sẽ có một số kiểm tra truy cập tiêu đề,
tôi cho rằng không có quyền truy cập HTTP nào tốt hơn (theo suy nghĩ của tôi )

PS: Có vẻ như bộ nhớ cục bộ chỉ hỗ trợ cặp khóa-giá trị , ai đó có thể chứng minh điều đó không?
(tốt nhất với một số ví dụ)


1
Wikipedia rõ ràng đã thử hiệu quả tuyệt vời này: twitter.com/catrope/status/408018210529615872 twitter.com/catrope/status/408018210529615872/photo/1
Dave

1
đó là ý tưởng 2 năm trước của tôi ... :)
ajreal

Câu hỏi của bạn là điều đầu tiên tôi tìm thấy khi tôi hiểu về nó. Có rất nhiều cuộc thảo luận ở đây về việc liệu đó có phải là một ý tưởng tốt hay không, vì vậy tôi nghĩ rằng tôi sẽ cung cấp một số bằng chứng giai thoại có lợi!
Dave

1
Hình ảnh đó là sai lệch. Nếu bạn cuộn xuống sâu hơn, bạn có thể thấy rằng sự sụt giảm lớn trên thực tế không phải vì lưu trữ cục bộ tốt hơn bộ nhớ đệm, mà là một lỗi trong thiết lập bộ nhớ đệm của họ: " Hóa ra là ít ngoạn mục hơn :(. Đồ thị là lưu lượng truy cập nội bộ, giảm do đến localStorage ẩn lỗi bộ nhớ đệm "- twitter.com/catrope/status/408110382599782400
Jamie Barker

Câu trả lời:


11

Hoàn toàn ổn khi sử dụng bộ nhớ cục bộ để lưu trữ JS và CSS. Tuy nhiên, lưu trữ cục bộ có 5M cho mỗi giới hạn tên miền. Bạn có thể phải xem xét lại chiến lược này.

Đối với web trên máy tính để bàn, bạn có thể tận dụng bộ đệm của trình duyệt mặc định để thực hiện thủ thuật. Chỉ cần đặt phản hồi HTTP JS & CSS thành bộ nhớ cache. Nó rất đơn giản và dễ dàng.

Đối với web di động, độ trễ là cao. Vì vậy, giảm yêu cầu HTTP là rất quan trọng. Vì vậy, có JS & CSS trong URL bên ngoài là tối ưu. Sẽ tốt hơn nhiều nếu có nội tuyến JS & CSS. Điều này làm giảm các yêu cầu HTTP, nhưng làm mờ nội dung HTML. Rồi sao? Như bạn đã nói, sử dụng lưu trữ cục bộ!

Khi một trình duyệt truy cập trang web lần đầu tiên, JS & CSS sẽ được đặt nội tuyến. JS cũng có thêm hai công việc: 1) Lưu trữ JS & CSS vào bộ nhớ cục bộ; 2) Đặt cookie để gắn cờ rằng JS & CSS đang lưu trữ cục bộ.

Khi trình duyệt truy cập trang web lần thứ hai, máy chủ đã nhận được cookie và biết rằng trình duyệt đã có JS & CSS liên quan. Vì vậy, HTML kết xuất có JS nội tuyến để đọc JS & CSS từ bộ nhớ cục bộ và chèn vào cây DOM.

Đây là ý tưởng cơ bản về cách tạo ra phiên bản di động bing.com. Bạn có thể cần phải xem xét kiểm soát phiên bản JS & CSS khi triển khai nó trong sản xuất.

Cảm ơn


Vâng, khá gần với những gì tôi nghĩ.
ajreal

Google đã phát triển một mô-đun cho Page Speed ​​Mod thực hiện điều tương tự. Đây là trang nơi họ nói về hàng hóa, xấu và không biết nhà phát
triển.google.com/speed/pagespeed/module/ mẹo

nâng cấp, nhưng wtf có nghĩa là "nội tuyến" trong trường hợp này. "Nội tuyến" có 5 ý nghĩa khác nhau.
Alexander Mills

1
Nó thực sự đã tăng lên 10 MB cho Máy tính để bàn và 5 MB cho thiết bị di động
Roko C. Buljan

1
Bạn không cần bất kỳ cookie. bạn chỉ có thể đọc nếu bộ lưu trữ cục bộ có khóa / giá trị bạn đang tìm kiếm cộng với bạn phải cung cấp một phiên bản (cho mục đích vô hiệu rõ ràng). Thủ thuật này chỉ tốt sau lần truy cập thứ hai của trang web và cả khi tài sản không có trong bộ đệm (vì một số lý do)
vsync


23

Vấn đề ở đây là gì?

Đã có một kỹ thuật được thiết lập tốt được gọi là bộ nhớ đệm phía máy khách. Bộ nhớ cục bộ HTML5 mang lại điều gì trong trường hợp này bộ nhớ đệm bị thiếu?

Bạn có thể có một số loại ứng dụng lạ phải tự động tải các đoạn mã JavaScript để bạn không thể sử dụng bộ đệm một cách hiệu quả, nhưng đó là một trường hợp cực kỳ hiếm.

Ngoài ra, hãy chú ý đến một điều khác. Các trình duyệt có chính sách cụ thể cho bộ đệm và hầu hết các trình duyệt khá tốt trong việc quản lý tốt bộ đệm (chỉ xóa nội dung cũ hơn, v.v.). Bằng cách triển khai bộ đệm tự tạo tại nhà, bạn ngăn các trình duyệt quản lý nó một cách chính xác. Nó không chỉ có thể bị chỉ trích mà còn có thể làm tổn thương bạn sớm hay muộn. Ví dụ: khi người dùng ứng dụng web báo cáo lỗi, bạn thường trả lời bằng cách yêu cầu họ xóa bộ nhớ cache. Tôi không chắc chắn những gì bạn sẽ hỏi trong trường hợp của bạn, vì xóa bộ nhớ cache sẽ không bao giờ giải quyết vấn đề với ứng dụng web của bạn.


Đáp lại lần chỉnh sửa đầu tiên của bạn (lần chỉnh sửa thứ hai của bạn không có chủ đề):

Tôi biết bộ nhớ cache của trình duyệt, vẫn sẽ có một số kiểm tra truy cập tiêu đề

Bạn dường như thiếu một số hiểu biết về bộ nhớ đệm trình duyệt. Đó là lý do tại sao cần phải hiểu cách thức hoạt động của nó trước tiên, trước khi bắt đầu thực hiện cơ chế bộ nhớ đệm tự làm tại nhà . Chỉ phát minh lại bánh xe của riêng bạn khi bạn hiểu đủ các bánh xe hiện có và có lý do chính đáng để không sử dụng chúng. Xem điểm 1 trong câu trả lời của tôi cho câu hỏi "Phát minh lại bánh xe và KHÔNG hối tiếc" .

Khi cung cấp một số dữ liệu qua HTTP, bạn có thể chỉ định một vài tiêu đề liên quan đến bộ đệm:

  • Last-Modified Chỉ định khi nội dung được thay đổi,
  • ExpiresChỉ định khi trình duyệt phải yêu cầu máy chủ nếu nội dung thay đổi .

Hai tiêu đề này cho phép trình duyệt:

  • Tránh tải xuống nội dung nhiều lần. Nếu Last-Modifiedđược đặt thành tháng trước và nội dung đã được tải xuống hôm nay một vài giờ trước đó, thì không cần phải tải lại.
  • Tránh truy vấn cho ngày mà tệp được sửa đổi lần cuối. Nếu Expiresmột thực thể bộ nhớ cache là ngày 05 tháng 5 ngày , năm 2014, bạn không cần phải đưa ra bất cứ yêu cầu GET không phải trong năm 2011, cũng không phải trong năm 2012 hoặc năm 2013, kể từ khi bạn biết rằng bộ nhớ cache là up-to-date.

Cái thứ hai là cần thiết cho CDN. Khi Google phục vụ JQuery cho khách truy cập Stack Overflow hoặc cdn.sstatic.netphục vụ hình ảnh hoặc bảng định kiểu được sử dụng bởi Stack Overflow, họ không muốn trình duyệt truy vấn phiên bản mới mỗi lần. Thay vào đó, họ đang phục vụ các tệp đó một lần, đặt ngày hết hạn thành một cái gì đó đủ lâu và đó là tất cả.

Ví dụ, đây là ảnh chụp màn hình về những gì đang xảy ra khi tôi đến trang chủ Stack Overflow:

Ảnh chụp màn hình dòng thời gian Stack Overflow trong Chrome hiển thị 15 tệp, 3 được yêu cầu, 12 được phục vụ trực tiếp từ bộ đệm mà không yêu cầu máy chủ từ xa

Có 15 tập tin để phục vụ. Nhưng tất cả những 304 Not Modifiedphản ứng đó ở đâu? Bạn chỉ có ba yêu cầu nội dung đã thay đổi. Đối với mọi thứ khác, trình duyệt sử dụng phiên bản được lưu trong bộ nhớ cache mà không yêu cầu bất kỳ máy chủ nào .


Để kết luận, bạn thực sự cần phải suy nghĩ kỹ trước khi thực hiện cơ chế bộ đệm của riêng mình và đặc biệt là tìm một kịch bản tốt trong đó điều này có thể hữu ích . Như tôi đã nói ở đầu câu trả lời của mình, tôi chỉ có thể tìm thấy một: nơi bạn đang phục vụ các đoạn JavaScript để sử dụng chúng thông qua, OMG eval(),. Nhưng trong trường hợp này, tôi khá chắc chắn rằng có những cách tiếp cận tốt hơn:

  • Hiệu quả hơn bằng cách sử dụng các kỹ thuật bộ đệm tiêu chuẩn, hoặc
  • Dễ bảo trì hơn.

+1 cho cái này. Nó là hoàn toàn vô nghĩa. Hầu như trong mọi trường hợp hoàn toàn. Bộ nhớ đệm bằng một số khóa dựa trên hàm băm độc đáo là cách tốt hơn.
shabunc

1
Bạn không hoàn toàn đúng về bộ đệm của trình duyệt. Một làm mới cứng sẽ bằng cách vượt qua tất cả các kiểm tra bộ đệm của trình duyệt.
ajreal

1
Liên kết đến reinventing the wheel and not regretting itđã chết: '(
Esailija

4
Bộ nhớ đệm Bowser không đơn giản như bạn nghĩ, cũng không nhất quán trên tất cả các trình duyệt. Ví dụ: một số trình duyệt quyết định tải phông chữ web một cách ngẫu nhiên (bất kể tiêu đề - không thể tìm thấy bài viết về điều này ngay bây giờ nhưng tôi nghĩ rằng chính Dave Rupert đã phát hiện ra điều này). Ngoài ra, các ETAG buộc các trình duyệt kiểm tra xem tài nguyên đã được cập nhật chưa ... và đôi khi bạn không thể xóa ETAG (ví dụ: Amazon S3) - vì vậy nếu tệp CSS của bạn gửi tiêu đề ETAG, nó sẽ luôn được kiểm tra cập nhật (304s vẫn là một trọng tải). Để ngăn chặn các yêu cầu không cần thiết, bộ nhớ đệm tùy chỉnh được yêu cầu.
Ryan Wheale

7

Bộ nhớ đệm cục bộ phía máy khách nên được tối ưu hóa nhiều hơn so với sử dụng bộ nhớ cục bộ HTML5. Chỉ cần đảm bảo javascript và CSS của bạn nằm trong các tệp có thể lưu trong bộ nhớ cache bên ngoài và trang của bạn sẽ tải nhanh hơn nhiều qua bộ đệm của trình duyệt hơn là cố gắng trích xuất chúng từ bộ nhớ cục bộ và tự thực hiện chúng.

Ngoài ra, trình duyệt có thể bắt đầu tải tài nguyên bên ngoài khi trang bắt đầu tải, trước khi bạn thực sự có thể bắt đầu chạy javascript trong trang đó để lấy tài nguyên của mình từ bộ nhớ cục bộ HTML5.

Ngoài ra, dù sao bạn cũng cần mã trong trang để tải từ bộ nhớ cục bộ HTML5, vì vậy chỉ cần đặt tất cả mã JS của bạn vào một tệp JS có thể lưu trữ bên ngoài.



2

Bạn sẽ có hiệu suất tốt hơn nhiều bằng cách sử dụng mạng phân phối nội dung (CDN) như thư viện mã của Google . Được lên kế hoạch chu đáo, phần lớn JS và CSS của bạn phải có trong bộ nhớ cache của mọi khách truy cập trước khi họ truy cập trang web của bạn lần đầu tiên. Giảm thiểu phần còn lại.

Bạn luôn có thể điểm chuẩn bộ nhớ đệm trình duyệt so với giải pháp HTML5 cuộn bằng tay của bạn. Nhưng đặt cược của tôi là bộ nhớ đệm bản địa sẽ đánh bại nó.


2

Sử dụng localStorage rất nhanh (er)! Thử nghiệm của tôi cho thấy

  • Đang tải jQuery từ CDN: Chrome 268ms , FireFox: 200ms
  • Đang tải jQuery từ localStorage: Chrome 47ms , FireFox 14ms

Tôi đoán việc lưu yêu cầu HTTP đã mang lại lợi thế tốc độ lớn. Mọi người ở đây dường như bị kết án ngược lại, vì vậy hãy chứng minh tôi sai.

Nếu bạn muốn kiểm tra kết quả của tôi, tôi đã chọn một thư viện nhỏ lưu trữ các tập lệnh trong localStorage. Hãy xem thử trên Github https://github.com/webpgr/cached-webpgr.js hoặc chỉ sao chép nó từ ví dụ bên dưới.

Thư viện hoàn chỉnh:

function _cacheScript(c,d,e){var a=new XMLHttpRequest;a.onreadystatechange=function(){4==a.readyState&&(200==a.status?localStorage.setItem(c,JSON.stringify({content:a.responseText,version:d})):console.warn("error loading "+e))};a.open("GET",e,!0);a.send()}function _loadScript(c,d,e,a){var b=document.createElement("script");b.readyState?b.onreadystatechange=function(){if("loaded"==b.readyState||"complete"==b.readyState)b.onreadystatechange=null,_cacheScript(d,e,c),a&&a()}:b.onload=function(){_cacheScript(d,e,c);a&&a()};b.setAttribute("src",c);document.getElementsByTagName("head")[0].appendChild(b)}function _injectScript(c,d,e,a){var b=document.createElement("script");b.type="text/javascript";c=JSON.parse(c);var f=document.createTextNode(c.content);b.appendChild(f);document.getElementsByTagName("head")[0].appendChild(b);c.version!=e&&localStorage.removeItem(d);a&&a()}function requireScript(c,d,e,a){var b=localStorage.getItem(c);null==b?_loadScript(e,c,d,a):_injectScript(b,c,d,a)};

Gọi thư viện

requireScript('jquery', '1.11.2', 'http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js', function(){
    requireScript('examplejs', '0.0.3', 'example.js');
});

3
Các biện pháp của bạn là không liên quan. (1) Nếu người dùng chưa quen với trang web, dù sao anh ta cũng không có jQuery trong bộ nhớ cục bộ. (2) Mặt khác, nếu người dùng đã truy cập trang web của bạn, anh ta có jQuery trong bộ đệm, điều đó có nghĩa là nó sẽ không được tải từ CDN. Điều này cũng dẫn đến điểm thứ ba: (3) lưu trữ cục bộ phù hợp với một trang web nhất định, trong khi jQuery trên CDN của Google được chia sẻ bởi nhiều trang web, điều đó có nghĩa là người dùng đã truy cập, giả sử, Stack Overflow nhưng mới đối với trang web của bạn đã giành chiến thắng Không cần tải lại jQuery từ CDN nếu bạn sử dụng cùng một phiên bản jQuery.
Arseni Mourzenko

@MainMa Có thể biện pháp này không tốt, tôi thấy bây giờ, nhưng để bộ đệm của trình duyệt hoạt động, cần phải có một yêu cầu gửi đến một máy chủ để trả về 304. Yêu cầu này mất nhiều thời gian hơn là trực tiếp nhận tệp từ bộ lưu trữ cục bộ . Sửa lỗi cho tôi nếu tôi sai.
chọn

@MainMa vui lòng kiểm tra ý kiến ​​từ các lập trình viên.stackexchange.com/a/105526/195684 có nhiều vấn đề hơn với bộ đệm, như so sánh ETAG giúp bộ đệm ẩn tùy chỉnh này nhanh hơn
chọn
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.