czy realistyczne jest wykorzystanie lokalnej pamięci HTML5 do przechowywania CSS i JavaScript

22

Pomysł polega na wykorzystaniu lokalnej pamięci HTML5 do przechowywania często używanych CSS i JavaScript.

Na przykład (pseudo-kod):

var load_from_cdn = true;
if (wykryj pamięć lokalną)  
{
  if (pamięć podręczna css, znaleziono js)
  {
     załaduj lokalną pamięć podręczną
     load_from_cdn = false;
  }
}
if (load_from_cdn)
{
   document.write ('<script> ...');
}

Czy to możliwe, czy realistyczne?

Mam świadomość pamięć podręczną przeglądarki, nie będzie jeszcze jakiś nagłówek kontrola dostępu,
ja zakładając brak dostępu HTTP jest lepiej (w moim myśleniu )

PS: Wydaje się, że pamięć lokalna obsługuje tylko parę klucz-wartość , czy ktoś może to udowodnić?
(najlepiej z kilkoma przykładami)

ajreal
źródło
1
Wikipedia najwyraźniej spróbowała tego z wielkim skutkiem: twitter.com/catrope/status/408018210529615872 twitter.com/catrope/status/408018210529615872/photo/1
Dave
1
to mój pomysł 2 lata temu ... :)
ajreal
Twoje pytanie było pierwszą rzeczą, którą znalazłem, kiedy go o to napisałem. Dyskutowano tutaj o tym, czy to był dobry pomysł, czy nie, więc pomyślałem, że przedstawię jakieś niepotwierdzone dowody na korzyść!
Dave
1
To zdjęcie jest mylące. Jeśli przewiniesz w dół, zobaczysz, że ogromny spadek nie był w rzeczywistości, ponieważ pamięć lokalna była lepsza niż buforowanie, ale raczej błąd w konfiguracji buforowania: „ Okazało się mniej spektakularne :(. Wykres pokazuje ruch wewnętrzny, spadek z powodu do localStorage ukrywa błąd buforowania "- twitter.com/catrope/status/408110382599782400
Jamie Barker

Odpowiedzi:

11

Używanie pamięci lokalnej do przechowywania JS i CSS jest całkowicie w porządku. Jednak pamięć lokalna ma ograniczenie 5 MB na domenę. Być może będziesz musiał ponownie rozważyć tę strategię.

W przypadku komputerów stacjonarnych możesz wykorzystać domyślną pamięć podręczną przeglądarki, aby załatwić sprawę. Wystarczy ustawić odpowiedź HTTP JS i CSS na buforowalną. To jest proste i łatwe.

W przypadku sieci mobilnej opóźnienie jest wysokie. Zatem ograniczenie żądań HTTP ma kluczowe znaczenie. Zatem posiadanie JS i CSS w zewnętrznych adresach URL jest optymalne. O wiele lepiej byłoby mieć wbudowane JS i CSS. Zmniejszyło to liczbę żądań HTTP, ale zwiększyła zawartość HTML. Co wtedy? Tak jak powiedziałeś, używaj lokalnego magazynu!

Gdy jedna przeglądarka odwiedza witrynę po raz pierwszy, JS i CSS są wstawiane. JS ma również dwa dodatkowe zadania: 1) Przechowuj JS i CSS w pamięci lokalnej; 2) Ustaw plik cookie, aby oznaczyć, że JS i CSS są w lokalnej pamięci.

Gdy przeglądarka uzyskuje dostęp do witryny po raz drugi, serwer otrzymał plik cookie i wie, że przeglądarka ma już powiązane JS i CSS. Tak więc renderowany HTML ma wbudowany JS do odczytu JS i CSS z lokalnego magazynu i wstawiania do drzewa DOM.

To podstawowy pomysł na tworzenie wersji mobilnej bing.com. Konieczne może być uwzględnienie kontroli wersji JS i CSS podczas wdrażania jej w środowisku produkcyjnym.

Dzięki

Morgan Cheng
źródło
Tak, całkiem blisko tego, o czym myślę.
ajreal
Google opracował moduł Page Speed ​​Mod, który robi to samo. Oto strona, na której rozmawiają o towarach, wadach i
dontknows
pozytywnie oceniany, ale w tym przypadku wtf oznacza „inline”. „inline” ma 5 różnych znaczeń.
Alexander Mills,
1
W rzeczywistości został zwiększony do 10 MB na komputer i 5 MB na telefon
Roko C. Buljan
1
Ci nie potrzeba żadnego ciasteczko. możesz po prostu przeczytać, czy lokalny magazyn ma szukany klucz / wartość, a także musisz podać wersję (dla oczywistych celów unieważnienia). Ta sztuczka jest dobra dopiero po drugim wejściu na stronę, a także, jeśli zasoby nie są w pamięci podręcznej (z jakiegoś powodu)
vsync
33

Czy przeglądarka już tego nie robi dla ciebie i prawdopodobnie lepiej?

Bryan Boettcher
źródło
2
można mieć nadzieję
Alexander Mills
23

Jaki jest sens?

Istnieje już dobrze znana technika zwana buforowaniem po stronie klienta. Co przynosi lokalna pamięć HTML5 w tym przypadku, czego brakuje buforowania?

Możesz mieć jakąś dziwną aplikację, która musi dynamicznie ładować fragmenty kodu JavaScript, aby nie można było skutecznie korzystać z pamięci podręcznej, ale jest to niezwykle rzadki przypadek.

Pamiętaj też o innej rzeczy. Przeglądarki mają określone zasady dotyczące pamięci podręcznej, a większość przeglądarek dobrze radzi sobie z pamięcią podręczną (usuwając tylko starszą zawartość itp.). Wdrożenie domowej pamięci podręcznej uniemożliwia prawidłowe zarządzanie przeglądarkami. Nie tylko można go skrytykować samodzielnie, ale zaszkodzi ci też prędzej czy później. Przykład: gdy użytkownicy aplikacji sieciowej zgłaszają błędy, często odpowiadasz, prosząc ich o wyczyszczenie pamięci podręcznej. Nie jestem pewien, o co poprosisz w swoim przypadku, ponieważ wyczyszczenie pamięci podręcznej nigdy nie rozwiąże problemów z aplikacją internetową.


W odpowiedzi na twoją pierwszą edycję (druga edycja jest nie na temat):

Mam świadomość pamięci podręcznej przeglądarki, nadal będzie sprawdzanie dostępu do nagłówka

Wygląda na to, że nie rozumiesz buforowania przeglądarki. Dlatego ważne jest, aby zrozumieć, jak to działa, zanim zaczniesz wdrażać własny mechanizm buforowania . Odkryj własne koło tylko wtedy, gdy zrozumiesz wystarczająco dużo istniejących kół i masz dobry powód, aby ich nie używać. Zobacz punkt 1 mojej odpowiedzi na pytanie „Ponowne wynalezienie koła i NIE żałowanie” .

Udostępniając niektóre dane przez HTTP, możesz podać kilka nagłówków związanych z pamięcią podręczną:

  • Last-Modified określa, kiedy treść została zmieniona,
  • Expiresokreśla, kiedy przeglądarka musi zapytać serwer, czy treść uległa zmianie .

Te dwa nagłówki umożliwiają przeglądarce:

  • Unikaj pobierania zawartości raz po raz. Jeśli Last-Modifiedustawiono na ostatni miesiąc, a treść została już dzisiaj pobrana kilka godzin wcześniej, nie trzeba jej ponownie pobierać.
  • Unikaj zapytań o datę ostatniej modyfikacji pliku. Jeśli Expirespodmiotu cache jest 5 maja th , 2014, nie trzeba wydawać ani żadnego żądania GET w 2011, ani w 2012 lub 2013 roku, ponieważ wiesz, że pamięć podręczna jest up-to-date.

Drugi jest niezbędny w przypadku CDN. Gdy Google udostępnia JQuery odwiedzającemu Stack Overflow lub cdn.sstatic.netwyświetla obrazy lub arkusze stylów używane przez Stack Overflow, nie chcą, aby przeglądarki za każdym razem pytały o nową wersję. Zamiast tego serwują te pliki raz, ustawiają datę ważności na wystarczająco długo i to wszystko.

Oto na przykład zrzut ekranu z tego, co się dzieje, gdy wchodzę na stronę główną Stack Overflow:

Zrzut ekranu osi czasu przepełnienia stosu w Chrome pokazuje 15 plików, 3 są żądane, 12 jest obsługiwanych bezpośrednio z pamięci podręcznej bez żadnych żądań do zdalnych serwerów

Do obsłużenia jest 15 plików. Ale gdzie są te wszystkie 304 Not Modifiedodpowiedzi? Masz tylko trzy żądania treści, które uległy zmianie. W pozostałych przypadkach przeglądarka korzysta z wersji buforowanej bez wysyłania żadnych żądań do dowolnego serwera .


Podsumowując, naprawdę musisz przemyśleć dwa razy przed wdrożeniem własnego mechanizmu pamięci podręcznej, a zwłaszcza znaleźć dobry scenariusz, w którym może to być przydatne . Jak powiedziałem na początku mojej odpowiedzi, mogę znaleźć tylko jedno: gdzie służysz kawałki JavaScript aby użyć ich przez, OMG, eval(). Ale w tym przypadku jestem prawie pewien, że istnieją lepsze podejścia, które są albo:

  • Bardziej efektywne przy użyciu standardowych technik pamięci podręcznej lub
  • Łatwiejsze w utrzymaniu.
Arseni Mourzenko
źródło
+1 dla tego. To jest absolutnie bezcelowe. Niemal we wszystkich przypadkach absolutnie. Buforowanie przy użyciu unikatowego klucza opartego na haszowaniu jest znacznie lepsze.
shabunc
1
Nie masz całkowitej racji co do pamięci podręcznej przeglądarki. Twarde odświeżanie zakończy wszystkie sprawdzanie pamięci podręcznej przeglądarki.
ajreal
1
Link do strony reinventing the wheel and not regretting itjest martwy: '(
Esailija
4
Buforowanie Bowsera nie jest tak proste, jak mogłoby się wydawać, ani spójne we wszystkich przeglądarkach. Na przykład niektóre przeglądarki losowo decydują się na ładowanie czcionek internetowych (niezależnie od nagłówków - nie mogą teraz znaleźć artykułu na ten temat, ale myślę, że to Dave Rupert to odkrył). Ponadto ETAG zmusza przeglądarki do sprawdzenia, czy zasób został zaktualizowany ... a czasami nie można usunąć ETAG (np. Amazon S3) - więc jeśli plik CSS wysyła nagłówek ETAG, zawsze będzie sprawdzany pod kątem aktualizacji (304s nadal są ładunkiem). Aby zapobiec niepotrzebnym żądaniom, wymagane jest niestandardowe buforowanie.
Ryan Wheale
7

Lokalne buforowanie po stronie klienta powinno być znacznie bardziej zoptymalizowane niż korzystanie z lokalnej pamięci HTML5. Upewnij się tylko, że javascript i CSS znajdują się w zewnętrznych plikach, które można buforować, a strona powinna ładować się znacznie szybciej za pomocą pamięci podręcznej przeglądarki, niż próbować wyodrębnić je z pamięci lokalnej i wykonać je samodzielnie.

Poza tym przeglądarka może rozpocząć ładowanie zasobów zewnętrznych, gdy strona zacznie się ładować, zanim będzie można uruchomić skrypt javascript na tej stronie, aby następnie pobrać zasoby z lokalnego magazynu HTML5.

Dodatkowo potrzebujesz kodu na stronie, aby załadować z lokalnego magazynu HTML5, więc po prostu umieść wszystkie swoje JS w jednym zewnętrznym, możliwym do buforowania pliku JS.

jfriend00
źródło
2

Osiągniesz znacznie lepszą wydajność dzięki sieci dostarczania treści (CDN), takiej jak biblioteka kodów Google . Zaplanowane z rozwagą, większość twoich JS i CSS powinna znajdować się w pamięci podręcznej każdego użytkownika, zanim trafią na twoją stronę po raz pierwszy. Zminimalizuj resztę.

Zawsze możesz porównywać buforowanie przeglądarki z ręcznie opracowanym rozwiązaniem HTML5. Ale założę się, że natywna pamięć podręczna pobije go od spodni.

Cczona
źródło
2

Korzystanie z localStorage jest szybkie (er)! Mój test pokazał

  • Ładowanie jQuery z CDN: Chrome 268ms , FireFox: 200ms
  • Ładowanie jQuery z localStorage: Chrome 47ms , FireFox 14ms

Wydaje mi się, że zapisanie żądania HTTP już zapewnia dużą przewagę prędkości. Wydaje się, że wszyscy tutaj są przekonani o czymś przeciwnym, więc proszę udowodnij, że się mylę.

Jeśli chcesz przetestować moje wyniki, stworzyłem małą bibliotekę, która buforuje skrypty w localStorage. Sprawdź to na Github https://github.com/webpgr/cached-webpgr.js lub po prostu skopiuj z poniższego przykładu.

Pełna biblioteka:

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)};

Dzwonię do biblioteki

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');
});
Wybierz
źródło
3
Twoje środki są nieistotne. (1) Jeśli użytkownik jest nowy na stronie, i tak nie ma jQuery w lokalnej pamięci. (2) Jeśli z drugiej strony użytkownik już odwiedził twoją stronę, ma jQuery w pamięci podręcznej, co oznacza, że ​​nie zostanie załadowana z CDN. Prowadzi to również do trzeciego punktu: (3) lokalne przechowywanie jest właściwe dla danej witryny, podczas gdy jQuery w sieci CDN Google jest współużytkowany przez wiele witryn, co oznacza, że ​​użytkownik, który odwiedził, powiedzmy, Stack Overflow, ale jest nowy w Twojej witrynie, wygrał nie musisz ponownie ładować jQuery z CDN, jeśli używasz tej samej wersji jQuery.
Arseni Mourzenko
@MainMa Może ten środek nie jest dobry, widzę to teraz, ale aby pamięć podręczna przeglądarki działała, musi zostać wysłane żądanie do serwera, który następnie zwraca 304. Żądanie to zajmuje więcej czasu niż bezpośrednie pobranie pliku z pamięci lokalnej . Popraw mnie, jeśli się mylę.
wybierz
@MainMa sprawdź również komentarze programistów.stackexchange.com/a/ 105526/195684 jest więcej problemów z pamięcią podręczną, takich jak porównanie ETAG, które przyspieszają to niestandardowe buforowanie
wybierz