Open lzwaiwai opened 5 years ago
因为便于分享和传播的优势,越来越多的移动客户端做的直播业务也会出现 H5 的版本当中
这里我们就来解决一些前端直播间页面,因为消息快速刷屏导致的问题。
这里不做过多解释,直接上代码了~
针对维持有关系的数据在处理时序不错位,我们可以将推送过来的数据放入队列中去处理,保证所有的消息都是先后按照推送顺序进行处理的。
这里我们可以利用 async.js:
function QueueTask() { this.Q = async.queue((task, callback) => { console.log(`queue: ${task.name}`); callback(); }); } QueueTask.prototype.push = function (task, callback) { this.Q.push(task, callback); }; const queueTask = new QueueTask(); socket.on('event-1', msg => queueTask.push({ name: 'event-1' }, () => { log('#event-1', msg); })); socket.on('event-2', msg => queueTask.push({ name: 'event-2' }, () => { log('#event-2', msg); }));
针对消息刷屏时,导致的页面卡顿是主要由大量频繁的数据处理与同步的UI渲染同时进行引起的。因为 js 自身单线程设计,正常的处理没法将两者各自运行,不受影响。
这里我们可利用 web worker 进行优化(使用框架的话,可以了解下worker-loader):
index.js:
window.onload = () => { if (window.Worker) { const socketWorker = new Worker('worker.js'); socketWorker.postMessage({ action: 'SOCKET_INIT', params: { transports: ['websocket'] } }); socketWorker.onmessage = (e) => { const { action, data } = e.data; log('#' + action + ': ', data); }; } else { // 兼容处理 } }
worker.js:
importScripts( 'https://cdn.bootcss.com/socket.io/2.1.0/socket.io.js', 'https://cdnjs.cloudflare.com/ajax/libs/async/2.6.1/async.min.js'); function QueueTask() { this.Q = async.queue((task, callback) => { console.log(`queue: ${task.name}`); callback(); }); } QueueTask.prototype.push = function (task, callback) { this.Q.push(task, callback); }; function SocketHandler(socket, queue) { this.socket = socket; this.queue = queue; } SocketHandler.prototype.queuePost = function (event, data, err) { this.queue.push({ name: event }, () => { if (err) { postMessage({ action: event, err }); return; } postMessage({ action: event, data }); }); }; SocketHandler.prototype.on = function (event, callback = (msg) => msg) { this.socket.on(event, msg => { this.queuePost(event, callback(msg)); }); }; SocketHandler.prototype.emit = function (event, param = {}, callback = (msg) => msg) { this.socket.emit(event, param, (err, msg) => { if (err) { this.queuePost(event, null, err); return; } this.queuePost(event, callback(msg)); }); }; function socketInit(params) { let socketInited = false; const socket = io('/', params); const queueTask = new QueueTask(); const socketHandler = new SocketHandler(socket, queueTask); socket.on('connect', () => { if (socketInited) { // 防止重连多次初始化 return; } socketInited = true; socketHandler.queuePost('CONNECT', socket.id); socketHandler.on('RECEIVE_MESSAGE'); }); // 系统事件 socketHandler.on('disconnect'); socketHandler.on('disconnecting'); socketHandler.on('error'); } onmessage = (e) => { const { action, params } = e.data; if (action === 'SOCKET_INIT') { socketInit(params); } };
因为便于分享和传播的优势,越来越多的移动客户端做的直播业务也会出现 H5 的版本当中
这里我们就来解决一些前端直播间页面,因为消息快速刷屏导致的问题。
发现问题
优化方案
这里不做过多解释,直接上代码了~
针对维持有关系的数据在处理时序不错位,我们可以将推送过来的数据放入队列中去处理,保证所有的消息都是先后按照推送顺序进行处理的。
这里我们可以利用 async.js:
针对消息刷屏时,导致的页面卡顿是主要由大量频繁的数据处理与同步的UI渲染同时进行引起的。因为 js 自身单线程设计,正常的处理没法将两者各自运行,不受影响。
这里我们可利用 web worker 进行优化(使用框架的话,可以了解下worker-loader):
index.js:
worker.js: