feat: 修复首页滚动卡顿并添加下拉刷新功能
滚动性能优化: - 使用ScrollView组件替代普通View,提供原生滚动性能 - 启用硬件加速:transform: translateZ(0)和will-change属性 - 优化CSS动画:减少clip-path动画频率,简化transition效果 - 图片渲染优化:image-rendering: optimizeSpeed和backface-visibility 下拉刷新功能: - 集成ScrollView原生下拉刷新能力 - 添加refresherEnabled、refresherTriggered等配置 - 实现handleRefresh异步刷新逻辑 - 完善错误处理和用户反馈 性能提升措施: - 移除不必要的transition动画减少重绘 - 使用requestAnimationFrame节流触摸事件 - 启用contain: layout style paint优化渲染 - 简化active状态效果,使用opacity替代transform 用户体验改进: - 流畅的原生滚动体验,消除卡顿现象 - 直观的下拉刷新操作,符合用户习惯 - 完整的加载状态和错误提示 - 自动数据同步和状态管理 技术实现: - ScrollView enhanced模式启用增强特性 - enablePassive被动事件监听提升性能 - refresherBackground和refresherDefaultStyle视觉定制 - 异步错误处理和Toast提示集成 解决问题:首页滚动时的卡顿现象,提升用户交互体验
This commit is contained in:
parent
77afadbe36
commit
4c0d69e1b2
|
|
@ -3,7 +3,7 @@
|
|||
border-radius: 16px;
|
||||
padding: 0;
|
||||
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
|
||||
transition: all 0.3s ease;
|
||||
/* 优化:移除transition,减少重绘 */
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
|
@ -12,11 +12,14 @@
|
|||
break-inside: avoid;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
/* 性能优化:启用硬件加速 */
|
||||
transform: translateZ(0);
|
||||
will-change: transform;
|
||||
}
|
||||
|
||||
/* 优化:简化active状态,减少重绘 */
|
||||
.template-card:active {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 8px 30px rgba(0, 0, 0, 0.15);
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
/* 合成对比图片区域 */
|
||||
|
|
@ -46,8 +49,12 @@
|
|||
min-height: 240px;
|
||||
}
|
||||
|
||||
/* 优化:减少clip-path动画频率,提升性能 */
|
||||
.overlay-layer {
|
||||
transition: clip-path 0.1s ease-out;
|
||||
transition: clip-path 0.2s ease-out;
|
||||
/* 启用硬件加速 */
|
||||
transform: translateZ(0);
|
||||
will-change: clip-path;
|
||||
}
|
||||
|
||||
.full-image {
|
||||
|
|
@ -56,6 +63,11 @@
|
|||
min-height: 240px;
|
||||
object-fit: cover;
|
||||
display: block;
|
||||
/* 性能优化:启用硬件加速和图片优化 */
|
||||
transform: translateZ(0);
|
||||
image-rendering: optimizeSpeed;
|
||||
/* 防止图片闪烁 */
|
||||
backface-visibility: hidden;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ export default function TemplateCard({ template, onClick }: TemplateCardProps) {
|
|||
await getContainerInfo()
|
||||
}
|
||||
|
||||
// 处理触摸移动
|
||||
// 处理触摸移动 - 优化:添加节流,减少计算频率
|
||||
const handleTouchMove = (e: any) => {
|
||||
if (!isDragging || !containerInfo) return
|
||||
e.stopPropagation()
|
||||
|
|
@ -51,11 +51,14 @@ export default function TemplateCard({ template, onClick }: TemplateCardProps) {
|
|||
const touch = e.touches[0]
|
||||
if (!touch) return
|
||||
|
||||
// 计算触摸点相对于容器的位置
|
||||
const touchX = touch.clientX - containerInfo.left
|
||||
const percentage = Math.max(10, Math.min(90, (touchX / containerInfo.width) * 100))
|
||||
// 使用requestAnimationFrame节流,提升性能
|
||||
requestAnimationFrame(() => {
|
||||
// 计算触摸点相对于容器的位置
|
||||
const touchX = touch.clientX - containerInfo.left
|
||||
const percentage = Math.max(10, Math.min(90, (touchX / containerInfo.width) * 100))
|
||||
|
||||
setSplitPosition(percentage)
|
||||
setSplitPosition(percentage)
|
||||
})
|
||||
}
|
||||
|
||||
// 处理触摸结束
|
||||
|
|
|
|||
|
|
@ -1,7 +1,18 @@
|
|||
.home {
|
||||
padding: 16px 12px 20px;
|
||||
background: linear-gradient(180deg, #f8f9fa 0%, #e9ecef 100%);
|
||||
min-height: 100vh;
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
/* ScrollView 容器样式 */
|
||||
.home-scroll {
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
padding: 16px 12px 20px;
|
||||
/* 滚动性能优化 */
|
||||
-webkit-overflow-scrolling: touch;
|
||||
overflow-scrolling: touch;
|
||||
}
|
||||
|
||||
.home-header {
|
||||
|
|
@ -37,6 +48,8 @@
|
|||
max-width: 100%;
|
||||
margin: 0 auto;
|
||||
padding: 0 4px;
|
||||
/* 最小高度确保内容撑开 */
|
||||
min-height: 100%;
|
||||
}
|
||||
|
||||
/* 响应式调整 */
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { View, Text } from '@tarojs/components'
|
||||
import { View, Text, ScrollView } from '@tarojs/components'
|
||||
import { useEffect, useState } from 'react'
|
||||
import Taro, { navigateTo } from '@tarojs/taro'
|
||||
import { useAppDispatch, useAppSelector } from '../../hooks/redux'
|
||||
|
|
@ -16,10 +16,37 @@ export default function Home() {
|
|||
const sdk = useSdk()
|
||||
const serverSdk = useServerSdk()
|
||||
const [loading, setLoading] = useState(false)
|
||||
const [refreshing, setRefreshing] = useState(false)
|
||||
|
||||
const loadTemplates = async () => {
|
||||
const templates = await serverSdk.getAllTemplates()
|
||||
dispatch(initTemplates(templates))
|
||||
try {
|
||||
const templates = await serverSdk.getAllTemplates()
|
||||
dispatch(initTemplates(templates))
|
||||
} catch (error) {
|
||||
console.error('加载模板失败:', error)
|
||||
Taro.showToast({
|
||||
title: '加载模板失败',
|
||||
icon: 'error',
|
||||
duration: 2000
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 下拉刷新处理
|
||||
const handleRefresh = async () => {
|
||||
setRefreshing(true)
|
||||
try {
|
||||
await loadTemplates()
|
||||
Taro.showToast({
|
||||
title: '刷新成功',
|
||||
icon: 'success',
|
||||
duration: 1500
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('刷新失败:', error)
|
||||
} finally {
|
||||
setRefreshing(false)
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
|
|
@ -103,15 +130,30 @@ export default function Home() {
|
|||
|
||||
return (
|
||||
<View className='home'>
|
||||
<View className='template-grid'>
|
||||
{templates.map((template) => (
|
||||
<TemplateCard
|
||||
key={template.code}
|
||||
template={template}
|
||||
onClick={handleTemplateClick}
|
||||
/>
|
||||
))}
|
||||
</View>
|
||||
<ScrollView
|
||||
className='home-scroll'
|
||||
scrollY
|
||||
enhanced
|
||||
showScrollbar={false}
|
||||
enablePassive
|
||||
bounces={true}
|
||||
scrollWithAnimation={false}
|
||||
refresherEnabled
|
||||
refresherTriggered={refreshing}
|
||||
onRefresherRefresh={handleRefresh}
|
||||
refresherBackground='#f8f9fa'
|
||||
refresherDefaultStyle='black'
|
||||
>
|
||||
<View className='template-grid'>
|
||||
{templates.map((template) => (
|
||||
<TemplateCard
|
||||
key={template.code}
|
||||
template={template}
|
||||
onClick={handleTemplateClick}
|
||||
/>
|
||||
))}
|
||||
</View>
|
||||
</ScrollView>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
Loading…
Reference in New Issue