<picture>
<source srcset="2x.webp 2x, 1x.webp 1x" type="image/webp">
<source srcset="2x.jpg 2x, 1x.jpg 1x" type="image/jpeg">
<img src="fallback.jpg" alt="">
</picture>// create observer
const observer = new IntersectionObserver(onChange);
function onChange(changes) {
changes.forEach(change => {
// take image url from `data-src` attribute
change.target.src = change.target.dataset.src;
// stop observing the current target
observer.unobserve(change.target);
});
}
// convert node list to array
const imgs = [ ...document.querySelectorAll('.lazy') ];
// observe each image
imgs.forEach(img => observer.observe(img));<style>
body {
font-family: Arial, sans-serif;
}
body.has-fonts-loaded {
font-family: "My fancy font";
}
</style>
<script>
someFontLoader
.load('My fancy font')
.then(() => {
document.body.classList.add('has-fonts-loaded');
});
</script>body {
font-family:
/* 1 */ -apple-system, BlinkMacSystemFont,
/* 2 */ "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans",
/* 3 */ "Helvetica Neue", sans-serif;
}<link rel="preload" href="font.woff2" as="font" type="font/woff2" crossorigin=""> />
github.com/
// index.html
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/sw.js');
}// sw.js
self.addEventListener('install', (event) => {
// Prime your cache
});// sw.js
self.addEventListener('activate', (event) => {
// This SW is taking control, clean up old caches and do migration work if needed
});// sw.js
self.addEventListener('fetch', (event) => {
// Intercept network requests, resolve from cache if hit.
});