Lazy loading with intersection observer
As the title says we will create logic for lazy loading modules.
The goal here is to load the module only if it reaches the viewport.
The reason why we want to do it lies in the fact that we do not want to load or execute code that is not visible to the user.
observer.ts file
const imported = {} as { [key: string]: boolean }
export default (element: HTMLElement, componentFileName: string) => {
const target = element;
const entryCallback = (elements: IntersectionObserverEntry[], observerRef: IntersectionObserver) => {
elements.map(async (entry) => {
if (entry.isIntersecting) {
// Once we've observed this element come into view, we can safely remove the observer since we won't need to import the Module again
observerRef.unobserve(target);
// Create name by ID or Class
const name = element.id || element.className;
if (!imported[name]) {
// Prevention of multiple loading
imported[name] = true;
// Path to your modules
import(`../javascripts/components/${componentFileName}`).then(({
default: Component
}) => {
const component = new Component();
// Run your component/Class
return component.init();
}).catch((err) => console.log(module, 'does not exists'));
}
} else {
// Logic for element if it's not visible
entry.target.classList.remove('visible')
}
});
}
const componentObserver = new IntersectionObserver(entryCallback);
return componentObserver;
}
components/component.ts file
export default class ComponentA {
message: string;
constructor() {
this.message = 'Hello from component A';
}
init() {
console.log(this.message);
}
}
modules/component.ts
import observer from '../observer';
export default () => {
const element = document.getElementById('app');
if (element) {
observer(element, 'component').observe(element);
}
};
scripts.ts
import component from "./modules/component";
document.addEventListener("DOMContentLoaded", (event) => {
component();
});
领英推荐