сжатие строки javascript с помощью localStorage

Я использую localStorage в проекте, и ему потребуется хранить много данных, в основном типа int, bool и string. Я знаю, что строки javascript являются юникодом, но при хранении в localStorage остаются ли они в юникоде? Если да, то есть ли способ сжать строку, чтобы использовать все данные в байте Unicode, или я должен просто использовать base64 и иметь меньшее сжатие? Все данные будут храниться в виде одной большой строки.

РЕДАКТИРОВАТЬ: Теперь, когда я думаю об этом, base64 вообще не будет сильно сжимать, данные уже находятся в базе 64, a-zA-Z0-9 ;: составляет 65 символов.


person invisible bob    schedule 28.07.2011    source источник
comment
Я не думаю, что это в рекомендации. Я думаю, каждая реализация может отличаться.   -  person KARASZI István    schedule 29.07.2011
comment
что localStorage находится в юникоде? или что javascript есть? Я совершенно уверен, что строки javascript являются Unicode, но я не знаю, являются ли строки localstorage   -  person invisible bob    schedule 29.07.2011
comment
Я думаю, что все, что вы храните в localStorage, должно быть возвращено в том виде, в котором вы это хранили. Но, как никто не знает, я все время использую кодировку base64.   -  person KARASZI István    schedule 29.07.2011
comment
Я тестировал локальное хранилище со строкой, содержащей , unicode hiragana A, и оно не сохраняет значение (в google chrome). если это не юникод, что бы это было? ascii? латинский-что-то?   -  person invisible bob    schedule 29.07.2011
comment
Мне интересно узнать, есть ли какой-либо алгоритм сжатия Javascript, который можно использовать с localStorage. Я ищу что-то быстрое, что может дать некоторое сжатие данных, в основном текстовых.   -  person HoLyVieR    schedule 12.09.2011
comment
localStorage хранится как JSON со строковыми данными, закодированными в base64 (в Opera, и было бы неудивительно, если бы другие браузеры следовали тому же шаблону).   -  person c69    schedule 16.09.2011
comment
У вас есть только 5 МБ пространства в localStorage, и он не предназначен для больших объемов данных. Можете ли вы выгрузить часть этих данных на сервер и получить их с помощью AJAX? Или это должно быть полностью офлайн?   -  person beatgammit    schedule 18.09.2011
comment
Я пытаюсь сделать то же самое и удивляюсь, насколько это сложно.   -  person Nelson    schedule 29.05.2012


Ответы (5)


"при хранении в localStorage они остаются в кодировке Unicode?"

В рабочем проекте веб-хранилища значения локального хранилища определены как DOMString. DOMStrings определены как последовательности 16-битные блоки, использующие кодировку UTF-16. Так что да, они остаются Unicode.

есть ли способ сжать строку, чтобы использовать все данные в байте Unicode ... ?

Кодировка «Base32k» должна давать 15 бит на символ. Кодировка типа base32k использует все 16 битов в символах UTF-16, но теряет бит, чтобы избежать срабатывания символов двойного слова. Если ваши исходные данные закодированы в base64, они используют только 6 бит на символ. Кодирование этих 6 бит в base32k должно сжать его до 6/15 = 40% от исходного размера. См. http://lists.xml.org/archives/xml-dev/200307/msg00505.html и http://lists.xml.org/archives/xml-dev/200307/msg00507.html.

Для еще большего уменьшения размера вы можете декодировать свои строки base64 в их полный 8-битный двоичный файл, сжать их с помощью какого-либо известного алгоритма сжатия (например, см. javascript-реализация gzip), а затем base32k кодирует сжатый вывод.

person Oren Trutner    schedule 14.09.2011
comment
+1 за ссылку на все спецификации, на которые я собирался ссылаться, и за то, что пошел еще дальше. - person ellisbben; 18.09.2011
comment
но тогда почему あ не сохраняет (в google chrome, может быть, хром просто не так?)? Спасибо за base32k! - person invisible bob; 29.09.2011

Вы можете кодировать в Base64, а затем реализовать простой алгоритм сжатия без потерь, такой как кодирование длин серий или кодирование Голомба. Это не должно быть слишком сложно сделать, и это может вызвать у вас некоторое впечатление.

Кодировка Голомба

Я также нашел JsZip. Думаю, вы можете проверить код и использовать алгоритм только в том случае, если он совместим.

Надеюсь это поможет.

http://jszip.stuartk.co.uk/

person Laurent Zuijdwijk    schedule 12.09.2011
comment
Я пробовал несколько кодировок без потерь, но они часто используют символ UTF-16, который не работает с localStorage. И если вы кодируете содержимое base64, вы в конечном итоге получите содержимое больше, чем исходное, когда исходным содержимым является ASCII. Я проверю кодировку Голомба и JSZip, хотя я еще не экспериментировал с ними. Это может дать хороший результат. - person HoLyVieR; 13.09.2011
comment
Это еще один пост, который может вас заинтересовать. Не уверен, будет ли он соответствовать вашему варианту использования, но тем не менее интересно: sean. co.uk/a/webdesign/javascript_string_compression.shtm - person Laurent Zuijdwijk; 13.09.2011
comment
Я закончил пробовать кодировку Голомба, и пока она дает хороший результат с реальными данными (сжатие около 5%, и оно все еще читается). Учитывая скорость алгоритма, это лучшее, что я видел. - person HoLyVieR; 16.09.2011
comment
Base64 добавляет 30% к размеру вашей строки, уверены ли вы, что сжатие сможет это компенсировать? - person c69; 16.09.2011

Недавно мне пришлось сохранять огромные объекты JSON в localStorage.

Во-первых, да, они остаются в юникоде. Но не пытайтесь сохранить что-то вроде объекта прямо в локальное хранилище. Это должна быть строка.

Вот несколько методов сжатия, которые я использовал (которые, похоже, хорошо сработали в моем случае) перед преобразованием моего объекта в строку:

Любые числа можно преобразовать из базы 10 в базу 36, выполнив что-то вроде (+ num) .toString (36). Например, число 48346942 будет «ss8qm», что (включая кавычки) на 1 символ меньше. Возможно, добавление кавычек действительно увеличит количество символов. Таким образом, чем больше число, тем лучше выигрыш. Чтобы преобразовать его обратно, вы должны сделать что-то вроде parseInt ("ss8qm", 36).

Если вы сохраняете объект с любым ключом, который будет повторяться, лучше всего создать объект поиска, в котором вы назначите сокращенный ключ оригиналу. Итак, для примера, если у вас есть:

{
    name: 'Frank',
    age: 36,
    family: [{
        name: 'Luke',
        age: 14,
        relation: 'cousin'
    }, {
        name: 'Sarah',
        age: 22,
        relation: 'sister'
    }, {
        name: 'Trish',
        age: 31,
        relation: 'wife'
    }]
}

Тогда вы могли бы это сделать:

{
    // original w/ shortened keys
    o: {    
        n: 'Frank',
        a: 36,
        f: [{
            n: 'Luke',
            a: 14,
            r: 'cousin'
        }, {
            n: 'Sarah',
            a: 22,
            r: 'sister'
        }, {
            n: 'Trish',
            a: 31,
            r: 'wife'
        }]
    },

    // lookup
    l: {
        n: 'name',
        a: 'age',
        r: 'relation',
        f: 'family'
    }
}

Опять же, это окупается размером. И повторение. В моем случае это сработало очень хорошо. Но это зависит от предмета.

Все это требует функции сжатия и расширения обратно.

Кроме того, я бы рекомендовал создать класс, который используется для хранения и извлечения данных из локального хранилища. Я столкнулся с нехваткой места. Так что записи не удастся. Другие сайты также могут записывать данные в локальное хранилище, что может занять часть этого места. См. этот пост для более подробной информации.

То, что я сделал в созданном мной классе, было первой попыткой удалить любой элемент с заданным ключом. Затем попробуйте setItem. Эти две строки заключены в пробную ловушку. В случае сбоя предполагается, что хранилище заполнено. Затем он очистит все в localStorage, пытаясь освободить для него место. Затем, после очистки, он снова попытается установитьItem. Это тоже связано с попыткой улова. Поскольку он может потерпеть неудачу, если сама строка больше, чем может обработать localStorage.

РЕДАКТИРОВАТЬ: Кроме того, вы встретите сжатие LZW, о котором упоминают многие люди. Я реализовал это, и это сработало для небольших строк. Но с большими строками он начнет использовать недопустимые символы, что приведет к повреждению данных. Так что будьте осторожны, и если вы пойдете в этом направлении test test test

person Marshall    schedule 14.09.2011
comment
Я пришел к такому же выводу о сжатии LZW, он не работал с большой струной. Что касается класса хранения, то, что я обнаружил, также было полезно реализовать механизм истечения срока хранения для ключа, который вы храните, таким образом, старый ключ не остается навсегда. И подсказки с числами были действительно полезны, особенно если вы работаете с отметкой времени. - person HoLyVieR; 17.09.2011

В этом вопросе Stackoverflow есть ответ, который может помочь. Есть ссылка на библиотеку сжатия JavaScript.

person kzh    schedule 14.09.2011

Сжатие Base64 для javascript очень хорошо описано в этом блоге. Реализация также доступна здесь при использовании всего framework.

person J punto Marcos    schedule 11.06.2013