Reducing JS code in your Vue bundle
v-moe
Posted on May 27, 2022
I recently got a typical task for a UI component library.
Creating an atomic video component.
Not hard to achieve, take an embed url for example one of those from Youtube and set it as the src attribute of an iframe.
As a requirement there should be a default width-to-height ratio on the iframe and the possibility to customize it.
The following code examples are simplified.
My first approach is probably what would occur first to every Vue dev put in front of this problem.
<script setup lang="ts">
interface Props {
url: string
ratio?: [number, number]
}
withDefaults(defineProps<Props>(), {
ratio: () => [776, 437],
})
</script>
<template>
<iframe
:src="url"
:style="{ aspectRatio: `${ratio[0]} / ${ratio[1]}` }"
/>
</template>
This exposes a nice API, wehere the customer can customize the ratio like this
<UiVideo url="somewhere" :ratio="[3, 1]"/>
But we have added a prop and silently a computed prop just for a CSS property value.
Not a big deal in an SPA but what if you are building a site where you want your JS to be as small as possible?
Well we could use Astro of course ;-)
But what if not?
A teammate came up with a great idea, it avoids the JS at the price of a tiny little bit of extra CSS!
<script setup lang="ts">
interface Props {
url: string
}
</script>
<template>
<iframe :src="url" style="aspect-ratio: var(--video-ratio, 776 / 437)" />
</template>
The extra prop is gone!
Consuming the component and customizing the ratio will now look like
<UiVideo url="somewhere" style="--video-ratio: 3 / 1"/>
You can also create a CSS class and apply that instead of using an inline style of course.
Really convenient! While I think that the first version is still a bit more developer friendly (TS + your IDE will suggest ratio
as a prop when you start typing <UiVideo ...
) the second does everything you actually need and is even cleaner from some point of view (CSS from style
or class
, data + logic from props
)
In a big SPA where initial page load performance is not an issue, I would still prefer the first version though, maybe I still have to get used to this great pattern that leverages the power of CSS custom props.
Good documentation and a reliable CSS props naming strategy is absolutely necessary to make this scale and not become messy.
Posted on May 27, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.