feat: lazy load images (#1969)
parent
1ceb3e2857
commit
23c1dfec10
|
@ -1,8 +1,6 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { decode } from 'blurhash'
|
const { blurhash = '', src, srcset, shouldLoadImage = true } = defineProps<{
|
||||||
|
blurhash?: string
|
||||||
const { blurhash, src, srcset, shouldLoadImage = true } = defineProps<{
|
|
||||||
blurhash?: string | null | undefined
|
|
||||||
src: string
|
src: string
|
||||||
srcset?: string
|
srcset?: string
|
||||||
shouldLoadImage?: boolean
|
shouldLoadImage?: boolean
|
||||||
|
@ -11,44 +9,8 @@ const { blurhash, src, srcset, shouldLoadImage = true } = defineProps<{
|
||||||
defineOptions({
|
defineOptions({
|
||||||
inheritAttrs: false,
|
inheritAttrs: false,
|
||||||
})
|
})
|
||||||
|
|
||||||
const isLoaded = ref(false)
|
|
||||||
const placeholderSrc = $computed(() => {
|
|
||||||
if (!blurhash)
|
|
||||||
return ''
|
|
||||||
const pixels = decode(blurhash, 32, 32)
|
|
||||||
return getDataUrlFromArr(pixels, 32, 32)
|
|
||||||
})
|
|
||||||
|
|
||||||
function loadImage() {
|
|
||||||
const img = document.createElement('img')
|
|
||||||
|
|
||||||
img.onload = () => {
|
|
||||||
isLoaded.value = true
|
|
||||||
}
|
|
||||||
|
|
||||||
img.src = src
|
|
||||||
|
|
||||||
if (srcset)
|
|
||||||
img.srcset = srcset
|
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
isLoaded.value = true
|
|
||||||
}, 3_000)
|
|
||||||
}
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
if (shouldLoadImage)
|
|
||||||
loadImage()
|
|
||||||
})
|
|
||||||
|
|
||||||
watch(() => shouldLoadImage, () => {
|
|
||||||
if (shouldLoadImage)
|
|
||||||
loadImage()
|
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<img v-if="isLoaded || !placeholderSrc" v-bind="$attrs" :src="src" :srcset="srcset">
|
<UnLazyImage v-bind="$attrs" :blurhash="blurhash" :src="src" :src-set="srcset" :lazy-load="shouldLoadImage" auto-sizes />
|
||||||
<img v-else v-bind="$attrs" :src="placeholderSrc">
|
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -214,7 +214,7 @@ watch(shouldLoadAttachment, () => {
|
||||||
@click="!shouldLoadAttachment ? loadAttachment() : openMediaPreview(attachments ? attachments : [attachment], attachments?.indexOf(attachment) || 0)"
|
@click="!shouldLoadAttachment ? loadAttachment() : openMediaPreview(attachments ? attachments : [attachment], attachments?.indexOf(attachment) || 0)"
|
||||||
>
|
>
|
||||||
<CommonBlurhash
|
<CommonBlurhash
|
||||||
:blurhash="attachment.blurhash"
|
:blurhash="attachment.blurhash || ''"
|
||||||
class="status-attachment-image"
|
class="status-attachment-image"
|
||||||
:src="src"
|
:src="src"
|
||||||
:srcset="srcset"
|
:srcset="srcset"
|
||||||
|
|
|
@ -24,6 +24,7 @@ export default defineNuxtConfig({
|
||||||
'@vue-macros/nuxt',
|
'@vue-macros/nuxt',
|
||||||
'@nuxtjs/i18n',
|
'@nuxtjs/i18n',
|
||||||
'@nuxtjs/color-mode',
|
'@nuxtjs/color-mode',
|
||||||
|
'@unlazy/nuxt',
|
||||||
'nuxt-vitest',
|
'nuxt-vitest',
|
||||||
...(isDevelopment || isWindows) ? [] : ['nuxt-security'],
|
...(isDevelopment || isWindows) ? [] : ['nuxt-security'],
|
||||||
'~/modules/emoji-mart-translation',
|
'~/modules/emoji-mart-translation',
|
||||||
|
@ -248,6 +249,9 @@ export default defineNuxtConfig({
|
||||||
staleDep: {
|
staleDep: {
|
||||||
packageManager: 'pnpm',
|
packageManager: 'pnpm',
|
||||||
},
|
},
|
||||||
|
unlazy: {
|
||||||
|
ssr: false,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
|
|
|
@ -112,6 +112,7 @@
|
||||||
"@types/js-yaml": "^4.0.5",
|
"@types/js-yaml": "^4.0.5",
|
||||||
"@types/prettier": "^2.7.2",
|
"@types/prettier": "^2.7.2",
|
||||||
"@types/wicg-file-system-access": "^2020.9.6",
|
"@types/wicg-file-system-access": "^2020.9.6",
|
||||||
|
"@unlazy/nuxt": "^0.8.8",
|
||||||
"bumpp": "^9.1.0",
|
"bumpp": "^9.1.0",
|
||||||
"consola": "^3.0.1",
|
"consola": "^3.0.1",
|
||||||
"eslint": "^8.38.0",
|
"eslint": "^8.38.0",
|
||||||
|
|
|
@ -185,10 +185,10 @@ importers:
|
||||||
version: 5.0.1
|
version: 5.0.1
|
||||||
tauri-plugin-log-api:
|
tauri-plugin-log-api:
|
||||||
specifier: github:tauri-apps/tauri-plugin-log
|
specifier: github:tauri-apps/tauri-plugin-log
|
||||||
version: github.com/tauri-apps/tauri-plugin-log/36100c269e33ac91246b0a4bfadd18c1caee5296
|
version: github.com/tauri-apps/tauri-plugin-log/782a97aeb30cf0f54355d04e6026842fa420bd83
|
||||||
tauri-plugin-store-api:
|
tauri-plugin-store-api:
|
||||||
specifier: github:tauri-apps/tauri-plugin-store
|
specifier: github:tauri-apps/tauri-plugin-store
|
||||||
version: github.com/tauri-apps/tauri-plugin-store/df267506bf12de451762f3f4b7f929ebed1421c9
|
version: github.com/tauri-apps/tauri-plugin-store/f4ef29684e4a32eddf51befaae98a5e498df8574
|
||||||
theme-vitesse:
|
theme-vitesse:
|
||||||
specifier: ^0.6.4
|
specifier: ^0.6.4
|
||||||
version: 0.6.4
|
version: 0.6.4
|
||||||
|
@ -256,6 +256,9 @@ importers:
|
||||||
'@types/wicg-file-system-access':
|
'@types/wicg-file-system-access':
|
||||||
specifier: ^2020.9.6
|
specifier: ^2020.9.6
|
||||||
version: 2020.9.6
|
version: 2020.9.6
|
||||||
|
'@unlazy/nuxt':
|
||||||
|
specifier: ^0.8.8
|
||||||
|
version: 0.8.8(fast-blurhash@1.1.2)(rollup@2.79.1)(thumbhash@0.1.1)
|
||||||
bumpp:
|
bumpp:
|
||||||
specifier: ^9.1.0
|
specifier: ^9.1.0
|
||||||
version: 9.1.0
|
version: 9.1.0
|
||||||
|
@ -3859,6 +3862,26 @@ packages:
|
||||||
unhead: 1.1.26
|
unhead: 1.1.26
|
||||||
vue: 3.2.45
|
vue: 3.2.45
|
||||||
|
|
||||||
|
/@unlazy/core@0.8.8:
|
||||||
|
resolution: {integrity: sha512-V1QBPCF9IN8PK4d9uxl3fcQEndmqu47kOH7Ai7/Lj98Nuobnjv8K9xJfXfwqGkPcYfVBcFKvnwA3Z41XWLcd0Q==}
|
||||||
|
dependencies:
|
||||||
|
fast-blurhash: 1.1.2
|
||||||
|
thumbhash: 0.1.1
|
||||||
|
dev: true
|
||||||
|
|
||||||
|
/@unlazy/nuxt@0.8.8(fast-blurhash@1.1.2)(rollup@2.79.1)(thumbhash@0.1.1):
|
||||||
|
resolution: {integrity: sha512-Osb6RHNGYLFHJ3Ib0XKpCwFLpodWUJWd5QA2kk4iR+vfU+3fIxXYFbcX3zG7sFLUIBN9n+NuNY2CuIAJV4BJqQ==}
|
||||||
|
dependencies:
|
||||||
|
'@nuxt/kit': 3.4.2(rollup@2.79.1)
|
||||||
|
defu: 6.1.2
|
||||||
|
unlazy: 0.8.8(fast-blurhash@1.1.2)(thumbhash@0.1.1)
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- fast-blurhash
|
||||||
|
- rollup
|
||||||
|
- supports-color
|
||||||
|
- thumbhash
|
||||||
|
dev: true
|
||||||
|
|
||||||
/@unocss/astro@0.51.4(rollup@2.79.1)(vite@4.3.1):
|
/@unocss/astro@0.51.4(rollup@2.79.1)(vite@4.3.1):
|
||||||
resolution: {integrity: sha512-denp8/PHvzfN9azfTF72+ey6xpgUB4L4416FI4DfcfKPzRMo4KjIaHlTD6xuaJwBdC8UJSOIcDRXldRGPT33Ag==}
|
resolution: {integrity: sha512-denp8/PHvzfN9azfTF72+ey6xpgUB4L4416FI4DfcfKPzRMo4KjIaHlTD6xuaJwBdC8UJSOIcDRXldRGPT33Ag==}
|
||||||
dependencies:
|
dependencies:
|
||||||
|
@ -7303,6 +7326,10 @@ packages:
|
||||||
pathe: 1.1.0
|
pathe: 1.1.0
|
||||||
ufo: 1.1.1
|
ufo: 1.1.1
|
||||||
|
|
||||||
|
/fast-blurhash@1.1.2:
|
||||||
|
resolution: {integrity: sha512-lJVOgYSlahqkRhrKumNx/SGB2F/qS0D1z7xjGYjb5EZJRtlzySGMniZjkQ9h9Rv8sPmM/V9orEgRiMwazDNH6A==}
|
||||||
|
dev: true
|
||||||
|
|
||||||
/fast-deep-equal@3.1.3:
|
/fast-deep-equal@3.1.3:
|
||||||
resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
|
resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
|
||||||
|
|
||||||
|
@ -12459,6 +12486,10 @@ packages:
|
||||||
/through@2.3.8:
|
/through@2.3.8:
|
||||||
resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==}
|
resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==}
|
||||||
|
|
||||||
|
/thumbhash@0.1.1:
|
||||||
|
resolution: {integrity: sha512-kH5pKeIIBPQXAOni2AiY/Cu/NKdkFREdpH+TLdM0g6WA7RriCv0kPLgP731ady67MhTAqrVG/4mnEeibVuCJcg==}
|
||||||
|
dev: true
|
||||||
|
|
||||||
/time-zone@1.0.0:
|
/time-zone@1.0.0:
|
||||||
resolution: {integrity: sha512-TIsDdtKo6+XrPtiTm1ssmMngN1sAhyKnTO2kunQWqNPWIVvCm15Wmw4SWInwTVgJ5u/Tr04+8Ei9TNcw4x4ONA==}
|
resolution: {integrity: sha512-TIsDdtKo6+XrPtiTm1ssmMngN1sAhyKnTO2kunQWqNPWIVvCm15Wmw4SWInwTVgJ5u/Tr04+8Ei9TNcw4x4ONA==}
|
||||||
engines: {node: '>=4'}
|
engines: {node: '>=4'}
|
||||||
|
@ -12930,6 +12961,17 @@ packages:
|
||||||
resolution: {integrity: sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==}
|
resolution: {integrity: sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==}
|
||||||
engines: {node: '>= 10.0.0'}
|
engines: {node: '>= 10.0.0'}
|
||||||
|
|
||||||
|
/unlazy@0.8.8(fast-blurhash@1.1.2)(thumbhash@0.1.1):
|
||||||
|
resolution: {integrity: sha512-7wro4wypXPr2WurVcuapEYwju9YXkJP9fHT2SgK5e0aegmuGL/M6wPaZNFQMzfMUCiFb5NODxW9lykq7ymOEog==}
|
||||||
|
peerDependencies:
|
||||||
|
fast-blurhash: ^1.1.2
|
||||||
|
thumbhash: ^0.1.1
|
||||||
|
dependencies:
|
||||||
|
'@unlazy/core': 0.8.8
|
||||||
|
fast-blurhash: 1.1.2
|
||||||
|
thumbhash: 0.1.1
|
||||||
|
dev: true
|
||||||
|
|
||||||
/unocss@0.51.4(@unocss/webpack@0.51.4)(postcss@8.4.23)(rollup@2.79.1)(vite@4.3.1):
|
/unocss@0.51.4(@unocss/webpack@0.51.4)(postcss@8.4.23)(rollup@2.79.1)(vite@4.3.1):
|
||||||
resolution: {integrity: sha512-84kRoL29Rk0AKdeS2GGZ+YduW5F0S2on3cSxA2Hh1KlI4MN8Xvxa8+f4RfFS0U5iH4yoHohvcWThRgjDhOWSeg==}
|
resolution: {integrity: sha512-84kRoL29Rk0AKdeS2GGZ+YduW5F0S2on3cSxA2Hh1KlI4MN8Xvxa8+f4RfFS0U5iH4yoHohvcWThRgjDhOWSeg==}
|
||||||
engines: {node: '>=14'}
|
engines: {node: '>=14'}
|
||||||
|
@ -14185,16 +14227,16 @@ packages:
|
||||||
resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==}
|
resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
github.com/tauri-apps/tauri-plugin-log/36100c269e33ac91246b0a4bfadd18c1caee5296:
|
github.com/tauri-apps/tauri-plugin-log/782a97aeb30cf0f54355d04e6026842fa420bd83:
|
||||||
resolution: {tarball: https://codeload.github.com/tauri-apps/tauri-plugin-log/tar.gz/36100c269e33ac91246b0a4bfadd18c1caee5296}
|
resolution: {tarball: https://codeload.github.com/tauri-apps/tauri-plugin-log/tar.gz/782a97aeb30cf0f54355d04e6026842fa420bd83}
|
||||||
name: tauri-plugin-log-api
|
name: tauri-plugin-log-api
|
||||||
version: 0.0.0
|
version: 0.0.0
|
||||||
dependencies:
|
dependencies:
|
||||||
'@tauri-apps/api': 1.2.0
|
'@tauri-apps/api': 1.2.0
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
github.com/tauri-apps/tauri-plugin-store/df267506bf12de451762f3f4b7f929ebed1421c9:
|
github.com/tauri-apps/tauri-plugin-store/f4ef29684e4a32eddf51befaae98a5e498df8574:
|
||||||
resolution: {tarball: https://codeload.github.com/tauri-apps/tauri-plugin-store/tar.gz/df267506bf12de451762f3f4b7f929ebed1421c9}
|
resolution: {tarball: https://codeload.github.com/tauri-apps/tauri-plugin-store/tar.gz/f4ef29684e4a32eddf51befaae98a5e498df8574}
|
||||||
name: tauri-plugin-store-api
|
name: tauri-plugin-store-api
|
||||||
version: 0.0.0
|
version: 0.0.0
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|
Loading…
Reference in New Issue