Как кэшировать javascript на iPhone Safari с помощью HTML5 localStorage?
Я создаю мобильный веб-сайт, который использует основную библиотеку jquery и некоторые собственные js. Наш сайт слишком большой и имеет слишком много данных, чтобы быть простым офлайн/онлайн веб-приложением. Нам нужно подключение к интернету.
Я пытаюсь улучшить производительность кэширования для кэширования большого количества javascript для мобильного сайта. Хорошо известно, что кэширование на safari iPhone ограничено файлами размером 15-25kb, а наш minified js составляет около 125kb.
Я думал об использовании манифеста кэша, но это имеет тот недостаток, что браузер запрашивает манифест кэша при каждой загрузке страницы, и поскольку мы не используем одностраничное веб-приложение, это добавляет дополнительные запросы к серверу.
можем ли мы кэшировать javascript в localStorage (доступно в мобильном safari и в браузере android), а затем выполнить его оттуда?
3 ответов
Да, вы можете. (извините за ответ на мой собственный вопрос, я думал, что это интересное решение)
Я нашел контур примера кода здесь, на слайде #12.
http://www.slideshare.net/jedisct1/abusing-javascript-to-speedup-mobile-web-sites
я реализовал это на http://m.bbref.com/ (все еще в бета-версии)
вы должны использовать управление версиями url-адреса скрипта, чтобы очистить кэш, когда новая версия создано, но это работает для страниц с localStorage, а также будет работать, когда localStorage недоступен. Я добавил некоторый отладочный код в нижний колонтитул, чтобы показать вам, откуда загружается js.
Я разделил это на скрипт для верхнего и нижнего колонтитулов. Они выглядят встроенными.
в заголовке (я поместил его здесь, поскольку мы используем modernizr для добавления некоторых классов в HTML-тег, и я хочу, чтобы они были там как можно быстрее для рендеринга. Можно переместить в нижняя сноска.
<script type="text/javascript">
// .001 is the current js version
// this script assumes it is in the root web directory.
var js_file = "site_lib.001.js";
// vars to store where the file is loaded from.
var _mob_load_js = false;
var _mob_ajax_load_js = false;
{
// if we have localStorage and the files exists there get it.
if(window.localStorage && window.localStorage[js_file]) {
// eval the js file.
try{
window.eval(window.localStorage[js_file]);
// successfully eval'ed the code, so
// we don't need to download it later.
_mob_load_js = true;
} catch (e) { _mob_load_js = false; }
}
else if (window.localStorage) {
// We have localStorage, but no cached file, so we
// load the file via ajax, eval it and then store
// the file in localStorage
// To remove previous versions, I remove all of our localStorage,
// This is extreme if we store other vars there.
window.localStorage.clear();
// standard ajax request.
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
// eval the js
try {
window.eval(xhr.responseText);
// successfully eval'ed the code, so
// we don't need to download it later.
_mob_ajax_load_js = true;
} catch (e) { _mob_ajax_load_js = false; }
try {
// store the js.
window.localStorage[js_file] = xhr.responseText;
} catch (e) {}
}
else {
return;
}
};
xhr.open("GET",js_file,true);
xhr.send();
}
};
</script>
и в нижнем колонтитуле (по соображениям производительности). Я размещаю стандартный метод загрузки. Обратите внимание, что браузеры, которые используют эту ветку все кэш правильно, пока у вас есть истекает набор заголовков.
<div id="sr_external_script"></div>
<script type="text/javascript">
// We haven't loaded the js yet, so we create a script
// tag and get the script the old fashioned way
if (!_mob_load_js && !_mob_ajax_load_js) {
var script=document.createElement("script");
script.type="text/javascript";
script.src=js_file;
document.getElementById("sr_external_script").appendChild(script);
// add a note to the footer
document.write('<div>loaded from server and not stored</div>');
}
else if (!_mob_load_js) {
// add a note to the footer
document.write('<div>loaded via ajax and stored in localStorage</div>');
}
else {
// add a note to the footer
document.write('<div>loaded from localStorage</div>');
}
</script>
Я подтвердил в chrome и safari, что js загружается из localStorage, и функциональность сайта работает так, как ожидалось, и нет запроса на сервер. И я подтвердил, что при запуске в IE или firefox он загружает скрипт как нашел в футере.
Примечание: я добавил код, чтобы обернуть evals в try catch, так как у меня была проблема в firefox.
кроме того, я также наткнулся на этот загрузчик скрипт корзина.js он может делать именно то, что вы хотите.
у меня был аналогичный вопрос, а также создал небольшую библиотеку для этого. Вы можете найти его в https://github.com/webpgr/cached-webpgr.js
Я создал его с корзины.js имеет некоторую зависимость и предоставляет гораздо больше функций, которые мне нужны. Вы можете проверить мой код в Github, я уверен, что вы сможете понять все это довольно быстро. Но если вы просто хотите идти вперед и использовать его, вот полный пример того, как его использовать.
полный библиотека:
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)};
вызов библиотеки
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');
});