1. 数据分页与懒加载
分页请求实现
async fetchPaginatedData ( page = 1 , pageSize = 20 ) {
try {
this . loading = true ;
const response = await api. get ( '/large-data' , {
params : { page, pageSize }
} ) ;
this . data = response. data;
this . total = response. total;
} finally {
this . loading = false ;
}
}
滚动加载更多
<template>
<div @scroll="handleScroll" class="scroll-container">
<div v-for="item in loadedData" :key="item.id">
{{ item.content }}
</div>
<div v-if="loadingMore" class="loading-more">加载中...</div>
</div>
</template>
<script>
export default {
data() {
return {
loadedData: [],
currentPage: 1,
loadingMore: false,
hasMore: true
}
},
methods: {
async handleScroll(event) {
const { scrollTop, clientHeight, scrollHeight } = event.target
if (scrollHeight - (scrollTop + clientHeight) < 50 && !this.loadingMore && this.hasMore) {
this.loadingMore = true
this.currentPage++
const newData = await this.fetchMoreData(this.currentPage)
this.loadedData = [...this.loadedData, ...newData]
if (newData.length < 20) this.hasMore = false
this.loadingMore = false
}
}
}
}
</script>
2. 虚拟滚动技术
使用vue-virtual-scroller
<template>
<RecycleScroller
class="scroller"
:items="bigData"
:item-size="50"
key-field="id"
v-slot="{ item }"
>
<div class="item">
{{ item.name }}
</div>
</RecycleScroller>
</template>
<script>
import { RecycleScroller } from 'vue-virtual-scroller'
import 'vue-virtual-scroller/dist/vue-virtual-scroller.css'
export default {
components: { RecycleScroller },
data() {
return {
bigData: [] // 大数据集
}
}
}
</script>
<style>
.scroller {
height: 500px;
}
.item {
height: 50px;
}
</style>
3. 数据分块处理
processLargeData ( data ) {
const chunkSize = 1000
for ( let i = 0 ; i < data. length; i += chunkSize) {
const chunk = data. slice ( i, i + chunkSize)
requestIdleCallback ( ( ) => {
this . renderChunk ( chunk)
} )
}
} ,
renderChunk ( chunk ) {
chunk. forEach ( item => {
} )
}
4. Web Worker 处理
worker.js
self. onmessage = function ( e ) {
const result = e. data. map ( item => {
return processedItem
} )
self. postMessage ( result)
}
主线程使用
processDataWithWorker ( data ) {
const worker = new Worker ( 'worker.js' )
worker. postMessage ( data)
worker. onmessage = ( e ) => {
this . processedData = e. data
worker. terminate ( )
}
}
5. 前端数据缓存
使用IndexedDB缓存
const dbPromise = idb. open ( 'bigDataDB' , 1 , upgradeDB => {
upgradeDB. createObjectStore ( 'data' , { keyPath : 'id' } )
} )
async saveDataToIDB ( data ) {
const db = await dbPromise
const tx = db. transaction ( 'data' , 'readwrite' )
const store = tx. objectStore ( 'data' )
await Promise. all ( data. map ( item => store. put ( item) ) )
return tx. complete
}
async getDataFromIDB ( ) {
const db = await dbPromise
return db. transaction ( 'data' ) . objectStore ( 'data' ) . getAll ( )
}
6. 请求优化
请求取消
let cancelToken = null
async fetchData ( ) {
if ( cancelToken) {
cancelToken. cancel ( 'Operation canceled due to new request.' )
}
cancelToken = axios. CancelToken. source ( )
try {
const response = await api. get ( '/data' , {
cancelToken : cancelToken. token
} )
this . data = response. data
} catch ( error) {
if ( ! axios. isCancel ( error) ) {
console. error ( '请求错误:' , error)
}
}
}
请求合并
import { debounce } from 'lodash'
methods : {
fetchData : debounce ( async function ( params ) {
const response = await api. get ( '/data' , { params } )
this . data = response. data
} , 300 )
}
7. 可视化优化
数据采样展示
sampleData ( data, sampleSize = 1000 ) {
if ( data. length <= sampleSize) return data
const step = Math. floor ( data. length / sampleSize)
return data. filter ( ( _, index ) => index % step === 0 )
}
8. 内存管理
大数据释放
beforeDestroy ( ) {
this . bigData = null
this . processedData = null
if ( window. gc) window. gc ( )
}
9. 交互优化
骨架屏加载
<template>
<div v-if="loading" class="skeleton-container">
<div v-for="i in 10" :key="i" class="skeleton-item"></div>
</div>
<div v-else>
<!-- 实际内容 -->
</div>
</template>
<style>
.skeleton-item {
height: 50px;
background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
background-size: 400% 100%;
animation: shimmer 1.5s infinite;
margin-bottom: 10px;
}
@keyframes shimmer {
0% { background-position: 100% 50%; }
100% { background-position: 0 50%; }
}
</style>
10. 性能监控
性能指标收集
measurePerformance ( ) {
const startTime = performance. now ( )
this . processLargeData ( )
const endTime = performance. now ( )
console. log ( ` 处理耗时: ${ endTime - startTime} ms ` )
if ( performance. memory) {
console. log ( ` 内存使用: ${ performance. memory. usedJSHeapSize / 1048576 } MB ` )
}
}