Как вы кешируете JavaScript на iphone Safari, используя html5 localStorage? - PullRequest
7 голосов
/ 24 февраля 2011

Я создаю мобильный веб-сайт, который использует основную библиотеку jquery и несколько собственных js. Наш веб-сайт слишком большой и содержит слишком много данных, чтобы быть простым оффлайн / онлайн-приложением. Нам нужно подключение к сети.

Я пытаюсь улучшить производительность кэширования для кэширования большого количества javascript для мобильного сайта. Общеизвестно, что кэширование в сафари iPhone ограничено файлами размером 15-25 КБ, а минимальный размер js составляет около 125 КБ.

Я думал об использовании манифеста кеша, но у него есть недостаток: браузер запрашивает манифест кеша при каждой загрузке страницы, и, поскольку мы не используем одностраничное веб-приложение, это добавляет дополнительные запросы к сервер.

Можем ли мы кэшировать javascript в localStorage (доступно в мобильном сафари и в браузере Android), а затем выполнить его оттуда?

Ответы [ 3 ]

18 голосов
/ 24 февраля 2011

Да, вы можете.(извините за ответ на мой собственный вопрос, я подумал, что это интересное решение)

Я нашел набросок примера кода здесь на слайде № 12.

http://www.slideshare.net/jedisct1/abusing-javascript-to-speedup-mobile-web-sites

Я реализовал это на http://m.bbref.com/ (все еще в бета-версии)

Вы должны использовать управление версиями скрипта, чтобы очистить кеш при создании новой версии, но это работает для страниц с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>

и в нижнем колонтитуле (по соображениям производительности). Я помещаю стандартный метод загрузки. Обратите внимание, что браузеры, использующие эту ветвь, все кешируют правильно, если у вас установлен заголовок expires.

<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.

2 голосов
/ 11 апреля 2013

Кроме того, я также натолкнулся на загрузчик скриптов с именем basket.js , он может делать именно то, что вам нужно.

0 голосов
/ 08 марта 2015

У меня был похожий вопрос, и я создал для этого небольшую библиотеку.Вы можете найти его в https://github.com/webpgr/cached-webpgr.js

Я создал его, так как basket.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');
});
...