How do we usually store something in the database that needs to be shown to the user and has some markup properties? Whoever made his blog at least once, habr or similar will immediately say - html. What if I told you what you can do differently? JSON.
I would like to consider the advantages and disadvantages of such storage, or at least try.
What? Json? Why is this even necessary?
Description:
We have a service, in the database we store html for displaying some content.
, ( ) . \
( , )
:
, , css - .
- UI, , html css .
: , , :
css javascript ( ) .
:
html, json, , .
, :
. ( ) json html. json' html, Web View .
, api ( ) \
: , , .
html, json.
: : https://habr.com/ru/company/tuturu/blog/526710/
<img src="https://habrastorage.org/webt/nz/2t/p3/nz2tp3ywl9fdr7quadxm1dzmhdo.jpeg"><br>
<sup> , , . . </sup><br>
{
"type": "image",
"src": "https://habrastorage.org/webt/nz/2t/p3/nz2tp3ywl9fdr7quadxm1dzmhdo.jpeg",
"caption": " , , . ."
}
: : https://habr.com/ru/post/526676/
<img src="https://habrastorage.org/webt/lr/ql/v9/lrqlv9u6cxmuoyn-0hgrik3z0aw.jpeg"><br>
<i> .</i><br>
{
"type": "image",
"src": "https://habrastorage.org/webt/lr/ql/v9/lrqlv9u6cxmuoyn-0hgrik3z0aw.jpeg",
"caption": " ."
}
, , figcaption
, , , , , .
.
( , html5 details):
<div class="spoiler" role="button" tabindex="0">
<b class="spoiler_title"> . </b>
<div class="spoiler_text">, :<br />
<br />
<ul>
<li> ( ) </li>
<li> </li>
<li> </li>
<li> </li>
<li> </li>
<li></li>
</ul><br />
« » «
». - , .<br />
<br />
<a
href="https://anabin.kmk.org/anabin.html" rel="nofollow">Anabin</a>.<br />
<br />
:<br />
<br />
<ul>
<li> </li>
<li> . «»
</li>
<li> </li>
<li> , ,
</li>
<li> <a
href="https://germania.diplo.de/ru-ru/service/05-VisaEinreise/langfristigerAufenthalt/-/1611410?openAccordionId=item-1611410-3-panel"
rel="nofollow"> </a> </li>
<li> </li>
<li> </li>
</ul><br />
, .<br />
<br />
: <a href="https://germania.diplo.de/ru-ru"
rel="nofollow"> </a> . : ,
. ,
, . ,
«blue card», - —
.<br />
<br />
, .<br />
<br />
, - - 3 6-.
, !<br />
<br />
, . <br />
</div>
</div>
Eeeeee ... let's convert this to json:
{
"type": "details",
"title": " . ",
"child": {
"type": "div",
"children": [
{
"type": "tp",
"text": ", :"
},
{
"type": "unordered_list",
"children": [
{
"type": "tp",
"text": " ( ) "
},
{
"type": "tp",
"text": " "
},
{
"type": "tp",
"text": " "
},
{
"type": "tp",
"text": " "
},
{
"type": "tp",
"text": " "
},
{
"type": "tp",
"text": ""
}
]
},
{
"type": "tp",
"text": " « » « ». - , ."
},
{
"type": "paragraph",
"children": [
{
"type": "span",
"text": " ",
"mode": []
},
{
"type": "link_span",
"text": "Anabin",
"src": "https://anabin.kmk.org/anabin.html"
},
{
"type": "span",
"text": ".",
"mode": []
}
]
},
{
"type": "tp",
"text": " :"
},
{
"type": "unordered_list",
"children": [
{
"type": "tp",
"text": " "
},
{
"type": "tp",
"text": " . «» "
},
{
"type": "tp",
"text": " "
},
{
"type": "tp",
"text": " , , "
},
{
"type": "paragraph",
"children": [
{
"type": "span",
"text": "",
"mode": []
},
{
"type": "link_span",
"text": " ",
"src": "https://germania.diplo.de/ru-ru/service/05-VisaEinreise/langfristigerAufenthalt/-/1611410?openAccordionId=item-1611410-3-panel"
},
{
"type": "span",
"text": " ",
"mode": []
}
]
},
{
"type": "tp",
"text": " "
},
{
"type": "tp",
"text": " "
}
]
},
{
"type": "tp",
"text": ", ."
},
{
"type": "paragraph",
"children": [
{
"type": "span",
"text": " : ",
"mode": []
},
{
"type": "link_span",
"text": " ",
"src": "https://germania.diplo.de/ru-ru"
},
{
"type": "span",
"text": " . : , . , , . , «blue card», - — .",
"mode": []
}
]
},
{
"type": "tp",
"text": " , ."
},
{
"type": "tp",
"text": ", - - 3 6-. , !"
},
{
"type": "tp",
"text": ", ."
}
]
}
}
, Html , .
:
{
"type": "paragraph",
"children": [
{
"type": "span",
"text": " ",
"mode": []
},
{
"type": "link_span",
"text": "Anabin",
"src": "https://anabin.kmk.org/anabin.html"
},
{
"type": "span",
"text": ".",
"mode": []
}
]
}
: mode
, bold
, italic
, strike
, .
, .
? , span
, , , TextView
, html
, , ( ). html Dart, . , , — .
. , html , , .
? 2 :
- json html json json'.
- .
? React, , "html_to_react" ( "html-dom-parser"), , , .
:
- json.
- , , :
- ( , html)
- html json
- json html .
- dom , "html_to_react"
:
import Benchmark from "benchmark";
import fs from 'fs';
import htmlToDOM from 'html-dom-parser';
function parse(str) {
return JSON.parse(str);
}
function prepareAndParse(str) {
return htmlToDOM(JSON.parse(str)["textHtml"]);
}
const suiteName = '526574'
const defaultHtml = fs.readFileSync(`./test_data/${suiteName}/html.json`);
const jHtml = fs.readFileSync(`./test_data/${suiteName}/jhtml.json`);
const suite = new Benchmark.Suite;
suite.add('Json c html2json', () => parse(jHtml))
suite.add('Html json', () => parse(defaultHtml))
suite.add('Html json html-dom-parser', () => prepareAndParse(defaultHtml))
suite.on('complete', function() {
console.log('Fastest is ' + this.filter('fastest').map('name'));
}).on('cycle', function(event) {
console.log(String(event.target));
})
suite.run()
:
Json c html2json x 1,892 ops/sec ±0.79% (88 runs sampled)
Html json x 1,917 ops/sec ±0.81% (89 runs sampled)
Html json html-dom-parser x 798 ops/sec ±3.04% (86 runs sampled)
- json' html json' .
- ( json, html) 2 html.
, ?
:
,
html
, , . css .
, , ios, flutter, web - .
WebView .
:
json , html
, :
- ,
- json ( — bson json), , , .
json html
, -:
- , , .
- , .
html , html, , , ( , )
, ,
, , , ?
:
- - ui
- , html. , , , .. javascript .
- , , , .
As a result, I would like to say that I do not propose to all at once switch to the approach I described in this article. First of all, I am interested in the opinion of other developers, both backend and frontend. Most likely, I did not take into account the nuances and am ready to listen and discuss criticism and comments.