odoo/o-spreadsheet#7756
Created by BI, Vincent Schippefilt (vsc)
Statuses:
- label
- odoo:master-squish-vsc
- head
- a34c02c927d3e8f2d8380595457964e613cad6d7
- merged
- 2 months ago by BI, Lucas Lefèvre (lul)
| odoo/o-spreadsheet | |
|---|---|
| master | #7756 |
[IMP] export: reduce JSON size
Description:
Reduce the JSON file size of spreadsheets by storing only changes to formulae and, in a second pass,
collecting all the formulae or changes that are the same and storing them under one single key in the JSON file.
Task: 5489478
API changes:
compiler.ts/compile(formula: string) --> CompiledFormula.Compile(formula: string, sheetId: UID, getters: CoreGetters)
fomulas/helpers.ts/getFunctionsFromTokens(tokens: Tokens[], functionNames: string[]) --> fomulas/helpers.ts/getFunctionsFromTokens(compiledFormula: CompiledFormula, functionNames: string[])
removed RangeCompiledFormula --> CompiledFormula
model.ts/export() --> export(shouldSquish?: boolean = false)
cell.ts/getTranslatedFormulaCell(sheetId: UID, offsetX: number, offsetY: number, tokens: Token[]) --> getTranslatedFormulaCell(sheetId: UID,offsetX: number,offsetY: number,compiledFormula: CompiledFormula | SerializedCompiledFormula )
removed plugins/core/cell.ts/ReferenceToken class --> it is implemented in CompiledFormulaformulas/helper.ts/isExportableToExcel&getFunctionsFromTokens--> CompiledFormula.areAllFunctionsExportableToExcel&getFunctionsFromTokens`
removed FormulaCellWithDependencies and ReferenceToken
Observed performance gains on large dashboard:
importing sheets:
~2300ms --> ~680 ms
1560 MB ram --> 580 MB
JSON Size:
40 MB -> 147 KB
4,4 MB -> 3KB
1,6 MB-> 43 KB
How does it work:
Shared formula
```cells: {
A1: "My Text",
A2: "=SUM(B2:B9)",
A3: "=SUM(B2:B9)",
As we can see, A2 and A3 share the same formula. They can be rewritten as
```cells: {
A1: "My Text",
'A2:A3': "=SUM(B2:B9)",
removing duplication completely
Formula with small differences
Usually formula do not repeat exactly the same, but offset their dependencies (being either references to other cells, numbers or strings) slightly. We can rewrite:
```cells: {
A1: "My Text",
A2: "=CONCAT(B2, $C$2, D2, "hello"),
A3: "=CONCAT(B3, $C$2, D3, "hello"),
A4: "=CONCAT(B4, $C$2, D4, "hello"),
to
```cells: {
A1: "My Text",
A2: "=CONCAT(B2, $C$2, D2, "hello"),
A3: { R : "+R1|=|+R1" },
A4: { R : "+R1|=|+R1" },
...
now we see that A3 and A4 have the same transformation, so we can rewrite them to
```cells: {
A1: "My Text",
A2: "=CONCAT(B2, $C$2, D2, "hello"),
"A3:A4": { R : "+R1|=|+R1" },
We apply the same for number arguments and string arguments.
A formula with all the arguments slightly changed might look like
```cells: {
A1: "=MY_FORMULA(1, B1, "coucou"),
A2: { R : "+R1", N: "+1", S: ["hello"] },
A3:A4: { R : "+R1", N: "+1"}
can be read as
cells: {
A1: "=MY_FORMULA(1, B1, "coucou"),
A2: "=MY_FORMULA(2, B2, "hello"),
A3: "=MY_FORMULA(3, B3, "hello"),
A4: "=MY_FORMULA(4, B4, "hello"),
When reading the compressed JSON, the order of the keys in the JSON itself do not matter, they are sorted on the first part of the key, so either the cell reference or the left part of the range.