Browse Source

优化: uniapp拉取过多离线消息导致卡顿

master
xsx 2 years ago
parent
commit
10d98af6e3
  1. 4
      im-uniapp/components/head-image/head-image.vue
  2. 46
      im-uniapp/pages/chat/chat.vue
  3. 56
      im-uniapp/store/chatStore.js

4
im-uniapp/components/head-image/head-image.vue

@ -83,9 +83,7 @@
.avatar-text { .avatar-text {
background-color: #f2f2f2; background-color: #f2f2f2;
/* 默认背景色 */ border-radius: 10%;
border-radius: 50%;
/* 圆角效果 */
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;

46
im-uniapp/pages/chat/chat.vue

@ -1,8 +1,8 @@
<template> <template>
<view class="tab-page"> <view class="tab-page">
<view v-if="loading" class="chat-loading" > <view v-if="loading" class="chat-loading">
<loading :size="50" :mask="false"> <loading :size="50" :mask="false">
<view>消息接收中...</view> <view>消息接收中...</view>
</loading> </loading>
</view> </view>
@ -129,21 +129,33 @@
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
.chat-tip { .tab-page {
position: absolute;
top: 400rpx;
padding: 50rpx;
line-height: 50rpx;
text-align: left;
color: darkblue;
font-size: 30rpx;
}
.chat-loading {
display: block;
height: 100rpx;
background: white;
position: relative; position: relative;
color: blue; border: #dddddd solid 1px;
display: flex;
flex-direction: column;
.chat-tip {
position: absolute;
top: 400rpx;
padding: 50rpx;
line-height: 50rpx;
text-align: left;
color: darkblue;
font-size: 30rpx;
}
.chat-loading {
display: block;
height: 100rpx;
background: white;
position: relative;
color: blue;
}
.scroll-bar {
flex: 1;
height: 100%;
}
} }
</style> </style>

56
im-uniapp/store/chatStore.js

@ -4,11 +4,14 @@ import {
} from '@/common/enums.js'; } from '@/common/enums.js';
import userStore from './userStore'; import userStore from './userStore';
/* uniapp线cacheChats,
等待所有离线消息拉取完成后再统一进行渲染 */
let cacheChats = [];
export default { export default {
state: { state: {
activeIndex: -1, activeIndex: -1,
chats: [], chats: [],
copyChats: [],
privateMsgMaxId: 0, privateMsgMaxId: 0,
groupMsgMaxId: 0, groupMsgMaxId: 0,
loadingPrivateMsg: false, loadingPrivateMsg: false,
@ -17,19 +20,26 @@ export default {
mutations: { mutations: {
initChats(state, chatsData) { initChats(state, chatsData) {
state.chats = chatsData.chats || []; // 暂存至缓冲区
cacheChats = JSON.parse(JSON.stringify(chatsData.chats))
// 只取前10条数据做做样子,一切都为了加快初始化时间
let size = Math.min(chatsData.chats.length,10);
for (let i = 0; i < size; i++) {
let chat = chatsData.chats[i];
chat.messages = [];
state.chats[i] = chat;
}
state.privateMsgMaxId = chatsData.privateMsgMaxId || 0; state.privateMsgMaxId = chatsData.privateMsgMaxId || 0;
state.groupMsgMaxId = chatsData.groupMsgMaxId || 0; state.groupMsgMaxId = chatsData.groupMsgMaxId || 0;
// 防止图片一直处在加载中状态 // 防止图片一直处在加载中状态
state.chats.forEach((chat) => { cacheChats.forEach((chat) => {
chat.messages.forEach((msg) => { chat.messages.forEach((msg) => {
if (msg.loadStatus == "loading") { if (msg.loadStatus == "loading") {
msg.loadStatus = "fail" msg.loadStatus = "fail"
} }
}) })
}) })
// 拷贝一份,用于缓存离线消息
state.copyChats = JSON.parse(JSON.stringify(state.chats))
}, },
openChat(state, chatInfo) { openChat(state, chatInfo) {
let chats = this.getters.findChats(); let chats = this.getters.findChats();
@ -112,6 +122,10 @@ export default {
} }
}, },
moveTop(state, idx) { moveTop(state, idx) {
// 加载中不移动,防止卡顿
if (this.getters.isLoading()) {
return;
}
let chats = this.getters.findChats(); let chats = this.getters.findChats();
if (idx > 0) { if (idx > 0) {
let chat = chats[idx]; let chat = chats[idx];
@ -158,7 +172,7 @@ export default {
} }
chat.lastSendTime = msgInfo.sendTime; chat.lastSendTime = msgInfo.sendTime;
chat.sendNickName = msgInfo.sendNickName; chat.sendNickName = msgInfo.sendNickName;
// 未读加1 // 未读加1
if (!msgInfo.selfSend && msgInfo.status != MESSAGE_STATUS.READED && if (!msgInfo.selfSend && msgInfo.status != MESSAGE_STATUS.READED &&
msgInfo.type != MESSAGE_TYPE.TIP_TEXT) { msgInfo.type != MESSAGE_TYPE.TIP_TEXT) {
@ -186,7 +200,7 @@ export default {
// 根据id顺序插入,防止消息乱序 // 根据id顺序插入,防止消息乱序
let insertPos = chat.messages.length; let insertPos = chat.messages.length;
// 防止 图片、文件 在发送方 显示 在顶端 因为还没存库,id=0 // 防止 图片、文件 在发送方 显示 在顶端 因为还没存库,id=0
if (msgInfo.id && msgInfo.id > 0 ) { if (msgInfo.id && msgInfo.id > 0) {
for (let idx in chat.messages) { for (let idx in chat.messages) {
if (chat.messages[idx].id && msgInfo.id < chat.messages[idx].id) { if (chat.messages[idx].id && msgInfo.id < chat.messages[idx].id) {
insertPos = idx; insertPos = idx;
@ -195,10 +209,10 @@ export default {
} }
} }
} }
if(insertPos == chat.messages.length){ if (insertPos == chat.messages.length) {
// 这种赋值效率最高 // 这种赋值效率最高
chat.messages[insertPos]= msgInfo; chat.messages[insertPos] = msgInfo;
}else{ } else {
chat.messages.splice(insertPos, 0, msgInfo); chat.messages.splice(insertPos, 0, msgInfo);
} }
this.commit("saveToStorage"); this.commit("saveToStorage");
@ -268,13 +282,18 @@ export default {
} }
}, },
refreshChats(state) { refreshChats(state) {
// 将离线消息一次性装载回来
state.chats = JSON.parse(JSON.stringify(state.copyChats)) // 排序
cacheChats.sort((chat1, chat2) => {
return chat2.lastSendTime - chat1.lastSendTime;
});
// 将消息一次性装载回来,只显示前30个会话,多了卡的不行
state.chats = JSON.parse(JSON.stringify(cacheChats.slice(0,30)))
this.commit("saveToStorage"); this.commit("saveToStorage");
}, },
saveToStorage(state) { saveToStorage(state) {
// 加载中不保存,防止卡顿 // 加载中不保存,防止卡顿
if(state.loadingPrivateMsg || state.loadingGroupMsg){ if (this.getters.isLoading()) {
return; return;
} }
let userId = userStore.state.userInfo.id; let userId = userStore.state.userInfo.id;
@ -291,7 +310,6 @@ export default {
}, },
clear(state) { clear(state) {
state.chats = []; state.chats = [];
state.copyChats = [];
state.activeIndex = -1; state.activeIndex = -1;
state.privateMsgMaxId = 0; state.privateMsgMaxId = 0;
state.groupMsgMaxId = 0; state.groupMsgMaxId = 0;
@ -317,11 +335,11 @@ export default {
} }
}, },
getters: { getters: {
findChats: (state) => () => { isLoading: (state) => () => {
/* uniapp线state.copyChats return state.loadingPrivateMsg || state.loadingGroupMsg
等待所有离线消息拉取完成后再统一进行渲染 */ },
let isLoading = state.loadingPrivateMsg || state.loadingGroupMsg; findChats: (state, getters) => () => {
return isLoading ? state.copyChats : state.chats; return getters.isLoading() ? cacheChats : state.chats;
}, },
findChatIdx: (state, getters) => (chat) => { findChatIdx: (state, getters) => (chat) => {
let chats = getters.findChats(); let chats = getters.findChats();

Loading…
Cancel
Save