Efficient Mobile Rendering: Conditional JavaScript with Alpine.js
Components often require different behaviors or visibility based on viewport size, typically appearing on desktop and hidden on mobile devices.
While CSS can hide elements, it doesn't remove them from the DOM. This can negatively impact page performance (Google DOM size) and SEO, especially for complex components or when state depends on more than just viewport size.
To truly optimize, Alpine.js's <template> syntax combined with window.matchMedia allows you to conditionally render components, removing them entirely from the DOM when not needed.
<script>
function initComponent() {
return {
isMobile: true,
init() {
const matchMedia = window.matchMedia('(max-width: 768px)');
// set the initial value
this.isMobile = matchMedia.matches;
// trigger update value on changes
if(typeof matchMedia.onchange !== 'object') {
// fallback for iOS 12/13, where addEventListener does not accept an event type parameter
matchMedia.addListener((event) => this.isMobile = event.matches);
} else {
matchMedia.addEventListener(
"change",
(event) => this.isMobile = event.matches
)
}
}
}
}
</script>
<div x-data="initComponent()" x-init="init()">
<template x-if="!isMobile">
<div>None of the HTML within <code><template></code> is counted as DOM elements by Google or the browser.</div>
</template>
</div>
For more details, explore window.matchMedia on the MDN documentation and the Alpine.js <template> directive on the Alpine templating docs.