优化消息平滑,让发消息速度变化不要太频繁

This commit is contained in:
John Smith 2021-01-24 19:10:25 +08:00
parent f50652af83
commit d3cd5a3120

View File

@ -47,7 +47,21 @@ import MembershipItem from './MembershipItem.vue'
import PaidMessage from './PaidMessage.vue' import PaidMessage from './PaidMessage.vue'
import * as constants from './constants' import * as constants from './constants'
//
const NEED_SMOOTH_MESSAGE_TYPES = [
constants.MESSAGE_TYPE_TEXT,
constants.MESSAGE_TYPE_GIFT,
constants.MESSAGE_TYPE_MEMBER,
constants.MESSAGE_TYPE_SUPER_CHAT
]
//
const MESSAGE_MIN_INTERVAL = 80
const MESSAGE_MAX_INTERVAL = 1000
// MESSAGE_MIN_INTERVAL
// 84 = ceil((1000 / 60) * 5)
const CHAT_SMOOTH_ANIMATION_TIME_MS = 84 const CHAT_SMOOTH_ANIMATION_TIME_MS = 84
//
const SCROLLED_TO_BOTTOM_EPSILON = 15 const SCROLLED_TO_BOTTOM_EPSILON = 15
export default { export default {
@ -239,36 +253,53 @@ export default {
}, },
enqueueMessages(messages) { enqueueMessages(messages) {
if (this.lastEnqueueTime) { //
let interval = new Date() - this.lastEnqueueTime if (!this.lastEnqueueTime) {
// B1S this.lastEnqueueTime = new Date()
if (interval > 100) { } else {
let curTime = new Date()
let interval = curTime - this.lastEnqueueTime
//
if (interval > 1000) {
this.enqueueIntervals.push(interval) this.enqueueIntervals.push(interval)
if (this.enqueueIntervals.length > 5) { if (this.enqueueIntervals.length > 5) {
this.enqueueIntervals.splice(0, this.enqueueIntervals.length - 5) this.enqueueIntervals.splice(0, this.enqueueIntervals.length - 5)
} }
this.estimatedEnqueueInterval = Math.max(...this.enqueueIntervals) this.estimatedEnqueueInterval = Math.max(...this.enqueueIntervals)
this.lastEnqueueTime = curTime
} }
} }
this.lastEnqueueTime = new Date()
// // messagesmessageGroup1
let messageGroup = [] let messageGroup = []
for (let message of messages) { for (let message of messages) {
messageGroup.push(message) messageGroup.push(message)
if (message.type !== constants.MESSAGE_TYPE_DEL && message.type !== constants.MESSAGE_TYPE_UPDATE) { if (this.messageNeedSmooth(message)) {
this.smoothedMessageQueue.push(messageGroup) this.smoothedMessageQueue.push(messageGroup)
messageGroup = [] messageGroup = []
} }
} }
//
if (messageGroup.length > 0) { if (messageGroup.length > 0) {
if (this.smoothedMessageQueue.length > 0) {
//
let lastMessageGroup = this.smoothedMessageQueue[this.smoothedMessageQueue.length - 1]
for (let message of messageGroup) {
lastMessageGroup.push(message)
}
} else {
//
this.smoothedMessageQueue.push(messageGroup) this.smoothedMessageQueue.push(messageGroup)
}
} }
if (!this.emitSmoothedMessageTimerId) { if (!this.emitSmoothedMessageTimerId) {
this.emitSmoothedMessageTimerId = window.setTimeout(this.emitSmoothedMessages) this.emitSmoothedMessageTimerId = window.setTimeout(this.emitSmoothedMessages)
} }
}, },
messageNeedSmooth({type}) {
return NEED_SMOOTH_MESSAGE_TYPES.indexOf(type) !== -1
},
emitSmoothedMessages() { emitSmoothedMessages() {
this.emitSmoothedMessageTimerId = null this.emitSmoothedMessageTimerId = null
if (this.smoothedMessageQueue.length <= 0) { if (this.smoothedMessageQueue.length <= 0) {
@ -280,21 +311,18 @@ export default {
if (this.estimatedEnqueueInterval) { if (this.estimatedEnqueueInterval) {
estimatedNextEnqueueRemainTime = Math.max(this.lastEnqueueTime - new Date() + this.estimatedEnqueueInterval, 1) estimatedNextEnqueueRemainTime = Math.max(this.lastEnqueueTime - new Date() + this.estimatedEnqueueInterval, 1)
} }
// 80ms/3 //
const MIN_SLEEP_TIME = 80
const MAX_SLEEP_TIME = 1000
const MAX_REMAIN_GROUP_NUM = 3
// //
let shouldEmitGroupNum = Math.max(this.smoothedMessageQueue.length - MAX_REMAIN_GROUP_NUM, 0) let shouldEmitGroupNum = Math.max(this.smoothedMessageQueue.length, 0)
// //
let maxCanEmitCount = estimatedNextEnqueueRemainTime / MIN_SLEEP_TIME let maxCanEmitCount = estimatedNextEnqueueRemainTime / MESSAGE_MIN_INTERVAL
// //
let groupNumToEmit let groupNumToEmit
if (shouldEmitGroupNum < maxCanEmitCount) { if (shouldEmitGroupNum < maxCanEmitCount) {
// 13 // 1
groupNumToEmit = 1 groupNumToEmit = 1
} else { } else {
// 13 // 1
groupNumToEmit = Math.ceil(shouldEmitGroupNum / maxCanEmitCount) groupNumToEmit = Math.ceil(shouldEmitGroupNum / maxCanEmitCount)
} }
@ -314,17 +342,17 @@ export default {
// //
let sleepTime let sleepTime
if (groupNumToEmit === 1) { if (groupNumToEmit === 1) {
// 便[MIN_SLEEP_TIME, MAX_SLEEP_TIME] // 便[MESSAGE_MIN_INTERVAL, MESSAGE_MAX_INTERVAL]
sleepTime = estimatedNextEnqueueRemainTime / this.smoothedMessageQueue.length sleepTime = estimatedNextEnqueueRemainTime / this.smoothedMessageQueue.length
sleepTime *= 0.5 + Math.random() sleepTime *= 0.5 + Math.random()
if (sleepTime > MAX_SLEEP_TIME) { if (sleepTime > MESSAGE_MAX_INTERVAL) {
sleepTime = MAX_SLEEP_TIME sleepTime = MESSAGE_MAX_INTERVAL
} else if (sleepTime < MIN_SLEEP_TIME) { } else if (sleepTime < MESSAGE_MIN_INTERVAL) {
sleepTime = MIN_SLEEP_TIME sleepTime = MESSAGE_MIN_INTERVAL
} }
} else { } else {
// //
sleepTime = MIN_SLEEP_TIME sleepTime = MESSAGE_MIN_INTERVAL
} }
this.emitSmoothedMessageTimerId = window.setTimeout(this.emitSmoothedMessages, sleepTime) this.emitSmoothedMessageTimerId = window.setTimeout(this.emitSmoothedMessages, sleepTime)
}, },
@ -425,7 +453,8 @@ export default {
} }
this.messagesBuffer = [] this.messagesBuffer = []
// items // items
this.$nextTick(this.showNewMessages) await this.$nextTick()
this.showNewMessages()
}, },
showNewMessages() { showNewMessages() {
let hasScrollBar = this.$refs.items.clientHeight > this.$refs.scroller.clientHeight let hasScrollBar = this.$refs.items.clientHeight > this.$refs.scroller.clientHeight