Сжатие строки javascript с помощью localStorage
Я использую localStorage
в проекте, и ему нужно будет хранить много данных, в основном типа int, bool и string. Я знаю, что строки javascript являются unicode, но когда они хранятся в localStorage
, они остаются в unicode? Если это так, есть ли способ сжать строку, чтобы использовать все данные в байтах юникода, или я должен просто использовать base64 и иметь меньше сжатия? Все данные будут сохранены в виде одной большой строки.
EDIT: теперь, когда я думаю об этом, base64 вообще не будет делать никакого сжатия, данные уже находятся в базе 64, a-zA-Z0-9 ;:
составляет 65 символов.
Ответы
Ответ 1
", если они хранятся в localStorage, они остаются в unicode?"
рабочий проект Web Storage определяет локальные значения хранилища как DOMString. DOMStrings определены как последовательности 16-битных единиц с помощью UTF- 16 ". Так что да, они остаются Юникодом.
есть способ, которым я мог бы сжать строку, чтобы использовать все данные в байтах юникода... ?
"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 кодирует сжатый вывод.
Ответ 2
Вы можете кодировать Base64, а затем реализовывать простой алгоритм сжатия без потерь, такой как кодирование по длине или кодирование Golomb. Это не должно быть слишком сложно сделать и может дать вам немного омрачения.
Кодировка Голомба
Я также нашел JsZip. Я думаю, вы можете проверить код и использовать его только в том случае, если он совместим.
Надеюсь, что это поможет.
http://jszip.stuartk.co.uk/
Ответ 3
Недавно мне пришлось сохранять огромные объекты 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. Эти две строки завернуты с помощью try catch. Если он терпит неудачу, он предполагает, что хранилище заполнено. Затем он очистит все в localStorage, пытаясь освободить место для этого. Затем, после ясной, попытается снова установить значение. Это тоже завернуто в попытку поймать. Так как это может привести к сбою, если сама строка больше, чем может обрабатывать localStorage.
EDIT: Кроме того, вы столкнетесь с компрессией LZW, о которой многие говорят. Я реализовал это, и он работал для небольших строк. Но с большими строками он начнет использовать недопустимые символы, которые приведут к повреждению данных. Так что будьте осторожны, и если вы пойдете в этом направлении, тестовый тестовый тест
Ответ 4
В этом вопросе о статических потоках есть ответ, который может помочь. Существует ссылка на библиотеку сжатия JavaScript.
Ответ 5
Сжатие Base64 для javascript очень хорошо объяснено в этом блоге. Реализация также доступна здесь при использовании целых framework.