perf: 大页面量体验优化(#68)

This commit is contained in:
pipipi-pikachu 2021-12-05 11:16:23 +08:00
parent 85bab19b12
commit c9fab09d02
5 changed files with 60 additions and 3 deletions

View File

@ -0,0 +1,30 @@
import { ref, onMounted, onUnmounted } from 'vue'
import { storeToRefs } from 'pinia'
import { useSlidesStore } from '@/store'
export default () => {
const { slides } = storeToRefs(useSlidesStore())
const timer = ref<number | null>(null)
const slidesLoadLimit = ref(50)
const loadSlide = () => {
if (slides.value.length > slidesLoadLimit.value) {
timer.value = setTimeout(() => {
slidesLoadLimit.value = slidesLoadLimit.value + 20
loadSlide()
}, 600)
}
else slidesLoadLimit.value = 9999
}
onMounted(loadSlide)
onUnmounted(() => {
if (timer.value) clearTimeout(timer.value)
})
return {
slidesLoadLimit,
}
}

View File

@ -35,8 +35,8 @@
@mousedown="$event => handleClickSlideThumbnail($event, index)"
v-contextmenu="contextmenusThumbnailItem"
>
<div class="label">{{ fillDigit(index + 1, 2) }}</div>
<ThumbnailSlide class="thumbnail" :slide="element" :size="120" />
<div class="label" :class="{ 'offset-left': index >= 99 }">{{ fillDigit(index + 1, 2) }}</div>
<ThumbnailSlide class="thumbnail" :slide="element" :size="120" :visible="index < slidesLoadLimit" />
</div>
</template>
</Draggable>
@ -52,6 +52,7 @@ import { ContextmenuItem } from '@/components/Contextmenu/types'
import { VIEWPORT_SIZE } from '@/configs/canvas'
import useSlideHandler from '@/hooks/useSlideHandler'
import useScreening from '@/hooks/useScreening'
import useLoadSlides from '@/hooks/useLoadSlides'
import Draggable from 'vuedraggable'
import ThumbnailSlide from '@/views/components/ThumbnailSlide/index.vue'
@ -72,6 +73,8 @@ export default defineComponent({
const { slides, slideIndex } = storeToRefs(slidesStore)
const { ctrlKeyState, shiftKeyState } = storeToRefs(keyboardStore)
const { slidesLoadLimit } = useLoadSlides()
const selectedSlidesIndex = computed(() => [..._selectedSlidesIndex.value, slideIndex.value])
const presetLayoutPopoverVisible = ref(false)
@ -249,6 +252,7 @@ export default defineComponent({
slideIndex,
selectedSlidesIndex,
presetLayoutPopoverVisible,
slidesLoadLimit,
createSlide,
createSlideByTemplate,
setThumbnailsFocus,
@ -340,6 +344,11 @@ export default defineComponent({
width: 20px;
cursor: grab;
&.offset-left {
position: relative;
left: -4px;
}
&:active {
cursor: grabbing;
}

View File

@ -11,7 +11,7 @@
:key="slide.id"
@click="turnSlideToIndex(index)"
>
<ThumbnailSlide :slide="slide" :size="150" />
<ThumbnailSlide :slide="slide" :size="150" :visible="index < slidesLoadLimit" />
</div>
</div>
</div>
@ -21,6 +21,7 @@
import { defineComponent, PropType } from 'vue'
import { storeToRefs } from 'pinia'
import { useSlidesStore } from '@/store'
import useLoadSlides from '@/hooks/useLoadSlides'
import ThumbnailSlide from '@/views/components/ThumbnailSlide/index.vue'
@ -38,11 +39,14 @@ export default defineComponent({
setup(props, { emit }) {
const { slides, slideIndex } = storeToRefs(useSlidesStore())
const { slidesLoadLimit } = useLoadSlides()
const close = () => emit('close')
return {
slides,
slideIndex,
slidesLoadLimit,
close,
}
},

View File

@ -27,6 +27,7 @@
width: slideWidth + 'px',
height: slideHeight + 'px',
}"
v-if="Math.abs(slideIndex - index) < 2"
>
<ScreenSlide
:slide="slide"

View File

@ -12,6 +12,7 @@
height: VIEWPORT_SIZE * viewportRatio + 'px',
transform: `scale(${scale})`,
}"
v-if="visible"
>
<div class="background" :style="backgroundStyle"></div>
<ThumbnailElement
@ -21,6 +22,7 @@
:elementIndex="index + 1"
/>
</div>
<div class="placeholder" v-else>加载中 ...</div>
</div>
</template>
@ -48,6 +50,10 @@ export default defineComponent({
type: Number,
required: true,
},
visible: {
type: Boolean,
default: true,
},
},
setup(props) {
const { viewportRatio } = storeToRefs(useSlidesStore())
@ -81,4 +87,11 @@ export default defineComponent({
background-position: center;
position: absolute;
}
.placeholder {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
</style>