Fetch API
o.jFetch3 = function () {
fetch(o.url)
.then(validate)
.then(jreduceFetch)
.then(toDOM)
.catch(log)
}
XHR: XMLHttpRequest()
| Promisified: fetchXHR()
@ Basic GET
document.querySelector('H1').onclick = makeRequest
function makeRequest() {
var xhr = new XMLHttpRequest()
xhr.open('GET', '/foo', true)
xhr.onreadystatechange = function() {
if(xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200){
toDOM(xhr) // callback
}
}
xhr.send()
}
var toDOM = (xhr) => {
var el = document.querySelector('H1'),
html = `<h2><code>${xhr.responseText}</code></h2>`
el.insertAdjacentHTML("afterend",html)
document.querySelector('BODY').prepend(el) // APPENDs to BODY
}
@ JSON POST
/GET
// POST
function post(url, data, callback) {
var xhr = new XMLHttpRequest()
xhr.open("POST", url, true)
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded")
xhr.onload = function() {
callback(JSON.parse(xhr.response))
}
xhr.send(JSON.stringify(data))
}
// GET
function get(url, callback) {
var xhr = new XMLHttpRequest()
xhr.open("GET", url, true)
xhr.onload = function() {
callback(JSON.parse(xhr.response))
};
xhr.send(null)
}
( XHR | Fetch ) & Render
Various schemes profiled @ JSON payload
- (
jrender.js
)
Fetch and render one large set of serialized blocks of an html component, coded in JSON; one file. - (
hrender.js
)
Fetch and render a serialized set of html files, each one block of the html component.
tl;dr
Injecting pre-rendered html fragments is very performant, in both network efficiency and DOM manipulation. JSON works as well too. Template literals are great for mapping JSON to html components very quickly; bypasses the per-node javascript code. The DOM performance will suffer some, but the tradeoff is well worth it for most text rendering scenarios, e.g., chat/comments threads and such.
XHR vs. Fetch
- Both use Promise chained processing, from HTTP GET, all the way through to HTML injected into DOM. Here, XHR refers to a promisified XHR function (
fetchXHR
). The Fetch API is a low-level API, just like its predecessor,
XHR
. Fetch requires explicit coding to handle the full set of AJAX processing fail modes. Asent such, it provides zero HTTP response info, e.g., onHTTP 404
; from MDN: The Promise returned fromfetch()
won’t reject on HTTP error status ...HTTP 404
or500
. Instead, it will resolve normally (withok
status set tofalse
), and it will only reject on network failure or if anything prevented the request from completing. Worse,.json()
is deadly. Forbids any scheme to catch any error on any malformed json payload. (It fails internally, somehow, and offers no hooks for any ES6 error catching schemes.) (More on Fetch API.)fetch()
defaults to allow CORS.// @ CORS, if server Response Header: // Access-Control-Allow-Origin: <origin> var initFetch = { method: 'GET', mode: 'cors', cache: 'default' } $.url = new Request($.domain+'/data/data-serial-1.json', initFetch) $.jFetch2()
- Both use Promise chained processing, from HTTP GET, all the way through to HTML injected into DOM. Here, XHR refers to a promisified XHR function (
HTML DOM
Best performance is by promise/resolve all data prior to DOM manipulation. Fetching a single JSON file of 1000 serialized html components takes about 50 ms, from fetch to DOM injection. Here is a single block of the tested component:<h2><code>el[008] @ 150</code></h2> <p>rTJqlr dm41uf L6UI36 gN9MkT pFvxbQ dBucYJ NfBsHt GVCPNf xS1khx k8TNLV KCv4kJ 2eWBBG LgjG3K 3qj5M6 rxvSXZ qTZqQ9 YGxMTD kFWJ56 5BK0Cl 3YepEy couB64 ND12vF WEXeYr AWXfiX kYWrPc </p> <div><span>foo</span> ☧ <i>bar</i> <span>baz</span></div>
ES6 _Tagged Template Literal is used to generate string,
injected byinsertAdjactentHTML()
method.// Render HTML from JSON; this is the data reducer callback. function render(s, j) { s += `\n<h2><code>${j.head}</code></h2> <p>${j.body}</p> <div><span>${j.f1}</span> ${j.f2} <i>${j.f3}</i> <span>${j.f4}</span></div>\n` return s }
- @
d.reduce(render, '')
- @