性能优化是提升用户体验的关键因素,本文将从多个维度详细介绍uni-app应用的性能优化策略,帮助你构建流畅的跨端应用。
1. 首屏加载优化
1.1 分包加载
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| { "pages": [{ "path": "pages/index/index", "style": { ... } }], "subPackages": [{ "root": "pagesA", "pages": [{ "path": "list/index", "style": { ... } }] }] }
|
1.2 预加载策略
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| uni.preloadSubPackage({ name: 'pagesA', success: () => { console.log('分包预加载成功') }, fail: () => { console.log('分包预加载失败') } })
onLoad() { uni.preloadPage({ url: '/pagesA/list/index' }) }
|
1.3 骨架屏实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| <!-- components/skeleton.vue --> <template> <view class="skeleton" v-if="loading"> <view class="skeleton-header"></view> <view class="skeleton-content"> <view class="skeleton-item" v-for="i in 5" :key="i"></view> </view> </view> </template>
<style> .skeleton { padding: 20rpx; } .skeleton-header { height: 40rpx; background: #f0f0f0; margin-bottom: 20rpx; animation: skeleton-loading 1s infinite; } .skeleton-item { height: 100rpx; background: #f0f0f0; margin-bottom: 20rpx; animation: skeleton-loading 1s infinite; } @keyframes skeleton-loading { 0% { opacity: 1; } 50% { opacity: 0.5; } 100% { opacity: 1; } } </style>
|
2. 渲染性能优化
2.1 长列表优化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
| <!-- 虚拟列表实现 --> <template> <view class="list-container"> <view class="list-phantom" :style="{ height: listHeight + 'px' }" ></view> <view class="list-content" :style="{ transform: getTransform }" > <view class="list-item" v-for="item in visibleData" :key="item.id" > {{ item.content }} </view> </view> </view> </template>
<script> export default { data() { return { listData: [], // 完整列表数据 itemHeight: 50, // 每项高度 visibleCount: 10, // 可视区域显示的数量 startIndex: 0, // 起始索引 endIndex: 0 // 结束索引 } }, computed: { listHeight() { return this.listData.length * this.itemHeight }, visibleData() { return this.listData.slice(this.startIndex, this.endIndex) }, getTransform() { return `translate3d(0, ${this.startIndex * this.itemHeight}px, 0)` } }, methods: { handleScroll(e) { const scrollTop = e.detail.scrollTop this.startIndex = Math.floor(scrollTop / this.itemHeight) this.endIndex = this.startIndex + this.visibleCount } } } </script>
|
2.2 避免频繁更新
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| function debounce(fn, delay) { let timer = null return function(...args) { if (timer) clearTimeout(timer) timer = setTimeout(() => { fn.apply(this, args) }, delay) } }
function throttle(fn, delay) { let timer = null let start = Date.now() return function(...args) { const current = Date.now() const remaining = delay - (current - start) if (timer) clearTimeout(timer) if (remaining <= 0) { fn.apply(this, args) start = Date.now() } else { timer = setTimeout(() => { fn.apply(this, args) start = Date.now() }, remaining) } } }
export default { methods: { updateData: debounce(function() { }, 300) } }
|
3. 内存优化
3.1 及时销毁
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| export default { data() { return { timer: null, observer: null } }, beforeDestroy() { if (this.timer) { clearTimeout(this.timer) this.timer = null } if (this.observer) { this.observer.disconnect() this.observer = null } } }
|
3.2 避免内存泄漏
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| const preloadImages = (urls) => { const promises = urls.map(url => { return new Promise((resolve, reject) => { const image = new Image() image.onload = () => { image.onload = null resolve(url) } image.onerror = () => { image.onerror = null reject(url) } image.src = url }) }) return Promise.all(promises) }
|
4. 网络优化
4.1 请求合并
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| class RequestQueue { constructor() { this.queue = new Map() } async request(key, promiseCreator) { if (this.queue.has(key)) { return this.queue.get(key) } const promise = promiseCreator() this.queue.set(key, promise) try { const result = await promise this.queue.delete(key) return result } catch (err) { this.queue.delete(key) throw err } } }
const requestQueue = new RequestQueue()
function fetchData(id) { return requestQueue.request(`data_${id}`, () => { return new Promise(resolve => { setTimeout(() => { resolve({ id, data: 'some data' }) }, 1000) }) }) }
|
4.2 数据缓存
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| class CacheManager { constructor(expire = 5 * 60 * 1000) { this.cache = new Map() this.expire = expire } set(key, value) { this.cache.set(key, { value, timestamp: Date.now() }) } get(key) { const data = this.cache.get(key) if (!data) return null if (Date.now() - data.timestamp > this.expire) { this.cache.delete(key) return null } return data.value } clear() { this.cache.clear() } }
const cache = new CacheManager()
async function getData(key) { const cached = cache.get(key) if (cached) return cached const data = await fetchData(key) cache.set(key, data) return data }
|
5. 其他优化技巧
5.1 图片优化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| Vue.directive('lazy', { bind(el, binding) { const observer = new IntersectionObserver(entries => { entries.forEach(entry => { if (entry.isIntersecting) { el.src = binding.value observer.unobserve(el) } }) }) observer.observe(el) } })
<image v-lazy="imageUrl" />
|
5.2 组件优化
1 2 3 4 5 6 7 8 9 10 11 12 13
| <keep-alive> <component :is="currentComponent"></component> </keep-alive>
const AsyncComponent = () => ({ component: import('./heavy-component.vue'), loading: LoadingComponent, error: ErrorComponent, delay: 200, timeout: 3000 })
|
6. 性能监控
6.1 页面性能监控
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| const performance = { mark(name) { if (typeof performance !== 'undefined') { performance.mark(name) } }, measure(name, startMark, endMark) { if (typeof performance !== 'undefined') { performance.measure(name, startMark, endMark) const measures = performance.getEntriesByName(name) return measures[0].duration } return 0 }, report(data) { console.log('性能数据:', data) } }
|
7. 总结
- 合理使用分包加载
- 实现虚拟列表
- 优化更新机制
- 注意内存管理
- 做好网络优化
- 监控性能指标
如果觉得文章对你有帮助,欢迎点赞、评论、分享,你的支持是我继续创作的动力!