feat: lazy load images (#1969)

zio/stable
Shinigami 2023-04-26 22:46:00 +02:00 committed by GitHub
parent 1ceb3e2857
commit 23c1dfec10
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 57 additions and 48 deletions

View File

@ -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>

View File

@ -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"

View File

@ -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 {

View File

@ -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",

View File

@ -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: