wip: review work

This commit is contained in:
tbitw2549 2024-06-14 18:31:21 +03:00
parent 23d0b8e4c8
commit 8c522836ed
3 changed files with 83 additions and 52 deletions

View File

@ -14,7 +14,7 @@ import { onNuxtReady } from '../composables/ready'
import { navigateTo, useRouter } from '../composables/router'
import { useNuxtApp, useRuntimeConfig } from '../nuxt'
import { cancelIdleCallback, requestIdleCallback } from '../compat/idle-callback'
import { useObserver } from '../utils'
import type { ObserveFn, CallbackFn } from '../utils'
// @ts-expect-error virtual file
import { nuxtLinkDefaults } from '#build/nuxt.config.mjs'
@ -437,6 +437,47 @@ function applyTrailingSlashBehavior (to: string, trailingSlash: NuxtLinkOptions[
// --- Prefetching utils ---
function useObserver (): { observe: ObserveFn } | undefined {
if (import.meta.server) { return }
const nuxtApp = useNuxtApp()
if (nuxtApp._observer) {
return nuxtApp._observer
}
let observer: IntersectionObserver | null = null
const callbacks = new Map<Element, CallbackFn>()
const observe: ObserveFn = (element, callback) => {
if (!observer) {
observer = new IntersectionObserver((entries) => {
for (const entry of entries) {
const callback = callbacks.get(entry.target)
const isVisible = entry.isIntersecting || entry.intersectionRatio > 0
if (isVisible && callback) { callback() }
}
})
}
callbacks.set(element, callback)
observer.observe(element)
return () => {
callbacks.delete(element)
observer!.unobserve(element)
if (callbacks.size === 0) {
observer!.disconnect()
observer = null
}
}
}
const _observer = nuxtApp._observer = {
observe
}
return _observer
}
function isSlowConnection () {
if (import.meta.server) { return }

View File

@ -1,49 +1,6 @@
import { useNuxtApp } from './nuxt'
export function toArray<T> (value: T | T[]): T[] {
return Array.isArray(value) ? value : [value]
}
type CallbackFn = () => void
type ObserveFn = (element: Element, callback: CallbackFn) => () => void
export function useObserver (): { observe: ObserveFn } | undefined {
if (import.meta.server) { return }
const nuxtApp = useNuxtApp()
if (nuxtApp._observer) {
return nuxtApp._observer
}
let observer: IntersectionObserver | null = null
const callbacks = new Map<Element, CallbackFn>()
const observe: ObserveFn = (element, callback) => {
if (!observer) {
observer = new IntersectionObserver((entries) => {
for (const entry of entries) {
const callback = callbacks.get(entry.target)
const isVisible = entry.isIntersecting || entry.intersectionRatio > 0
if (isVisible && callback) { callback() }
}
})
}
callbacks.set(element, callback)
observer.observe(element)
return () => {
callbacks.delete(element)
observer!.unobserve(element)
if (callbacks.size === 0) {
observer!.disconnect()
observer = null
}
}
}
const _observer = nuxtApp._observer = {
observe,
}
return _observer
}
export type CallbackFn = () => void
export type ObserveFn = (element: Element, callback: CallbackFn) => () => void

View File

@ -1,9 +1,40 @@
import { createStaticVNode, createVNode, defineComponent, getCurrentInstance, h, onBeforeUnmount, onMounted, ref } from 'vue'
import type { Component, Ref } from 'vue'
// import ClientOnly from '#app/components/client-only'
import { useObserver } from '#app/utils'
import type { ObserveFn } from '#app/utils'
import { getFragmentHTML } from '#app/components/utils'
import { useNuxtApp } from '#app/nuxt'
import { requestIdleCallback, cancelIdleCallback } from '#app/compat/idle-callback'
import { onNuxtReady } from '#app'
function useIntersectionObserver(options: IntersectionObserverInit) : {observe: ObserveFn} {
if (import.meta.server) { return {observe: () => () => {}}}
let observer: IntersectionObserver | null = null
const observe: ObserveFn = (element, callback) => {
if (!observer) {
observer = new IntersectionObserver((entries) => {
for (const entry of entries) {
const isVisible = entry.isIntersecting || entry.intersectionRatio > 0
if (isVisible && callback) { callback() }
}
}, options)
}
observer.observe(element)
return () => {
observer!.unobserve(element)
observer!.disconnect()
observer = null
}
}
const _observer = {
observe
}
return _observer
}
function elementIsVisibleInViewport (el: Element) {
const { top, left, bottom, right } = el.getBoundingClientRect()
@ -35,7 +66,7 @@ export const createLazyIOClientPage = (componentLoader: Component) => {
if (!isIntersecting.value) {
onMounted(() => {
const observer = useObserver()
const observer = useIntersectionObserver(attrs.loader ?? {})
unobserve = observer!.observe(el.value as Element, () => {
isIntersecting.value = true
unobserve?.()
@ -69,10 +100,12 @@ export const createLazyNetworkClientPage = (componentLoader: Component) => {
const isIdle = ref(false)
let idleHandle: number | null = null
onMounted(() => {
idleHandle = requestIdleCallback(() => {
isIdle.value = true
cancelIdleCallback(idleHandle as unknown as number)
idleHandle = null
onNuxtReady(()=>{
idleHandle = requestIdleCallback(() => {
isIdle.value = true
cancelIdleCallback(idleHandle as unknown as number)
idleHandle = null
}, attrs.loader ?? {timeout: 10000})
})
})
onBeforeUnmount(() => {