Подтвердить что ты не робот

Сжатие большой строки в рубине

У меня есть веб-приложение (ruby on rails), которое отправляет некоторый YAML в качестве значения скрытого поля ввода.

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

4b9b3361

Ответ 1

Вы можете использовать реализацию zlib в рубиновом ядре для данных in/de-flate:

require "zlib"
data = "some long yaml string" * 100
compressed_data = Zlib::Deflate.deflate(data)
#=> "x\x9C+\xCE\xCFMU\xC8\xC9\xCFKW\xA8L\xCC\xCDQ(.)\xCA\xCCK/\x1E\x15\x1C\x15\x1C\x15\x1C\x15\x1C\x15\x1C\x15\x1C\x15\x1C\x15D\x15\x04\x00\xB3G%\xA6"

Вы должны base64-кодировать сжатые данные, чтобы сделать его пригодным для печати:

require 'base64'
encoded_data = Base64.encode64 compressed_data
#=> "eJwrzs9NVcjJz0tXqEzMzVEoLinKzEsvHhUcFRwVHBUcFRwVHBUcFUQVBACz\nRyWm\n"

Позже, на стороне клиента, вы можете использовать pako (порт zlib для javascript), чтобы вернуть ваши данные. Этот ответ, вероятно, поможет вам в реализации части JS.

Чтобы дать вам представление о том, насколько это эффективно, вот размеры строк примера:

data.size            # 2100
compressed_data.size #   48
encoded_data.size    #   66

То же самое происходит наоборот при сжатии на клиенте и раздувании на сервере.

Zlib::Inflate.inflate(Base64.decode64(encoded_data))
#=> "some long yaml stringsome long yaml str ... (shortened, as the string is long :)

Отказ от ответственности:

  • Реализация ruby ​​zlib должна быть совместима с реализацией pako. Но я не пробовал.
  • Цифры о размерах строк немного обмануты. Zlib действительно эффективен здесь, потому что строка повторяет много. Данные реальной жизни обычно не повторяются.