Skip to content

Commit 073f7b6

Browse files
🐛 fix: performance improvements and suspense bug fixes (#530)
* fix: ensure `loadLottie` is called after the component mounted (#527) * fix: ensure `loadLottie` invoke after `lottieAnimationContainer` is mounted * refactor: remove unnecessary `nextTick` * perf: educe the unnecessary use of `ref` (#526) Co-authored-by: Sanjay Soundarajan <[email protected]> * refactor: switch to smaller dependencies to reduce bundle size (#525) * 🐛 fix: performance improvements and suspense bug fixes * 🔖 chore: prep for releasing v3.3 * 🔖 chore: prep for releasing v3.3 beta --------- Co-authored-by: Alex Liu <[email protected]>
1 parent d24d1e7 commit 073f7b6

File tree

10 files changed

+103
-36
lines changed

10 files changed

+103
-36
lines changed

README.md

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -153,11 +153,11 @@ yarn add vue3-lottie@latest
153153
- Add the following code to the **`Vue3Lottie.client.ts`** file.
154154

155155
```ts
156-
import { Vue3Lottie } from 'vue3-lottie'
156+
import { Vue3Lottie } from 'vue3-lottie'
157157

158-
export default defineNuxtPlugin((nuxtApp) => {
159-
nuxtApp.vueApp.component('Vue3Lottie')
160-
})
158+
export default defineNuxtPlugin((nuxtApp) => {
159+
nuxtApp.vueApp.component('Vue3Lottie')
160+
})
161161
```
162162

163163
If you get an error with TS, try `component(Vue3Lottie, { name: "Vue3Lottie" })`
@@ -254,5 +254,9 @@ A big thank you goes to [@reslear](https://github.com/reslear) for adding Typesc
254254
- [@Tafel](https://github.com/tafelnl) - PR[#296](https://github.com/megasanjay/vue3-lottie/pull/296) - Update lodash to the tree-shakeable versions
255255
- [@TartanLeGrand](https://github.com/TartanLeGrand) - PR[#307](https://github.com/megasanjay/vue3-lottie/pull/307) - Add the `assetsPath` prop to the component
256256
- [@HighSky2GT](https://github.com/HighSky2GT) - PR[#408](https://github.com/megasanjay/vue3-lottie/pull/408) - Add support for dynamic animation data
257+
- [@Mini-ghost](https://github.com/Mini-ghost) - PR[#524](https://github.com/megasanjay/vue3-lottie/pull/524) - Adjust script filter syntax
258+
- [@Mini-ghost](https://github.com/Mini-ghost) - PR[#525](https://github.com/megasanjay/vue3-lottie/pull/525) - Reduce bundle size by swapping `lodash-es` for `klona` and `fast-deep-equal`
259+
- [@Mini-ghost](https://github.com/Mini-ghost) - PR[#526](https://github.com/megasanjay/vue3-lottie/pull/526) - Improve rendering performance
260+
- [@Mini-ghost](https://github.com/Mini-ghost) - PR[#527](https://github.com/megasanjay/vue3-lottie/pull/527) - Fix lottie renders in `suspense` components
257261

258262
![forthebadge](https://forthebadge.shorty.systems/images/badges/made-with-vue.svg) ![forthebadge](https://forthebadge.shorty.systems/images/badges/built-with-love.svg)

packages/playground/nuxt-project/app.vue

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,22 @@
2727
/>
2828
</ClientOnly>
2929

30+
<Suspense>
31+
<LazyDynamicComponent />
32+
<template #fallback> Loading... </template>
33+
</Suspense>
34+
3035
<HelloWorld msg="Hello Lottie! Using Nuxt 3" />
3136
</template>
3237

3338
<script setup lang="ts">
3439
import DogJSON from '@/assets/dog.json'
3540
import Lottie from '@/assets/lottie.json'
41+
import { ref, defineAsyncComponent } from 'vue'
42+
43+
const LazyDynamicComponent = defineAsyncComponent(
44+
() => import('./components/DynamicComponent.vue'),
45+
)
3646
3747
const links = ref([
3848
'https://assets1.lottiefiles.com/packages/lf20_soCRuE.json',
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<template>
2+
<div>
3+
<Vue3Lottie :animationData="dog" :width="300" :height="300" />
4+
</div>
5+
</template>
6+
7+
<script setup lang="ts">
8+
import dog from '../assets/dog.json'
9+
10+
await new Promise((resolve) => {
11+
setTimeout(() => {
12+
resolve(true)
13+
}, 3000)
14+
})
15+
</script>

packages/playground/vite-project/src/App.vue

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
<template>
2-
<Vue3Lottie :animationData="data" :width="300" :height="300" @click="dataClick"/>
2+
<Vue3Lottie
3+
:animationData="data"
4+
:width="300"
5+
:height="300"
6+
@click="dataClick"
7+
/>
38

49
<Vue3Lottie
510
ref="lot"
@@ -20,23 +25,36 @@
2025
:width="200"
2126
/>
2227

28+
<Suspense>
29+
<LazyDynamicComponent />
30+
<template #fallback> Loading... </template>
31+
</Suspense>
32+
2333
<HelloWorld msg="Hello Lottie! Using Vue 3 + TypeScript + Vite" />
2434
</template>
2535

2636
<script setup lang="ts">
2737
import HelloWorld from './components/HelloWorld.vue'
2838
import DogJSON from './assets/dog.json'
2939
import Lottie from './assets/lottie.json'
30-
import { ref } from 'vue';
40+
import { ref, defineAsyncComponent } from 'vue'
41+
42+
const LazyDynamicComponent = defineAsyncComponent(
43+
() => import('./components/DynamicComponent.vue'),
44+
)
45+
3146
const lot = ref()
3247
33-
const link = ref(['https://assets1.lottiefiles.com/packages/lf20_soCRuE.json','https://assets1.lottiefiles.com/packages/lf20_xvz0dpbn.json'])
48+
const link = ref([
49+
'https://assets1.lottiefiles.com/packages/lf20_soCRuE.json',
50+
'https://assets1.lottiefiles.com/packages/lf20_xvz0dpbn.json',
51+
])
3452
const data = ref<any>(DogJSON)
35-
function linkClick(){
53+
function linkClick() {
3654
link.value = link.value.reverse()
3755
}
38-
function dataClick(){
39-
data.value = Lottie
56+
function dataClick() {
57+
data.value = Lottie
4058
}
4159
</script>
4260

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<template>
2+
<div>
3+
<Vue3Lottie :animationData="dog" :width="300" :height="300" />
4+
</div>
5+
</template>
6+
7+
<script setup lang="ts">
8+
import dog from '../assets/dog.json'
9+
10+
await new Promise((resolve) => {
11+
setTimeout(() => {
12+
resolve(true)
13+
}, 3000)
14+
})
15+
</script>

packages/vue3-lottie/README.md

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -153,11 +153,11 @@ yarn add vue3-lottie@latest
153153
- Add the following code to the **`Vue3Lottie.client.ts`** file.
154154

155155
```ts
156-
import { Vue3Lottie } from 'vue3-lottie'
156+
import { Vue3Lottie } from 'vue3-lottie'
157157

158-
export default defineNuxtPlugin((nuxtApp) => {
159-
nuxtApp.vueApp.component('Vue3Lottie')
160-
})
158+
export default defineNuxtPlugin((nuxtApp) => {
159+
nuxtApp.vueApp.component('Vue3Lottie')
160+
})
161161
```
162162

163163
If you get an error with TS, try `component(Vue3Lottie, { name: "Vue3Lottie" })`
@@ -254,5 +254,9 @@ A big thank you goes to [@reslear](https://github.com/reslear) for adding Typesc
254254
- [@Tafel](https://github.com/tafelnl) - PR[#296](https://github.com/megasanjay/vue3-lottie/pull/296) - Update lodash to the tree-shakeable versions
255255
- [@TartanLeGrand](https://github.com/TartanLeGrand) - PR[#307](https://github.com/megasanjay/vue3-lottie/pull/307) - Add the `assetsPath` prop to the component
256256
- [@HighSky2GT](https://github.com/HighSky2GT) - PR[#408](https://github.com/megasanjay/vue3-lottie/pull/408) - Add support for dynamic animation data
257+
- [@Mini-ghost](https://github.com/Mini-ghost) - PR[#524](https://github.com/megasanjay/vue3-lottie/pull/524) - Adjust script filter syntax
258+
- [@Mini-ghost](https://github.com/Mini-ghost) - PR[#525](https://github.com/megasanjay/vue3-lottie/pull/525) - Reduce bundle size by swapping `lodash-es` for `klona` and `fast-deep-equal`
259+
- [@Mini-ghost](https://github.com/Mini-ghost) - PR[#526](https://github.com/megasanjay/vue3-lottie/pull/526) - Improve rendering performance
260+
- [@Mini-ghost](https://github.com/Mini-ghost) - PR[#527](https://github.com/megasanjay/vue3-lottie/pull/527) - Fix lottie renders in `suspense` components
257261

258262
![forthebadge](https://forthebadge.shorty.systems/images/badges/made-with-vue.svg) ![forthebadge](https://forthebadge.shorty.systems/images/badges/built-with-love.svg)

packages/vue3-lottie/package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "vue3-lottie",
3-
"version": "3.2.0",
3+
"version": "3.3.0-beta.0",
44
"license": "MIT",
55
"author": "Sanjay Soundarajan <[email protected]> (https://sanjaysoundarajan.dev)",
66
"type": "module",
@@ -13,7 +13,8 @@
1313
"prettier": "npx prettier --write ."
1414
},
1515
"dependencies": {
16-
"lodash-es": "^4.17.21",
16+
"fast-deep-equal": "^3.1.3",
17+
"klona": "^2.0.6",
1718
"lottie-web": "5.12.2"
1819
},
1920
"peerDependencies": {

packages/vue3-lottie/src/vue3-lottie.vue

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,10 @@ import {
1616
defineComponent,
1717
PropType,
1818
watchEffect,
19-
nextTick,
2019
} from 'vue'
2120
import Lottie from 'lottie-web'
22-
import { cloneDeep, isEqual } from 'lodash-es'
21+
import isEqual from 'fast-deep-equal/es6';
22+
import { klona as cloneDeep } from 'klona/json';
2323
2424
import type {
2525
AnimationDirection,
@@ -113,13 +113,17 @@ export default defineComponent({
113113
},
114114
115115
setup(props, { emit: emits }) {
116-
const animationData = ref<any>()
117116
const lottieAnimationContainer = ref<HTMLDivElement>()
118117
118+
let animationData: any
119119
let lottieAnimation: AnimationItem | null = null
120120
let direction: AnimationDirection = 1
121121
122122
watchEffect(async () => {
123+
// track and ensure that `lottieAnimationContainer` is mounted
124+
// fix: #502
125+
if(!lottieAnimationContainer.value) return
126+
123127
if (props.animationLink != '') {
124128
// fetch the animation data from the url
125129
@@ -128,31 +132,29 @@ export default defineComponent({
128132
129133
const responseJSON = await response.json()
130134
131-
animationData.value = responseJSON
132-
133-
nextTick(() => loadLottie())
135+
animationData = responseJSON
134136
} catch (error) {
135137
console.error(error)
136138
return
137139
}
138140
} else if (isEqual(props.animationData, {}) === false) {
139141
// clone the animationData to prevent it from being mutated
140-
animationData.value = cloneDeep(props.animationData)
141-
142-
nextTick(() => loadLottie())
142+
animationData = cloneDeep(props.animationData)
143143
} else {
144144
throw new Error(
145145
'You must provide either animationLink or animationData',
146146
)
147147
}
148+
149+
loadLottie()
148150
})
149151
150152
const loadLottie = () => {
151153
// check if the lottieAnimationContainer has been created
152154
if (!lottieAnimationContainer.value) return
153155
154156
// check if the animationData has been loaded
155-
if (!animationData.value) return
157+
if (!animationData) return
156158
157159
// destroy the animation if it already exists
158160
lottieAnimation?.destroy()
@@ -186,7 +188,7 @@ export default defineComponent({
186188
renderer: props.renderer,
187189
loop: loop,
188190
autoplay: autoPlay,
189-
animationData: animationData.value,
191+
animationData: animationData,
190192
assetsPath: props.assetsPath,
191193
}
192194

packages/vue3-lottie/tsconfig.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
"module": "ESNext",
55
"strict": true,
66
"declaration": true,
7+
"allowSyntheticDefaultImports": true,
78
"lib": ["es2017", "ESNext", "DOM", "DOM.Iterable"],
89
"jsx": "preserve",
910
"outDir": "dist",

pnpm-lock.yaml

Lines changed: 6 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)