[JavaScript, Node.JS, TypeScript] Оптимизация трафика при синхронизация состояний через Jsonpatch
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
Задача синхронизации состояния между клиентом и сервером может быть решена разными способами, я хотел бы расказать про вариант с использованием спецификации JSON Patch, а также про спецификацию MessagePack и способ оптимизации размера пакета через библиотеку PatchPack.
Принцип синхронизации заключается в следующем: все состояние передается только один раз, последующие изменения состояний передаются списком операций. Каждая операция определяет конкретный тип изменения. Примерами таких изменений являются добавление элемента массива или замена значения свойства.
Jsonpatch
Например, следующие документы JSON представляют состояние, документ исправления JSON для ресурса и результат применения операций исправления.
Пример состояния
{
"users": {
"1": { "name": "Foo" },
"2": { "name": "Baz", "info": "FooBaz" },
},
"objects": [
{ "id": 1, "name": "Foo" },
{ "id": 2, "name": "Foo", "foo:" "Baz" },
],
"foo": { "baz": false }
}
Пример JSON Patch
[
{
"op": "add",
"path": "/users/3",
"value": {
"name": "FooBaz",
"info": "test"
}
}
]
В приведенном выше документе JSON:
- свойство op указывает тип операции;
- свойство path указывает обновляемый элемент;
- свойство value предоставляет новое значение.
Состояние после обновления
Ниже показан ресурс в том состоянии, которое он принимает после применения приведенного выше документа JSON Patch.
{
"users": {
"1": { "name": "Foo" },
"2": { "name": "Baz", "info": "FooBaz" },
"3": { "name": "FooBaz", "info": "test" },
},
"objects": [
{ "id": 1, "name": "Foo" },
{ "id": 2, "name": "Foo", "foo:" "Baz" },
],
"foo": { "baz": false }
}
Операции
В следующей таблице перечислены поддерживаемые операции, которые определены в спецификации JSON Patch.
Операция
Примечания
add
Добавляет свойство или элемент массива. Для существующего свойства устанавливает значение.
remove
Удаляет свойство или элемент массива.
replace
Действует так же, как remove с последующим add в том же расположении.
move
Действует так же, как remove из источника с последующим add, в котором указаны место назначения и значение из источника.
copy
Действует так же, как add, в котором указаны место назначения и значение из источника.
test
Возвращает успешный код состояния, если значение path совпадает с предоставленным value.
Json patch может быть реализован через метод HTTP-запрос PATCH или через сообщения websocket. Гибкость и понятность содержания каждого изменения сильно увеличивают размер этого изменения.
MessagePack
Есть разные способы для оптимизации Json состояния и изменения (JsonPatch) в частности. Один из таких способов — использование спецификации сериализации MessagePack.
Про MessagePack уже были статьи на хабре, поэтому я попробую рассказать преимущества и недостатки этой спецификации для синхронизации состояния.
MessagePack более компактен (чем JSON), существует реализация на многих языках программирования и не используют какие-либо внешние зависимости.
Однако, когда состояние имеет структуру, то MessagePack недостаточно компактный, т.к. нет никакой оптимизации для повторяющихся свойств в состоянии состояния.
Patchpack
Библиотеку PatchPack разработана на основе спецификации MessaagePack, но она сериализует состояние и изменения на много эффективнее. Это достигается путем формировании схемы состояния при сериализации и использования этой схемы для десериализации. Этот подход накладывает дополнительную сложность связанную с синхронизацией схемы.
В библиотеке PatchPack схема/изменение передаются вместе с сериализованным состоянием/изменением:
Вот небольшой пример использования библиотеки:
import { PatchPack } from "patchpack"
// первоначальное состояние
const state = {
users: {
"1": { name: "Foo" },
"2": { name: "Baz", info: "FooBaz" },
},
objects: [
{ id: 1, name: "Foo" },
{ id: 2, name: "Foo", foo: "Baz" },
],
foo: { baz: false }
}
// Создаем объект PatchPack и указываем типы, используемые в состоянии
const ppServer = new PatchPack({
State: ["users", "objects", "foo"],
User: ["name", "info"],
Object: ["id", "name", "foo"],
Foo: ["baz"]
})
// сериализуем состояние
const encodedState = ppServer.encodeState(state, false)
Сериализованное состояние отправляем на клиент, создаем объект PatchPack с аналогичными типами и выполняем метода decodeState.
Для сериализации изменений (JsonPatch) используется отдельный метод:
// добавляем пользователя в коллекцию
const patch1 = { op: "add", path: "/users/3", value: { name: "FooBaz", info: "test" } }
const encodedPatch1 = ppServer.encodePatch(patch1)
// изменяем свойство
const patch2 = { op: "replace", path: "/foo/baz", value: true }
const encodedPatch2 = ppServer.encodePatch(patch2)
Сериализованные изменения отправляем на клиент и при помощи метода decodePatch преобразуются в формат JsonPatch.
Сравнение размера после сериализации через PatchPach, MessagePack и JSON.stringify (в байтах):
patchpack
messagePack
JSON.stringify
state
60
107 (+78%)
165 (+175%)
patch1
22
53 (+140%)
72 (+227%)
patch2
5
33 (+560%)
47 (+840%)
В настоящий момент поддерживается не вся спецификация JsonPatch, а только базовые операции: add, replace, remove (copy, move, test — не поддерживаются).
В отличии от MessagePack библиотека PatchPack пока реализована только на JavaScript/Typescript, но в ближайшее время добавиться реализацию на dart и C#.
Спасибо, что прочитали, любая критика и предложения приветствуются!
===========
Источник:
habr.com
===========
Похожие новости:
- [Разработка веб-сайтов, JavaScript, Программирование] Сниппет, расширение для VSCode и CLI. Часть 2
- [JavaScript, Интерфейсы, ReactJS, TypeScript] Использование Effector в стеке React + TypeScript
- [JavaScript, Реверс-инжиниринг, Софт] Frida изучаем эксплуатацию алгоритмов Heap
- [JavaScript, Node.JS] Разработка сервера для многопользовательской игры с помощью nodejs и magx
- [JavaScript, Программирование, Node.JS] Декораторы в JavaScript с нуля (перевод)
- [JavaScript, Программирование, ReactJS] Начинающим React-разработчикам: приложение со списком дел (покупок) (перевод)
- [JavaScript, Node.JS] Отправка ответа с Коа (перевод)
- [Разработка веб-сайтов, JavaScript, Программирование] Сниппет, расширение для VSCode и CLI. Часть 1
- [Разработка веб-сайтов, JavaScript, Accessibility] Безжалостное избавление от Layout Shift на netlify.com (перевод)
- [Разработка веб-сайтов, Программирование, TypeScript] ТайпСкрип: Ох уж эта весёлая система типов
Теги для поиска: #_javascript, #_node.js, #_typescript, #_jsonpatch, #_serialization, #_messagepack, #_patchpack, #_javascript, #_node.js, #_typescript
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 12:50
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
Задача синхронизации состояния между клиентом и сервером может быть решена разными способами, я хотел бы расказать про вариант с использованием спецификации JSON Patch, а также про спецификацию MessagePack и способ оптимизации размера пакета через библиотеку PatchPack. Принцип синхронизации заключается в следующем: все состояние передается только один раз, последующие изменения состояний передаются списком операций. Каждая операция определяет конкретный тип изменения. Примерами таких изменений являются добавление элемента массива или замена значения свойства. Jsonpatch Например, следующие документы JSON представляют состояние, документ исправления JSON для ресурса и результат применения операций исправления. Пример состояния {
"users": { "1": { "name": "Foo" }, "2": { "name": "Baz", "info": "FooBaz" }, }, "objects": [ { "id": 1, "name": "Foo" }, { "id": 2, "name": "Foo", "foo:" "Baz" }, ], "foo": { "baz": false } } Пример JSON Patch [
{ "op": "add", "path": "/users/3", "value": { "name": "FooBaz", "info": "test" } } ] В приведенном выше документе JSON:
Состояние после обновления Ниже показан ресурс в том состоянии, которое он принимает после применения приведенного выше документа JSON Patch. {
"users": { "1": { "name": "Foo" }, "2": { "name": "Baz", "info": "FooBaz" }, "3": { "name": "FooBaz", "info": "test" }, }, "objects": [ { "id": 1, "name": "Foo" }, { "id": 2, "name": "Foo", "foo:" "Baz" }, ], "foo": { "baz": false } } Операции В следующей таблице перечислены поддерживаемые операции, которые определены в спецификации JSON Patch. Операция Примечания add Добавляет свойство или элемент массива. Для существующего свойства устанавливает значение. remove Удаляет свойство или элемент массива. replace Действует так же, как remove с последующим add в том же расположении. move Действует так же, как remove из источника с последующим add, в котором указаны место назначения и значение из источника. copy Действует так же, как add, в котором указаны место назначения и значение из источника. test Возвращает успешный код состояния, если значение path совпадает с предоставленным value. Json patch может быть реализован через метод HTTP-запрос PATCH или через сообщения websocket. Гибкость и понятность содержания каждого изменения сильно увеличивают размер этого изменения. MessagePack Есть разные способы для оптимизации Json состояния и изменения (JsonPatch) в частности. Один из таких способов — использование спецификации сериализации MessagePack. Про MessagePack уже были статьи на хабре, поэтому я попробую рассказать преимущества и недостатки этой спецификации для синхронизации состояния. MessagePack более компактен (чем JSON), существует реализация на многих языках программирования и не используют какие-либо внешние зависимости. Однако, когда состояние имеет структуру, то MessagePack недостаточно компактный, т.к. нет никакой оптимизации для повторяющихся свойств в состоянии состояния. Patchpack Библиотеку PatchPack разработана на основе спецификации MessaagePack, но она сериализует состояние и изменения на много эффективнее. Это достигается путем формировании схемы состояния при сериализации и использования этой схемы для десериализации. Этот подход накладывает дополнительную сложность связанную с синхронизацией схемы. В библиотеке PatchPack схема/изменение передаются вместе с сериализованным состоянием/изменением: Вот небольшой пример использования библиотеки: import { PatchPack } from "patchpack"
// первоначальное состояние const state = { users: { "1": { name: "Foo" }, "2": { name: "Baz", info: "FooBaz" }, }, objects: [ { id: 1, name: "Foo" }, { id: 2, name: "Foo", foo: "Baz" }, ], foo: { baz: false } } // Создаем объект PatchPack и указываем типы, используемые в состоянии const ppServer = new PatchPack({ State: ["users", "objects", "foo"], User: ["name", "info"], Object: ["id", "name", "foo"], Foo: ["baz"] }) // сериализуем состояние const encodedState = ppServer.encodeState(state, false) Сериализованное состояние отправляем на клиент, создаем объект PatchPack с аналогичными типами и выполняем метода decodeState. Для сериализации изменений (JsonPatch) используется отдельный метод: // добавляем пользователя в коллекцию
const patch1 = { op: "add", path: "/users/3", value: { name: "FooBaz", info: "test" } } const encodedPatch1 = ppServer.encodePatch(patch1) // изменяем свойство const patch2 = { op: "replace", path: "/foo/baz", value: true } const encodedPatch2 = ppServer.encodePatch(patch2) Сериализованные изменения отправляем на клиент и при помощи метода decodePatch преобразуются в формат JsonPatch. Сравнение размера после сериализации через PatchPach, MessagePack и JSON.stringify (в байтах): patchpack messagePack JSON.stringify state 60 107 (+78%) 165 (+175%) patch1 22 53 (+140%) 72 (+227%) patch2 5 33 (+560%) 47 (+840%) В настоящий момент поддерживается не вся спецификация JsonPatch, а только базовые операции: add, replace, remove (copy, move, test — не поддерживаются). В отличии от MessagePack библиотека PatchPack пока реализована только на JavaScript/Typescript, но в ближайшее время добавиться реализацию на dart и C#. Спасибо, что прочитали, любая критика и предложения приветствуются! =========== Источник: habr.com =========== Похожие новости:
|
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 12:50
Часовой пояс: UTC + 5