EN
JavaScript - own schema based JSON decompression algorithm
10 points
In this short article, we would like to show how in JavaScript, write a simple JSON decompression algorithm based on custom JSON schema.
This article presents an experimental concept.
Motivation:
by splitting JSON into schema and data parts we are able to reduce the amount of data needed to transfer from the server always on request.The schema should be sent once or embedded into the site code.
Compression effectiveness is visible here:
xxxxxxxxxx
1
// Compressed (66 characters):
2
3
["John",26,2,"Course","Classes","UK","London","000 000",null,null]
4
5
6
// Normal JSON (213 characters):
7
8
{"name":"John","age":26,"tasks":["Course","Classes"],"address":{"country":"UK","city":"London","postcode":"000 000","street":null,"number":null}}
9
10
11
// 100% * (66 / 213) = 30.98% of original size after compression
xxxxxxxxxx
1
// Hint: data can be transmitted as a simple string too (44 characters)
2
// e.g.
3
4
John,26,2,Course,Classes,UK,London,000 000,,
5
6
// Where:
7
// - coma separates values,
8
// - empty value between comas can be treat as null or empty string
9
// - escaped coma should be treat as string character,
10
// - value types are stored in schema - easy to detect type during decompression
11
12
13
// 100% * (44 / 213) = 20.66% of original size after compression
Practical example:
xxxxxxxxxx
1
const decompressValue = (schema, provider) => {
2
if (schema.type === 'object') {
3
return decompressObject(schema.properties, provider);
4
}
5
if (schema.type === 'array') {
6
return decompressArray(schema.item, provider);
7
}
8
return provider.get() ?? null;
9
};
10
11
const decompressObject = (schema, provider) => {
12
const data = {};
13
for (const entry of schema) {
14
data[entry.name] = decompressValue(entry, provider);
15
}
16
return data;
17
};
18
19
const decompressArray = (schema, provider) => {
20
const data = [];
21
const length = provider.get() ?? 0;
22
for (let i = 0; i < length; ++i) {
23
data.push(decompressValue(schema, provider));
24
}
25
return data;
26
};
27
28
const decompressData = (schema, data) => {
29
let index = -1;
30
const provider = {
31
get: () => data[++index]
32
};
33
return decompressValue(schema, provider);
34
};
35
36
37
// Usage example:
38
39
const schema = {
40
type: 'object',
41
properties: [
42
{name: 'name', type: 'string'},
43
{name: 'age', type: 'number'},
44
{
45
name: 'tasks',
46
type: 'array',
47
item: {
48
type: 'string'
49
}
50
},
51
{
52
name: 'address',
53
type: 'object',
54
properties: [
55
{name: 'country', type: 'string'},
56
{name: 'city', type: 'string'},
57
{name: 'postcode', type: 'string'},
58
{name: 'street', type: 'string'},
59
{name: 'number', type: 'string'}
60
]
61
}
62
]
63
};
64
65
// Input contains values according to schema order:
66
// - name: John
67
// - age: 26
68
// - 2 tasks: Course, Classes
69
// - country: UK
70
// - city: London
71
// - postcode: 000 000
72
// - street: null
73
// - number: null
74
//
75
const input = ['John', 26, 2, 'Course', 'Classes', 'UK', 'London', '000 000', null, null];
76
77
// Output contains decompressed object constructed using schema and input.
78
//
79
const output = decompressData(schema, input);
80
81
console.log(JSON.stringify(output, null, 4));