Solution for vue modal dropping frames when using transitions
is Given Below:
I wrote a custom vue modal and it works perfectly fine on my pc but it keeps dropping frames on some mobile devices. It seems to be related to the transitions – without it works as expected (but looks and feels bad).
Even a transition with opacity 1 to opacity 0 causing lag in this case. (Any animation causing lag)
It’s really simple code so it should work on every device – even mid range devices like the Samsung M31 can’t display the animation without lag. (Even when the transition is only opacity or scale)
Menu.vue
<Modal :is-open="testModalIsOpen" >
test1
test2
test3
test4
test5
<template #footer>
<button @click="testModalIsOpen=false">BACK</button>
</template>
</Modal>
Modal.vue
<template>
<transition name="rpg-modal__transition">
<div class="rpg-modal" v-if="isOpen" :class="classes">
<div class="rpg-modal__backdrop"></div>
<div class="mx-auto rpg-modal__content-wrapper">
<div class="rpg-modal__box" style="background-color: #0b1b3d">
<div>
<div class="rpg-modal__body">
<slot/>
</div>
<div class="rpg-modal__footer d-flex justify-content-end">
<slot name="footer"/>
</div>
</div>
</div>
</div>
</div>
</transition>
</template>
<script>
import {computed} from "@vue/reactivity";
export default {
name: "Modal",
props: {
isOpen: {
type: Boolean,
default: false
},
autoPadding: {
type: Boolean,
default: true
}
},
setup(props) {
const classes = computed(() => ({
'rpg-modal--auto-padding': props.autoPadding
}));
return {
classes,
};
}
}
</script>
<style lang="scss">
.rpg-modal {
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 1000;
$transition-duration: 0.3s;
&__transition {
&-enter-active, &-leave-active {
transition: all $transition-duration;
}
&-enter-from, &-leave-to {
opacity: 0;
filter: blur(5px);
transform: scale(1.3);
}
}
&__backdrop {
position: absolute;
height: 100%;
width: 100%;
background-color: rgba(0, 0, 0, 0.5);
}
&__content-wrapper {
max-width: 64vh;
margin: auto;
}
&__box {
$boxMargin: 13px;
position: relative;
margin: $boxMargin;
max-height: calc(100vh - #{$boxMargin * 2});
border-radius: 15px;
background-repeat: no-repeat;
background-size: 100% 100%;
box-shadow: #00000073 0 0 10px;
}
&--auto-padding &__body {
padding: 12px;
}
&__footer {
border-top: 1px solid #000000;
padding: 9px;
> * {
margin: .25rem;
}
}
&__close {
font-size: 1.5rem;
line-height: 1;
text-shadow: 0 1px 0 #fff;
position: absolute;
z-index: 20;
background-color: rgb(62 62 62);
box-shadow: #00000052 2px 2px 5px;
color: white;
height: 30px;
width: 30px;
padding: 0 0 4px;
border-radius: 50px;
border: none;
right: 17px;
top: 17px;
transition: background-color 200ms;
&:hover {
background-color: #9f3e3e;
}
}
}
</style>
Hope anyone can help & thanks for any answers!
Have you tried the will-change property?
The will-change property in CSS optimizes animations by letting the
browser know which properties and elements are just about to be
manipulated, potentially increasing the performance of that particular
operation.
from here
So, try this:
.rpg-modal{
will-change: transform, opacity, filter;
}
Also, set the initial value of the modal, the opacity:0 and the others…