Lazy Loading
Since RVS is written in React it means it will bring in React too which will add non-trivial weight to you page. Luckily this can be mitigated almost completely by lazy loading: Fox example you can the load it just time when the search input is focused.
The lazy loading is done using the dynamic import()
statement and the provided
loader tools.
To make things lazy loadable we must split the code into two files: main.js
and valu-search.js
for example. The main.js
will contain triggers for the
lazy loading and the dynamic import()
statement. The valu-search.js
will
then contain the actual import to the ValuSearch
class, its initialization and
export as the default export:
valu-search.js
:
import { ValuSearch } from "@valu/react-valu-search";
const vs = new ValuSearch({
customer: "<customer id>",
apiKey: "<api key>",
slots: {
modalHeader: () => null,
},
});
export default vs;
main.js
:
// 👇 It's important to not import @valu/react-valu-search directly here but
// only the subpackage `lazy`. This ensures the main entry bundle won't get
// bloated by RVS.
import { LazyValuSearch, select } from "@valu/react-valu-search/lazy";
const loader = new LazyValuSearch({
// import the file exporting the ValuSearch instance as the default export
load: () => import("./valu-search"),
});
loader.init(() => {
// This init callback will be invoked on the DOMContentLoaded event so you
// can safely query the DOM.
// RVS provides small wrapper to the document.querySelector() which will
// assert that the returned element is what you expect
const input = select("#search-input-in-header", HTMLInputElement);
input.addEventListener(
"focus",
() => {
// Start lazy loading when the input is focused
loader.load();
},
false,
);
return vs => {
// This function returned from the init callback will be called when the
// lazy loading completes. The ValuSearch instance is passed to it which
// can be used to bind inputs.
vs.bindInput(input);
vs.initModal();
};
});
Full example:
https://github.com/valu-digital/react-valu-search-examples/tree/master/parcel-header-input-lazy
Fullscreen with opener​
The fullscreen example with the build-in search input would look like this when lazy loaded:
valu-search.js
:
import { ValuSearch } from "@valu/react-valu-search";
const vs = new ValuSearch({
customer: "<customer id>",
apiKey: "<api key>",
});
export default vs;
main.js
:
import { LazyValuSearch, select } from "@valu/react-valu-search/lazy";
const loader = new LazyValuSearch({
load: () => import("./valu-search"),
});
loader.init(() => {
const button = select("#open-button", HTMLButtonElement);
button.addEventListener(
"click",
() => {
// The activate() method lazy loads the valu-search.js file and
// calls .activate() on the ValuSearch instance as well as soon as
// possible. On subsequent calls when the module is already loaded it
// just activates the VS instance.
loader.activate();
// Since the lazy loading might take a second we add a class that
// visualizes the loading state via CSS if it is not loaded yet.
if (!loader.isLoaded()) {
button.classList.add("loading");
}
},
false,
);
return vs => {
// Once ready we can remove the loading indicator
button.classList.remove("loading");
vs.initModal();
};
});
Full example
https://github.com/valu-digital/react-valu-search-examples/tree/master/parcel-fullscreen-modal-lazy
Fullscreen with input as opener​
The fullscreen example with the build-in search input would look like this when lazy loaded:
valu-search.js
:
import { ValuSearch } from "@valu/react-valu-search";
const vs = new ValuSearch({
customer: "<customer id>",
apiKey: "<api key>",
});
export default vs;
main.js
:
import { LazyValuSearch, select } from "@valu/react-valu-search/lazy";
const loader = new LazyValuSearch({
load: () => import("./valu-search"),
});
loader.init(() => {
const input = select("#outside-input", HTMLInputElement);
return vs => {
// Input is not visible while RVS is active so you should NOT use .bindInput()
// as it binds the input as a part of the RVS. Instead use .bindInputAsOpener()
// which activates the RVS on keydown event or if there already was text in the
// input when lazy load completes. Input contents are set as search terms and
// the input is cleared. Focus will move automatically to full screen input
vs.bindInputAsOpener(input);
vs.initModal();
};
});
Full example
Polyfills​
The LazyValuSearch
helper will automatically load and apply polyfills from our
CDN when needed but if you provide your own you can disable this behaviour by
marking the enviroment as modern:
const loader = new LazyValuSearch({
polyfill: {
isModern: true,
},
load: () => import("./valu-search"),
});
Executing custom vs code during lazy load​
Everything you export from main.js
can be accessed in loader.init()
callback.
Lazy valu-search.js
should have minimum amount of code to keep it light as
possible. Create pure functions in main.js
and call then in loader.init()
callback.
import { LazyValuSearch, select } from "@valu/react-valu-search/lazy";
const loader = new LazyValuSearch({
load: () => import("./valu-search"),
});
loader.init(() => {
const input = select("#outside-input", HTMLInputElement);
return (vs, module) => {
module.yourAwesomeFunction();
vs.bindInputAsOpener(input);
vs.initModal();
};
});