React Static prefetch
React Static, czyli lekki generator stron statycznych oparty na ReactJS przeszedł właśnie w tryb maintenance.
Oprócz przewodniej architektury opartej o JAMStack (JavaScript/
Preloader
Funkcję odpowiedzialną za pobieranie z wyprzedzeniem znajdziemy po stronie klienta. Preloader co pewien określony czas skanuje listę odnośników w dokumencie strony i dla nowo wykrytych rejestruje funkcję pobierania. Tuż po pojawieniu się odnośnika w okienku przeglądarki (Intersection Observer API) dane strony zostają pobrane w tle.
Mechanizm pobierania z wyprzedzeniem wyłączyć możemy, ustawiając flagę disablePreload
na true
w konfiguracji wyeksportowanej w pliku static.config.js.
Selektywnie zrobimy to, dodając do elementu atrybut data-prefetch="false"
.
Jednocześnie nic nie stoi na przeszkodzie implementacji własnych warunków pobierania.
Przykładowo, gdy mamy zbyt dużo odnośników na ekranie, wybrane z nich możemy chcieć pobierać dopiero po najechaniu na nie kursorem.
W takim przypadku importujemy funkcję prefetch
, implementujemy onVisible
(niestety nie jest ona wyeksportowana)
na swoje podobieństwo, a interesującą nas logikę umieszczamy we własnym preloaderze.
import App from './App';
import React from 'react';
import ReactDOM from 'react-dom';
import { prefetch } from "react-static";
export default App;
if (typeof document !== "undefined") {
const target = document.getElementById("root");
const renderMethod = target.hasChildNodes()
? ReactDOM.hydrate
: ReactDOM.render;
const render = Comp => {
renderMethod(<Comp />, target);
};
render(App);
if (module && module.hot) {
module.hot.accept("./App", () => {
render(App);
});
}
startPreloader();
}
function startPreloader() {
const prefetchCallback = (el, href) => {
if (!el.getAttribute("prefetch-on-hover")) {
prefetch(href);
return;
}
const onHover = function() {
el.removeEventListener("pointerenter", onHover)
prefetch(href);
};
el.addEventListener("pointerenter", onHover)
};
if (typeof document !== 'undefined') {
const run = () => {
const els = [].slice.call(document.getElementsByTagName('a'))
els.forEach(el => {
const href = el.getAttribute('href')
if (href) {
onVisible(el, prefetchCallback.bind(null, el, href));
}
})
}
setInterval(run, Number(process.env.REACT_STATIC_PRELOAD_POLL_INTERVAL))
}
}
const list = new Map()
const onVisible = (element, callback) => {/*...*/}
Preloader włączamy tuż po załadowaniu aplikacji (index.js).