Performance fixes

This commit is contained in:
wvffle 2022-07-24 23:43:40 +00:00 committed by Georg Krause
parent 29afac3101
commit d1b8190dca
5 changed files with 68 additions and 48 deletions

View File

@ -44,6 +44,7 @@
"vue-router": "4.1.2",
"vue-tsc": "0.38.9",
"vue-upload-component": "3.1.2",
"vue-virtual-scroller": "^2.0.0-alpha.1",
"vue3-gettext": "2.3.0",
"vue3-lazyload": "0.3.5",
"vue3-virtual-scroll-list": "0.2.0",
@ -61,6 +62,7 @@
"@types/qs": "6.9.7",
"@types/semantic-ui": "2.2.7",
"@types/showdown": "2.0.0",
"@types/vue-virtual-scroller": "npm:@earltp/vue-virtual-scroller",
"@typescript-eslint/eslint-plugin": "5.30.7",
"@vitejs/plugin-vue": "3.0.1",
"@vue/compiler-sfc": "3.2.37",

View File

@ -387,12 +387,19 @@ const reorderTracks = async (from: number, to: number) => {
:list="queueItems"
:component="QueueItem"
:size="50"
:item-class="(index: number) => currentIndex === index ? 'active': ''"
data-key="id"
@play="play"
@remove="removeTrack"
@reorder="reorderTracks"
/>
>
<template #default="{ index, item, classList }">
<queue-item
:data-index="index"
:index="index"
:source="item"
:class="[...classList, currentIndex === index && 'active']"
@play="play"
@remove="removeTrack"
/>
</template>
</virtual-list>
<div
v-if="$store.state.radios.running"
class="ui info message"

View File

@ -4,7 +4,6 @@ import type { QueueItemSource } from '~/types'
interface Props {
source: QueueItemSource
index: number
itemClass: (index: number) => string
}
interface Emits {
@ -18,7 +17,6 @@ defineEmits<Emits>()
<template>
<div
:class="itemClass(index)"
class="queue-item"
tabindex="0"
>

View File

@ -4,9 +4,10 @@ import type { MaybeElementRef, MaybeElement } from '@vueuse/core'
import { useMouse, useCurrentElement, useResizeObserver, useRafFn, useElementByPoint } from '@vueuse/core'
import { ref, watchEffect, reactive } from 'vue'
import VirtualItem from './VirtualItem.vue'
// @ts-expect-error no typings
import VirtualList from 'vue3-virtual-scroll-list'
// import VirtualList from 'vue3-virtual-scroll-list'
import { RecycleScroller } from 'vue-virtual-scroller'
import 'vue-virtual-scroller/dist/vue-virtual-scroller.css'
interface Emits {
(e: 'reorder', from: number, to: number): void
@ -15,7 +16,6 @@ interface Emits {
interface Props {
list: object[]
size: number
dataKey: string
}
const emit = defineEmits<Emits>()
@ -31,7 +31,7 @@ const getIndex = (element: HTMLElement) => +(element?.getAttribute('data-index')
const isTouch = ref(false)
const onMousedown = (event: MouseEvent | TouchEvent) => {
const element = event.target as HTMLElement
const dragItem = element.closest('.drag-item')?.children[0] as HTMLElement
const dragItem = element.closest('.drag-item') as HTMLElement
if (!dragItem || !element.classList.contains('handle')) return
// Touch devices stop emitting touch events while container is scrolled
@ -68,10 +68,7 @@ document.addEventListener('touchcancel', (event: TouchEvent) => {
})
const reorder = (event: MouseEvent | TouchEvent) => {
const element = event.target as HTMLElement
const dragItem = element.closest('.drag-item')?.children[0]
if (dragItem && draggedItem.value) {
if (draggedItem.value) {
const from = draggedItem.value.index
let to = hoveredIndex.value
@ -98,10 +95,6 @@ const cleanup = () => {
scrollDirection.value = undefined
}
const dragClassHandler = (index: number) => draggedItem.value && hoveredIndex.value === index
? `drop-${position.value}`
: ''
const scrollDirection = ref()
const containerSize = reactive({ bottom: 0, top: 0 })
const { x, y: screenY } = useMouse({ type: 'client' })
@ -109,12 +102,14 @@ const { element: hoveredElement } = useElementByPoint({ x, y: screenY })
// Find current index and position on both desktop and mobile devices
watchEffect(() => {
const dragItem = (hoveredElement.value as HTMLElement)?.closest('.drag-item')?.children[0] as HTMLElement
if (!dragItem) return
if (draggedItem.value) {
const dragItem = (hoveredElement.value as HTMLElement)?.closest('.drag-item') as HTMLElement
if (!dragItem) return
hoveredIndex.value = getIndex(dragItem)
const { y } = dragItem.getBoundingClientRect()
position.value = screenY.value - y < props.size / 2 ? 'before' : 'after'
hoveredIndex.value = getIndex(dragItem)
const { y } = dragItem.getBoundingClientRect()
position.value = screenY.value - y < props.size / 2 ? 'before' : 'after'
}
})
// Automatically scroll when on the edge
@ -137,7 +132,6 @@ watchEffect(() => {
scrollDirection.value = undefined
})
const keeps = ref(30)
const el = useCurrentElement()
useResizeObserver(el as unknown as MaybeElementRef<MaybeElement>, ([entry]) => {
const height = entry.borderBoxSize?.[0]?.blockSize ?? 0
@ -145,7 +139,6 @@ useResizeObserver(el as unknown as MaybeElementRef<MaybeElement>, ([entry]) => {
if (height !== 0) {
containerSize.top = (entry.target as HTMLElement).offsetTop
containerSize.bottom = height + containerSize.top
keeps.value = (containerSize.bottom - containerSize.top) / props.size * 2 | 0
}
})
@ -164,38 +157,29 @@ const { resume, pause } = useRafFn(() => {
const virtualList = ref()
defineExpose({
scrollToIndex: (index: number) => virtualList.value?.scrollToIndex(index),
scrollToIndex: (index: number) => virtualList.value?.scrollToItem(index),
cleanup
})
</script>
<script lang="ts">
export default {
inheritAttrs: false
}
</script>
<template>
<div>
<component
:is="VirtualList"
<recycle-scroller
ref="virtualList"
class="virtual-list"
wrap-class="drag-container"
item-class="drag-item"
:keeps="keeps"
:data-key="dataKey"
:data-sources="list"
:data-component="VirtualItem"
:estimate-size="size"
:extra-props="{
dragClassHandler,
...$attrs
}"
v-slot="{ item, index }"
class="virtual-list drag-container"
:items="list"
:item-size="size"
@mousedown="onMousedown"
@touchstart="onMousedown"
@touchmove="onTouchmove"
/>
>
<slot
:class-list="[draggedItem && hoveredIndex === index && `drop-${position}`, 'drag-item']"
:item="item"
:index="index"
/>
</recycle-scroller>
<div
ref="ghostContainer"

View File

@ -1689,6 +1689,11 @@
resolved "https://registry.yarnpkg.com/@types/trusted-types/-/trusted-types-2.0.2.tgz#fc25ad9943bcac11cceb8168db4f275e0e72e756"
integrity sha512-F5DIZ36YVLE+PN+Zwws4kJogq47hNgX3Nx6WyDJ3kcplxyke3XIzB8uK5n/Lpm1HBsbGzd6nmGehL8cPekP+Tg==
"@types/vue-virtual-scroller@npm:@earltp/vue-virtual-scroller":
version "1.0.1"
resolved "https://registry.yarnpkg.com/@earltp/vue-virtual-scroller/-/vue-virtual-scroller-1.0.1.tgz#75116ef9b091457a654d92ff0688e991b3cd9e8a"
integrity sha512-7UsmP2JALnkfWlheuWRDywuBUTLJcVPE86X5ogA3djUmYFybE6qximgQ7OgyJnrKLteWR7+1Cp0GUXHhdDKaDQ==
"@types/web-bluetooth@^0.0.14":
version "0.0.14"
resolved "https://registry.yarnpkg.com/@types/web-bluetooth/-/web-bluetooth-0.0.14.tgz#94e175b53623384bff1f354cdb3197a8d63cdbe5"
@ -5076,6 +5081,11 @@ minimist@^1.2.0, minimist@^1.2.5, minimist@^1.2.6:
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44"
integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==
mitt@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/mitt/-/mitt-2.1.0.tgz#f740577c23176c6205b121b2973514eade1b2230"
integrity sha512-ILj2TpLiysu2wkBbWjAmww7TkZb65aiQO+DkVdUTBpBXq+MHYiETENkKFMtsJZX1Lf4pe4QOrTSjIfUwN5lRdg==
moment@2.29.4:
version "2.29.4"
resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.4.tgz#3dbe052889fe7c1b2ed966fcb3a77328964ef108"
@ -6479,6 +6489,11 @@ vue-jest@3.0.7:
tsconfig "^7.0.0"
vue-template-es2015-compiler "^1.6.0"
vue-observe-visibility@^2.0.0-alpha.1:
version "2.0.0-alpha.1"
resolved "https://registry.yarnpkg.com/vue-observe-visibility/-/vue-observe-visibility-2.0.0-alpha.1.tgz#1e4eda7b12562161d58984b7e0dea676d83bdb13"
integrity sha512-flFbp/gs9pZniXR6fans8smv1kDScJ8RS7rEpMjhVabiKeq7Qz3D9+eGsypncjfIyyU84saU88XZ0zjbD6Gq/g==
vue-plyr@7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/vue-plyr/-/vue-plyr-7.0.0.tgz#938257e2a4def4582b5803a16087371a8e96209e"
@ -6487,6 +6502,11 @@ vue-plyr@7.0.0:
plyr "github:sampotts/plyr#develop"
vue "^2.6.12"
vue-resize@^2.0.0-alpha.1:
version "2.0.0-alpha.1"
resolved "https://registry.yarnpkg.com/vue-resize/-/vue-resize-2.0.0-alpha.1.tgz#43eeb79e74febe932b9b20c5c57e0ebc14e2df3a"
integrity sha512-7+iqOueLU7uc9NrMfrzbG8hwMqchfVfSzpVlCMeJQe4pyibqyoifDNbKTZvwxZKDvGkB+PdFeKvnGZMoEb8esg==
vue-router@4.1.2:
version "4.1.2"
resolved "https://registry.yarnpkg.com/vue-router/-/vue-router-4.1.2.tgz#ae08f63c9610afa6bff6743e8f128b7054d4c9f5"
@ -6511,6 +6531,15 @@ vue-upload-component@3.1.2:
resolved "https://registry.yarnpkg.com/vue-upload-component/-/vue-upload-component-3.1.2.tgz#9ba050f408781b008a16cb8bfaadbcf07eab68fa"
integrity sha512-z7/98xhNbLecTf09ZyJp0QKH6RMoVH3ojBrWYonPPHQ6qodQf0qVV81+vnB94cFVWpR/mb+F+dMN2p04K14ouw==
vue-virtual-scroller@^2.0.0-alpha.1:
version "2.0.0-alpha.1"
resolved "https://registry.yarnpkg.com/vue-virtual-scroller/-/vue-virtual-scroller-2.0.0-alpha.1.tgz#5b5410105b8e60ca57bbd5f2faf5ad1d8108d046"
integrity sha512-Mn5w3Qe06t7c3Imm2RHD43RACab1CCWplpdgzq+/FWJcpQtcGKd5vDep8i+nIwFtzFLsWAqEK0RzM7KrfAcBng==
dependencies:
mitt "^2.1.0"
vue-observe-visibility "^2.0.0-alpha.1"
vue-resize "^2.0.0-alpha.1"
vue3-gettext@2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/vue3-gettext/-/vue3-gettext-2.3.0.tgz#5825949e3978aa576e035128de46c97e59b65a5b"