Skip to content

Commit

Permalink
perf: add virtual-scroller for timeline component
Browse files Browse the repository at this point in the history
  • Loading branch information
webfansplz committed Mar 20, 2024
1 parent ac59853 commit 672bf5e
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 8 deletions.
3 changes: 2 additions & 1 deletion packages/applet/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@
"@vue/devtools-shared": "workspace:^",
"@vue/devtools-ui": "workspace:^",
"perfect-debounce": "^1.0.0",
"splitpanes": "^3.1.5"
"splitpanes": "^3.1.5",
"vue-virtual-scroller": "2.0.0-beta.8"
},
"devDependencies": {
"unplugin-vue": "^5.0.5",
Expand Down
26 changes: 19 additions & 7 deletions packages/applet/src/pinia/components/timeline/EventList.vue
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
<script setup lang="ts">
import type { TimelineEvent } from '@vue/devtools-kit'
import { computed } from 'vue'
import { RecycleScroller } from 'vue-virtual-scroller'
import { formatTime } from '~/utils'
import 'vue-virtual-scroller/dist/vue-virtual-scroller.css'
const props = defineProps<{
data: Array<TimelineEvent['event'] & { color?: string }>
data: Array<TimelineEvent['event'] & { color?: string, id?: number }>
}>()
const selected = defineModel()
Expand All @@ -13,12 +15,13 @@ const colors = ['#3e5770', '#42b983', '#0098c4']
const normalizedData = computed(() => {
let currentColorIndex = -1
let currentGroupId = 0
props.data.forEach((item) => {
props.data.forEach((item, index) => {
if (item.groupId !== currentGroupId || currentColorIndex === -1)
currentColorIndex = (currentColorIndex + 1) % colors.length
currentGroupId = item.groupId ?? currentGroupId
item.id = index
item.color = colors[currentColorIndex]
})
return props.data
Expand All @@ -27,19 +30,28 @@ const normalizedData = computed(() => {

<template>
<div class="p3">
<ul>
<li v-for="(item, index) in normalizedData" :key="index" class="relative mb7 h6 cursor-pointer" :style="{ color: selected === index ? item.color : '' }" @click="selected = index">
<RecycleScroller
v-slot="{ item }"
:items="normalizedData"
:min-item-size="52"
key-field="id"
page-mode
item-tag="li"
list-tag="ul"
:buffer="20"
>
<div class="relative mb7 h6 cursor-pointer" :style="{ color: selected === item.id ? item.color : '' }" @click="selected = item.id">
<!-- head -->
<span class="absolute top-1.5 inline-block h3 w3 b rounded-50%" :style="{ border: `3px solid ${item.color}` }" />
<!-- line -->
<span v-if="index < data.length - 1" class="absolute left-5px top-4.5 h10 w0 border-l-2" border="solid gray2" />
<span v-if="item.id < data.length - 1" class="absolute left-5px top-4.5 h10 w0 border-l-2" border="solid gray2" />
<!-- content -->
<p class="h-full flex items-center truncate pl5">
<span absolute top-5 pr2 text-3 op40>[{{ formatTime(item.time) }}]</span>
{{ item.title }}
<span pl2 op30>{{ item.subtitle }}</span>
</p>
</li>
</ul>
</div>
</RecycleScroller>
</div>
</template>
3 changes: 3 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 672bf5e

Please sign in to comment.