diff --git a/vite-tailwindcss/src/components/PhotoGallery.vue b/vite-tailwindcss/src/components/PhotoGallery.vue
index db085c4..3fc37dd 100644
--- a/vite-tailwindcss/src/components/PhotoGallery.vue
+++ b/vite-tailwindcss/src/components/PhotoGallery.vue
@@ -38,19 +38,27 @@
-
+
-
-
-
![]()
+
+
+
-
-
-
-
+
@@ -92,7 +100,9 @@
import { ref, computed, watch, nextTick } from 'vue'
import { borderClass } from '@/composables/borderStyles'
-const DECODE_TIMEOUT_MS = 4000
+const BATCH_SIZE = 3
+const BATCH_GAP_MS = 140
+const BATCH_DECODE_TIMEOUT_MS = 2500
const props = defineProps({
page: { type: Object, required: true },
@@ -102,37 +112,65 @@ const props = defineProps({
const emit = defineEmits(['preview-image', 'ready'])
const nineGridRef = ref(null)
+const nineShownCount = ref(0)
let readyEmitted = false
const frameClass = computed(() => borderClass(props.page.borderStyle))
-const waitImagesReady = async () => {
- await nextTick()
- const root = nineGridRef.value
- if (!root) return
- const imgs = [...root.querySelectorAll('img[src]')]
- if (!imgs.length) return
- const decodeAll = Promise.allSettled(
- imgs.map((img) => {
- if (typeof img.decode === 'function') return img.decode().catch(() => {})
- if (img.complete) return Promise.resolve()
- return new Promise((resolve) => {
- img.addEventListener('load', resolve, { once: true })
- img.addEventListener('error', resolve, { once: true })
- })
- })
- )
- await Promise.race([
- decodeAll,
- new Promise((resolve) => setTimeout(resolve, DECODE_TIMEOUT_MS)),
- ])
+const decodeImg = (img) => {
+ if (!img) return Promise.resolve()
+ if (typeof img.decode === 'function') return img.decode().catch(() => {})
+ if (img.complete) return Promise.resolve()
+ return new Promise((resolve) => {
+ img.addEventListener('load', resolve, { once: true })
+ img.addEventListener('error', resolve, { once: true })
+ })
+}
+
+const yieldToMain = () => new Promise((resolve) => {
+ if (typeof requestAnimationFrame === 'function') {
+ requestAnimationFrame(() => resolve())
+ } else {
+ setTimeout(resolve, 0)
+ }
+})
+
+const runBatchedReveal = async () => {
+ const images = props.page.images || []
+ const total = images.length
+ if (!total) return
+
+ for (let start = 0; start < total; start += BATCH_SIZE) {
+ nineShownCount.value = Math.min(total, start + BATCH_SIZE)
+ await nextTick()
+ await yieldToMain()
+
+ const root = nineGridRef.value
+ const end = nineShownCount.value
+ const imgs = root
+ ? [...root.querySelectorAll('img[data-nine-idx]')].filter((el) => {
+ const i = Number(el.getAttribute('data-nine-idx'))
+ return i >= start && i < end
+ })
+ : []
+
+ await Promise.race([
+ Promise.allSettled(imgs.map(decodeImg)),
+ new Promise((resolve) => setTimeout(resolve, BATCH_DECODE_TIMEOUT_MS)),
+ ])
+
+ if (end < total) {
+ await new Promise((resolve) => setTimeout(resolve, BATCH_GAP_MS))
+ await yieldToMain()
+ }
+ }
}
watch(
() => props.activate && props.page?.type === 'nine-grid',
async (on) => {
if (!on || readyEmitted) return
- await waitImagesReady()
+ await runBatchedReveal()
if (readyEmitted) return
readyEmitted = true
emit('ready')
diff --git a/vite-tailwindcss/src/views/index/index.vue b/vite-tailwindcss/src/views/index/index.vue
index 11c6f62..b1418f1 100644
--- a/vite-tailwindcss/src/views/index/index.vue
+++ b/vite-tailwindcss/src/views/index/index.vue
@@ -117,7 +117,7 @@
{{ data.formalText1 }}
{{ data.formalText2 }}
- 见证我们的幸福
+ 见证我们的幸福
诚挚邀请您
@@ -353,7 +353,8 @@ let nineGridRevealTimer = null
const nineGridDone = new Set()
const BOTTOM_RETURN_DELAY = 30000
const FREE_SCROLL_BASE_STEP = 1.2
-const NINE_GRID_REVEAL_HOLD_MS = 900
+/** 分批入场已占时间,收尾再略停一下即可 */
+const NINE_GRID_REVEAL_HOLD_MS = 400
const NINE_GRID_FULL_RATIO = 0.9
const freeInterval = computed(() => {