Skip to content

Commit 8e479e1

Browse files
committed
perf: 减少不必要的动画,使用预设的字体大小
1 parent 1d70eff commit 8e479e1

File tree

11 files changed

+99
-87
lines changed

11 files changed

+99
-87
lines changed

src/_locales/cmn-CN.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,8 @@ settings:
287287
home_adaptive_title_auto_size_desc: 根据网格宽度自动调整标题字号
288288
home_adaptive_title_font_size: 标题字号
289289
home_adaptive_title_font_size_desc: 固定的标题字号(像素),开启自适应时不生效
290+
video_card_title_font_size: 标题字号
291+
video_card_title_font_size_desc: 控制视频卡片标题的字号。
290292
video_card_author_font_size: UP 信息字号
291293
video_card_author_font_size_desc: 控制视频卡片上 UP 主昵称的字号。
292294
video_card_meta_font_size: 标签与时间字号

src/_locales/cmn-TW.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,8 @@ settings:
199199
home_adaptive_title_auto_size_desc: 依據網格寬度自動調整標題字級
200200
home_adaptive_title_font_size: 標題字級
201201
home_adaptive_title_font_size_desc: 固定標題字級(像素),開啟自適應時不生效
202+
video_card_title_font_size: 標題字級
203+
video_card_title_font_size_desc: 控制影片卡片標題的字級。
202204
video_card_author_font_size: UP 資訊字級
203205
video_card_author_font_size_desc: 控制影片卡片上 UP 主名稱的字級。
204206
video_card_meta_font_size: 標籤與時間字級

src/_locales/en.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,8 @@ settings:
256256
home_adaptive_title_auto_size_desc: Adjusts title font size based on the grid width
257257
home_adaptive_title_font_size: Title font size
258258
home_adaptive_title_font_size_desc: Fixed title font size (px); disabled when auto is on
259+
video_card_title_font_size: Title Font Size
260+
video_card_title_font_size_desc: Controls the font size of the video card title.
259261
video_card_author_font_size: UP info font size
260262
video_card_author_font_size_desc: Controls the font size for uploader names shown on video cards.
261263
video_card_meta_font_size: Tag & timestamp font size

src/_locales/jyut.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,8 @@ settings:
199199
home_adaptive_title_auto_size_desc: 根據網格闊度自動調整標題字體大小
200200
home_adaptive_title_font_size: 標題字體大小
201201
home_adaptive_title_font_size_desc: 固定標題字體大小(像素),開啟自動時唔生效
202+
video_card_title_font_size: 標題字體大小
203+
video_card_title_font_size_desc: 控制影片卡片標題嘅字體大小。
202204
video_card_author_font_size: UP 資訊字體大小
203205
video_card_author_font_size_desc: 控制影片卡片上 UP 主名稱嘅字體大小。
204206
video_card_meta_font_size: 標籤同時間字體大小

src/components/HorizontalScrollView.vue

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,9 @@ function handleMouseScroll(event: WheelEvent) {
8181
</template>
8282

8383
<style lang="scss" scoped>
84+
/* 简化遮罩渐变:使用3个关键点代替4个,提升性能 */
8485
.scroll-mask {
85-
mask-image: linear-gradient(to right, transparent 0, black 40px, black calc(100% - 40px), transparent 100%);
86-
-webkit-mask-image: linear-gradient(to right, transparent 0, black 40px, black calc(100% - 40px), transparent 100%);
86+
mask-image: linear-gradient(to right, transparent 0, black 40px, transparent 100%);
87+
-webkit-mask-image: linear-gradient(to right, transparent 0, black 40px, transparent 100%);
8788
}
8889
</style>

src/components/Settings/PluginComponentsAndPages/VideoCard/VideoCard.vue

Lines changed: 5 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -168,25 +168,11 @@ function resetColumns() {
168168
<Radio v-model="settings.showVideoCardRecommendTag" />
169169
</SettingsItem>
170170

171-
<SettingsItem :title="$t('settings.home_adaptive_title_auto_size')" :desc="$t('settings.home_adaptive_title_auto_size_desc')">
172-
<Radio v-model="settings.homeAdaptiveTitleAutoSize" />
173-
</SettingsItem>
174-
175-
<SettingsItem :title="$t('settings.home_adaptive_title_font_size')" :desc="$t('settings.home_adaptive_title_font_size_desc')">
176-
<div flex="~ justify-end" w-full>
177-
<Input
178-
v-model="settings.homeAdaptiveTitleFontSize"
179-
type="number"
180-
:min="12"
181-
:max="28"
182-
flex-1
183-
:disabled="settings.homeAdaptiveTitleAutoSize"
184-
>
185-
<template #suffix>
186-
px
187-
</template>
188-
</Input>
189-
</div>
171+
<SettingsItem
172+
:title="$t('settings.video_card_title_font_size')"
173+
:desc="$t('settings.video_card_title_font_size_desc')"
174+
>
175+
<Select v-model="settings.videoCardTitleFontSize" :options="videoCardFontSizeOptions" w="full" />
190176
</SettingsItem>
191177

192178
<SettingsItem

src/components/VideoCard/VideoCard.vue

Lines changed: 9 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import { computed, ref, watch, watchEffect } from 'vue'
33
44
import { useBewlyApp } from '~/composables/useAppProvider'
5+
import { useVideoCardSharedStyles } from '~/composables/useVideoCardSharedStyles'
56
import { settings } from '~/logic'
67
import type { VideoCardLayoutSetting } from '~/logic/storage'
78
import { calcCurrentTime, numFormatter } from '~/utils/dataFormatter'
@@ -38,6 +39,9 @@ const layout = computed((): 'modern' | 'old' => {
3839
const logic = useVideoCardLogic(props)
3940
const { mainAppRef } = useBewlyApp()
4041
42+
// 使用共享样式(避免每个卡片重复计算)
43+
const { titleFontSizeClass, titleStyle, authorFontSizeClass, metaFontSizeClass } = useVideoCardSharedStyles()
44+
4145
// Modern layout specific: cover stats calculation
4246
const statSuffixPattern = /(播放量?|观看|弹幕|点赞|views?|likes?|danmakus?|comments?|回复|人气|转发|分享|[次条人])/gi
4347
const statSeparatorPattern = /[•·]/g
@@ -144,26 +148,6 @@ const coverStatsStyle = computed(() => {
144148
return {}
145149
})
146150
147-
// Title and text sizing
148-
const DEFAULT_TITLE_LINE_HEIGHT = 1.35
149-
const CUSTOM_TITLE_LINE_HEIGHT = 1.25
150-
151-
const titleStyle = computed((): Record<string, string | number> => {
152-
const { homeAdaptiveTitleAutoSize, homeAdaptiveTitleFontSize } = settings.value
153-
154-
if (!homeAdaptiveTitleAutoSize && homeAdaptiveTitleFontSize) {
155-
return {
156-
fontSize: `${homeAdaptiveTitleFontSize}px`,
157-
lineHeight: CUSTOM_TITLE_LINE_HEIGHT.toString(),
158-
'--bew-title-line-height': CUSTOM_TITLE_LINE_HEIGHT.toString(),
159-
}
160-
}
161-
162-
return {
163-
'--bew-title-line-height': DEFAULT_TITLE_LINE_HEIGHT.toString(),
164-
}
165-
})
166-
167151
// Highlight tags calculation - 使用查找表优化性能
168152
const LIKE_RATIO_THRESHOLDS = [
169153
{ view: 1_000_000, ratio: 0.01 },
@@ -276,16 +260,6 @@ function parseDurationStr(durationStr?: string) {
276260
return seconds
277261
}
278262
279-
const VIDEO_CARD_FONT_SIZE_MAP = {
280-
xs: 'text-xs',
281-
sm: 'text-sm',
282-
base: 'text-base',
283-
lg: 'text-lg',
284-
} as const
285-
286-
const authorFontSizeClass = computed(() => VIDEO_CARD_FONT_SIZE_MAP[settings.value.videoCardAuthorFontSize] ?? VIDEO_CARD_FONT_SIZE_MAP.sm)
287-
const metaFontSizeClass = computed(() => VIDEO_CARD_FONT_SIZE_MAP[settings.value.videoCardMetaFontSize] ?? VIDEO_CARD_FONT_SIZE_MAP.xs)
288-
289263
const coverImageUrl = computed(() =>
290264
props.video ? `${logic.removeHttpFromUrl(props.video.cover)}@672w_378h_1c_!web-home-common-cover` : '',
291265
)
@@ -397,6 +371,7 @@ provide('getVideoType', () => props.type!)
397371
:video-url="logic.videoUrl.value"
398372
:more-btn="moreBtn"
399373
:show-video-options="logic.showVideoOptions.value"
374+
:title-font-size-class="titleFontSizeClass"
400375
:title-style="titleStyle"
401376
:author-font-size-class="authorFontSizeClass"
402377
:meta-font-size-class="metaFontSizeClass"
@@ -442,6 +417,10 @@ provide('getVideoType', () => props.type!)
442417
/* 防止字体度量变化 */
443418
-webkit-font-smoothing: antialiased;
444419
-moz-osx-font-smoothing: grayscale;
420+
421+
/* 防止骨架屏和真实内容切换时的布局偏移:
422+
确保容器在加载过程中保持稳定的最小高度 */
423+
min-height: fit-content;
445424
}
446425
447426
.horizontal-card-cover {

src/components/VideoCard/components/VideoCardCover.vue

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -245,13 +245,12 @@ onBeforeUnmount(() => {
245245
overflow-hidden
246246
cursor-pointer
247247
group-hover:z-2
248-
style="aspect-ratio: 16 / 9; contain: layout style;"
248+
style="aspect-ratio: 16 / 9; contain: layout style; will-change: auto;"
249249
>
250250
<!-- Skeleton mode -->
251251
<div
252252
v-if="skeleton"
253253
w-full h-full bg="$bew-skeleton" rounded="$bew-radius"
254-
class="animate-pulse"
255254
style="aspect-ratio: 16 / 9;"
256255
/>
257256

@@ -491,18 +490,10 @@ onBeforeUnmount(() => {
491490
left: 0;
492491
right: 0;
493492
bottom: 0;
493+
/* 简化渐变:从6层减少到3层,提升性能 */
494494
background: var(
495495
--bew-video-card-shadow-gradient,
496-
linear-gradient(
497-
to top,
498-
rgba(0, 0, 0, 0.8) 0%,
499-
rgba(0, 0, 0, 0.7) 30%,
500-
rgba(0, 0, 0, 0.5) 50%,
501-
rgba(0, 0, 0, 0.3) 70%,
502-
rgba(0, 0, 0, 0.15) 85%,
503-
rgba(0, 0, 0, 0.05) 95%,
504-
transparent 100%
505-
)
496+
linear-gradient(to top, rgba(0, 0, 0, 0.75) 0%, rgba(0, 0, 0, 0.35) 50%, transparent 100%)
506497
);
507498
height: var(--bew-video-card-shadow-height-multiplier, calc(var(--video-card-stats-overlay-scale, 1.4) * 100%));
508499
border-bottom-left-radius: inherit;

src/components/VideoCard/components/VideoCardInfo.vue

Lines changed: 14 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
<script setup lang="ts">
22
import { computed, ref } from 'vue'
33
4-
import { settings } from '~/logic'
54
import { calcTimeSince, numFormatter } from '~/utils/dataFormatter'
65
76
import type { Video } from '../types'
@@ -16,6 +15,7 @@ interface Props {
1615
videoUrl?: string
1716
moreBtn: boolean
1817
showVideoOptions: boolean
18+
titleFontSizeClass: string
1919
titleStyle: Record<string, string | number>
2020
authorFontSizeClass: string
2121
metaFontSizeClass: string
@@ -30,7 +30,6 @@ const emit = defineEmits<{
3030
}>()
3131
3232
const moreBtnRef = ref<HTMLDivElement | null>(null)
33-
const titleRef = ref<HTMLElement | null>(null)
3433
3534
defineExpose({
3635
moreBtnRef,
@@ -76,12 +75,12 @@ const primaryTags = computed(() => {
7675
text="overflow-ellipsis $bew-text-1 lg"
7776
>
7877
<!-- 使用与真实文本相同的行高填充,考虑 line-height -->
79-
<div w-full bg="$bew-skeleton" rounded-4px class="animate-pulse" style="height: 1em; margin-bottom: calc((var(--bew-title-line-height, 1.35) - 1) * 0.5em);" />
80-
<div w="3/4" bg="$bew-skeleton" rounded-4px class="animate-pulse" style="height: 1em;" />
78+
<div w-full bg="$bew-skeleton" rounded-4px style="height: 1em; margin-bottom: calc((var(--bew-title-line-height, 1.35) - 1) * 0.5em);" />
79+
<div w="3/4" bg="$bew-skeleton" rounded-4px style="height: 1em;" />
8180
</div>
8281
<div
8382
v-if="layout === 'modern'" shrink-0 w-8 h-8 rounded="1/2"
84-
bg="$bew-skeleton" class="animate-pulse"
83+
bg="$bew-skeleton"
8584
/>
8685
</div>
8786

@@ -93,18 +92,17 @@ const primaryTags = computed(() => {
9392
>
9493
<div
9594
w="34px" h="34px" rounded="1/2" bg="$bew-skeleton" shrink-0
96-
class="animate-pulse"
9795
/>
9896
<div flex="~ col gap-1" w="[calc(100%-50px)]">
9997
<!-- 作者名称骨架:使用与真实文本相同的字体大小和行高 -->
10098
<div
101-
w="60%" bg="$bew-skeleton" rounded-4px class="animate-pulse"
99+
w="60%" bg="$bew-skeleton" rounded-4px
102100
:class="authorFontSizeClass"
103101
style="height: 1em;"
104102
/>
105103
<!-- 标签骨架:使用与真实标签相同的高度,包括 padding -->
106104
<div
107-
w="80%" bg="$bew-skeleton" rounded-4px class="animate-pulse"
105+
w="80%" bg="$bew-skeleton" rounded-4px
108106
:class="metaFontSizeClass"
109107
style="height: calc(1em + 0.24em);"
110108
/>
@@ -118,7 +116,7 @@ const primaryTags = computed(() => {
118116
:class="metaFontSizeClass"
119117
>
120118
<div
121-
w="60px" bg="$bew-skeleton" rounded="$bew-radius" class="animate-pulse"
119+
w="60px" bg="$bew-skeleton" rounded="$bew-radius"
122120
style="height: calc(1em + 0.24em);"
123121
/>
124122
</div>
@@ -133,7 +131,7 @@ const primaryTags = computed(() => {
133131
:class="metaFontSizeClass"
134132
>
135133
<div
136-
bg="$bew-skeleton" rounded="$bew-radius" class="animate-pulse"
134+
bg="$bew-skeleton" rounded="$bew-radius"
137135
lh-6 p="x-2" w="60px"
138136
style="height: calc(1em + 0.24em);"
139137
/>
@@ -153,9 +151,9 @@ const primaryTags = computed(() => {
153151
<div
154152
v-if="horizontal"
155153
w="34px" h="34px" rounded="1/2" bg="$bew-skeleton"
156-
shrink-0 m-r-2 class="animate-pulse"
154+
shrink-0 m-r-2
157155
/>
158-
<div w="100px" bg="$bew-skeleton" rounded-4px class="animate-pulse" style="height: 1em;" />
156+
<div w="100px" bg="$bew-skeleton" rounded-4px style="height: 1em;" />
159157
</div>
160158

161159
<!-- View & Danmaku skeleton -->
@@ -164,7 +162,7 @@ const primaryTags = computed(() => {
164162
:class="metaFontSizeClass"
165163
text="$bew-text-2"
166164
>
167-
<div w="150px" bg="$bew-skeleton" rounded-4px class="animate-pulse" style="height: 1em; display: inline-block;" />
165+
<div w="150px" bg="$bew-skeleton" rounded-4px style="height: 1em; display: inline-block;" />
168166
</div>
169167
</div>
170168

@@ -175,7 +173,7 @@ const primaryTags = computed(() => {
175173
:class="metaFontSizeClass"
176174
>
177175
<div
178-
bg="$bew-skeleton" rounded="$bew-radius" class="animate-pulse"
176+
bg="$bew-skeleton" rounded="$bew-radius"
179177
lh-6 p="x-2" w="60px"
180178
style="height: calc(1em + 0.24em);"
181179
/>
@@ -197,13 +195,12 @@ const primaryTags = computed(() => {
197195
<div class="group/desc" flex="~ col" :class="layout === 'modern' ? 'gap-2' : ''" w="full" align="items-start">
198196
<div flex="~ gap-1 justify-between items-start" w="full" pos="relative">
199197
<h3
200-
ref="titleRef"
201198
:class="[
202199
video.liveStatus === 1 ? 'keep-one-line' : 'keep-two-lines',
203-
{ 'bew-title-auto': settings.homeAdaptiveTitleAutoSize },
204200
layout === 'modern' ? 'video-card-title' : '',
201+
titleFontSizeClass,
205202
]"
206-
text="overflow-ellipsis $bew-text-1 lg"
203+
text="overflow-ellipsis $bew-text-1"
207204
:style="titleStyle"
208205
cursor="pointer"
209206
:title="video.title"
@@ -497,13 +494,6 @@ const primaryTags = computed(() => {
497494
</template>
498495

499496
<style lang="scss" scoped>
500-
.bew-title-auto {
501-
/* Auto scale by actual card width (fallback to base grid width)
502-
Increase responsiveness and use unitless line-height for better small-size rendering */
503-
font-size: clamp(12px, calc((var(--bew-card-width, var(--bew-home-card-min-width, 280px)) / 280) * 20px), 30px);
504-
line-height: clamp(1.15, calc(1.1 + (var(--bew-card-width, var(--bew-home-card-min-width, 280px)) / 280) * 0.2), 1.5);
505-
}
506-
507497
.video-card-title {
508498
&.keep-two-lines {
509499
min-height: calc(var(--bew-title-line-height, 1.35) * 2em);
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/**
2+
* 视频卡片共享样式计算(单例模式)
3+
* 避免每个卡片重复计算相同的样式
4+
*/
5+
6+
import { computed } from 'vue'
7+
8+
import { settings } from '~/logic'
9+
10+
// 字体大小映射表(常量,无需重复计算)
11+
const VIDEO_CARD_FONT_SIZE_MAP = {
12+
xs: 'text-xs',
13+
sm: 'text-sm',
14+
base: 'text-base',
15+
lg: 'text-lg',
16+
} as const
17+
18+
// 标题行高常量
19+
const TITLE_LINE_HEIGHT = 1.35
20+
21+
/**
22+
* 使用视频卡片共享样式
23+
* 所有卡片使用相同的字体大小,避免重复计算
24+
*/
25+
export function useVideoCardSharedStyles() {
26+
// 标题字体大小类(全局共享,使用4档预设)
27+
const titleFontSizeClass = computed(() =>
28+
VIDEO_CARD_FONT_SIZE_MAP[settings.value.videoCardTitleFontSize] ?? VIDEO_CARD_FONT_SIZE_MAP.base,
29+
)
30+
31+
// 标题样式(全局共享)
32+
const titleStyle = computed((): Record<string, string | number> => {
33+
return {
34+
'--bew-title-line-height': TITLE_LINE_HEIGHT.toString(),
35+
}
36+
})
37+
38+
// 作者字体大小类(全局共享)
39+
const authorFontSizeClass = computed(() =>
40+
VIDEO_CARD_FONT_SIZE_MAP[settings.value.videoCardAuthorFontSize] ?? VIDEO_CARD_FONT_SIZE_MAP.sm,
41+
)
42+
43+
// 元数据字体大小类(全局共享)
44+
const metaFontSizeClass = computed(() =>
45+
VIDEO_CARD_FONT_SIZE_MAP[settings.value.videoCardMetaFontSize] ?? VIDEO_CARD_FONT_SIZE_MAP.xs,
46+
)
47+
48+
return {
49+
titleFontSizeClass,
50+
titleStyle,
51+
authorFontSizeClass,
52+
metaFontSizeClass,
53+
}
54+
}

0 commit comments

Comments
 (0)