Skip to content

Commit

Permalink
perf: use VirtualScroller component to optimize performance problems …
Browse files Browse the repository at this point in the history
…caused by large amounts of data (#9)

Co-authored-by: wendraw <[email protected]>
  • Loading branch information
wendraw and wendraw authored May 25, 2024
1 parent 5d24bc9 commit 76f05a9
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 69 deletions.
85 changes: 45 additions & 40 deletions ui/components/RegexDetail.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import type { RegexCall, RegexDoctorResult, RegexInfo } from 'regex-doctor'
import { h } from 'vue'
import { encode } from 'js-base64'
import VirtualScroller from 'primevue/virtualscroller'
const props = defineProps<{
info: RegexInfo
Expand Down Expand Up @@ -68,7 +69,7 @@ const RenderInput = defineComponent({
setup(props) {
return () => h(
'pre',
{},
{ class: 'max-h-136px' },
(props.call.input || []).map(i =>
typeof i === 'number'
? h('div', { style: 'opacity: 0.2' }, `--- ${i} chars truncated ---`)
Expand Down Expand Up @@ -117,57 +118,61 @@ const RenderInput = defineComponent({
</DataField>
</div>
<div grid="~ cols-[2fr_1fr]" min-h-0>
<div v-if="info.callsInfos.length" of-auto>
<div v-if="info.callsInfos.length" of-auto flex="~ col">
<div px4 py2 border="b base">
<span>Top {{ info.callsInfos.length }} Costly Calls</span>
</div>
<div flex="~ col" of-auto>
<div v-for="callInfo, idx of info.callsInfos" :key="idx" border="b base" p4 flex="~ gap-2">
<div w-45 grid="~ cols-[max-content_1fr] gap-1 items-center" flex-none h-max>
<div i-ph-timer-duotone op50 />
<DurationDisplay :ms="callInfo.duration" />
<div flex="~ col 1">
<VirtualScroller :items="info.callsInfos" :item-size="179" style="height: 100%">
<template #item="{ item: callInfo }">
<div flex="~ gap-2" border="b base" p4>
<div w-45 grid="~ cols-[max-content_1fr] gap-1 items-center" flex-none h-max>
<div i-ph-timer-duotone op50 />
<DurationDisplay :ms="callInfo.duration" />

<div i-ph-text-align-left-duotone op50 />
<div op50>
<NumberDisplay :number="callInfo.inputLength" /> chars
</div>
<div i-ph-text-align-left-duotone op50 />
<div op50>
<NumberDisplay :number="callInfo.inputLength" /> chars
</div>

<div i-ph-speedometer-duotone op50 flex-shrink-0 />
<div>
<DurationDisplay :ms="callInfo.dpk" /> <span op50 text-sm>/ 1K chars</span>
</div>
<div i-ph-speedometer-duotone op50 flex-shrink-0 />
<div>
<DurationDisplay :ms="callInfo.dpk" /> <span op50 text-sm>/ 1K chars</span>
</div>

<div :class="callInfo.matched ? 'text-green i-ph-check-circle-duotone' : 'text-orange i-ph-x-circle-duotone'" />
<div :class="callInfo.matched ? 'text-green' : 'op50'">
{{ callInfo.matched ? 'Matched' : 'Not matched' }}
</div>
<div :class="callInfo.matched ? 'text-green i-ph-check-circle-duotone' : 'text-orange i-ph-x-circle-duotone'" />
<div :class="callInfo.matched ? 'text-green' : 'op50'">
{{ callInfo.matched ? 'Matched' : 'Not matched' }}
</div>

<template v-if="callInfo.groups">
<div i-ph-brackets-round-duotone op50 />
<div op50>
{{ callInfo.groups }} groups
</div>
</template>
<template v-if="callInfo.groups">
<div i-ph-brackets-round-duotone op50 />
<div op50>
{{ callInfo.groups }} groups
</div>
</template>

<div i-ph-list-magnifying-glass-duotone op50 />
<div>
<div i-ph-list-magnifying-glass-duotone op50 />
<div>
<a
:href="getRegex101Link(callInfo)"
target="_blank" rel="noopener noreferrer"
op50 hover:underline hover:op100
>
Test on Regex101
</a>
</div>
</div>
<a
:href="getRegex101Link(callInfo)"
target="_blank" rel="noopener noreferrer"
op50 hover:underline hover:op100
:href="getRegex101Link(callInfo)" target="_blank" rel="noopener noreferrer"
w-full block bg-gray:5 px2 py1 border="~ base rounded" of-auto font-mono h-max
text-zinc
>
Test on Regex101
<RenderInput :call="callInfo" />
</a>
</div>
</div>
<a
:href="getRegex101Link(callInfo)" target="_blank" rel="noopener noreferrer"
w-full block bg-gray:5 px2 py1 border="~ base rounded" of-auto font-mono h-max
text-zinc
>
<RenderInput :call="callInfo" />
</a>
</div>
</template>
</VirtualScroller>
</div>
</div>
<div border="l base" of-auto>
Expand Down
22 changes: 20 additions & 2 deletions ui/components/RegexTable.vue
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ function showCurrentRegex(info: RegexInfo) {
</script>

<template>
<DataTable :value="filtered.slice(0, 100)" :default-sort-order="-1" data-key="no" table-class="w-full text-right data-table">
<DataTable class="regex-table" :value="filtered" scrollable scroll-height="flex" :virtual-scroller-options="{ itemSize: 36 }" :default-sort-order="-1" data-key="no" table-class="w-full text-right data-table">
<Column field="dynamic" header="Dynamic" header-class="pl4">
<template #body="{ data }">
<PackageNameDisplay v-if="data.dynamic" name="new" />
Expand Down Expand Up @@ -130,7 +130,7 @@ function showCurrentRegex(info: RegexInfo) {
</template>
</Column>

<Column field="filesCalled.length" header="Used in" sortable header-class="pr-4">
<Column field="filesCalled.length" header="Used in" sortable header-class="pr-7!">
<template #body="{ data }">
<div flex="~ gap-1 items-center justify-end">
<Dropdown>
Expand Down Expand Up @@ -176,3 +176,21 @@ function showCurrentRegex(info: RegexInfo) {
</div>
</Dialog>
</template>

<style>
.regex-table,
.regex-table .p-datatable-wrapper {
--uno: h-full;
}
.p-virtualscroller {
position: relative;
overflow: auto;
contain: strict;
transform: translateZ(0);
will-change: scroll-position;
outline: 0 none;
}
.p-datatable-scrollable-table > .p-datatable-thead {
--uno: top-0 z-1 bg-gray/2 backdrop-blur-md;
}
</style>
54 changes: 28 additions & 26 deletions ui/pages/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,33 +6,35 @@ const payload = Object.freeze(await $fetch('/api/payload.json') as RegexDoctorRe
</script>

<template>
<div p4 border="b base rounded">
<div>
<span font-bold>Regex</span><span font-100>Doctor</span> <sup op50>v{{ version }}</sup>
<div h-full flex="~ col">
<div p4 border="b base rounded">
<div>
<span font-bold>Regex</span><span font-100>Doctor</span> <sup op50>v{{ version }}</sup>
</div>
<div v-if="payload.cwd" font-mono text-xs op50>
{{ payload.cwd }}
</div>
</div>
<div v-if="payload.cwd" font-mono text-xs op50>
{{ payload.cwd }}
<div p4 border="b base rounded" grid="~ cols-8">
<DataField title="Unique regexes">
<NumberDisplay :number="payload.countUnique" />
</DataField>
<DataField title="Regex instances">
<NumberDisplay :number="payload.count" />
</DataField>
<DataField title="Regexes with details">
<NumberDisplay :number="payload.regexInfos.length" />
</DataField>
<DataField title="Total regex execution time">
<DurationDisplay :ms="payload.totalExecution" :colorful="false" />
<PercentageDisplay ml1 parens :value="payload.totalExecution / payload.totalDuration" />
</DataField>
<DataField title="Total time of the process">
<DurationDisplay :ms="payload.totalDuration" :colorful="false" />
</DataField>
</div>
<div flex-1>
<RegexTable :payload="payload" />
</div>
</div>
<div p4 border="b base rounded" grid="~ cols-8">
<DataField title="Unique regexes">
<NumberDisplay :number="payload.countUnique" />
</DataField>
<DataField title="Regex instances">
<NumberDisplay :number="payload.count" />
</DataField>
<DataField title="Regexes with details">
<NumberDisplay :number="payload.regexInfos.length" />
</DataField>
<DataField title="Total regex execution time">
<DurationDisplay :ms="payload.totalExecution" :colorful="false" />
<PercentageDisplay ml1 parens :value="payload.totalExecution / payload.totalDuration" />
</DataField>
<DataField title="Total time of the process">
<DurationDisplay :ms="payload.totalDuration" :colorful="false" />
</DataField>
</div>
<div py4>
<RegexTable :payload="payload" />
</div>
</template>
2 changes: 1 addition & 1 deletion ui/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ html:not(.dark) .shiki span {
}

.data-table th {
--uno: p2 text-sm op50 font-normal;
--uno: p2 text-sm op50 font-normal hover-cursor-pointer hover-bg-hover;
}

.data-table tbody tr {
Expand Down

0 comments on commit 76f05a9

Please sign in to comment.