如何提升单页应用的体验

想起公司里的domeos项目,angularjs单页应用。

其实还有很多问题,可以优化。

1.轮询 vs websocket数据推送

举个例子:

假设,项目中有一个用户A,他对项目有读写权限。

这会儿,当A用户正在修改项目的一些配置时(只有写权限的人才能修改项目配置),master用户把A用户的权限修改成了只读权限。

A用户对项目的修改就失败了,弹出模态框“对不起,您没有权限。”。然后页面切换到权限管理页面。

我们之前的项目也可以实现上述功能。我们使用的是每4s获取一次userlist表,更新页面状态。

例如:

//每隔4000ms就获取一次data
var timeout = void 0,var freshBuildList = function freshBuildList() {
            if (timeout) {
                $timeout.cancel(timeout);
            }
            loadBalancerService.getData().then(function (res) {
                _this.loadBalancerList = res.data.result || [];
            }).finally(function () {
                timeout = $timeout(freshBuildList,4000);
            });
        };

也就是说,每隔4s,都要与服务器建立一个tcp连接。如果用户数量很大,服务器的负载很高呀。

html5的websocket可以实现后台数据推送。让后台数据更新的时候,不需要前台请求。后台直接去推送数据,大大减轻了服务器的负载。然而,websocket需要使用ws协议代替http协议。

(1)socket.io

这里有一个socket.io。它是一个websocket api。
Socket.IO还提供了一个NodeJS API,它看起来非常像客户端API。

客户端:

先把socket.io引入到页面中

<script src="http://cdn.socket.io/stable/socket.io.js"></script>

然后就可以使用啦。

// 创建Socket.IO实例,建立连接
var socket= new io.Socket('localhost',{ 
  port: 8080 
}); 
socket.connect(); 

// 添加一个连接监听器
socket.on('connect',function() { 
  console.log('Client has connected to the server!'); 
});

// 添加一个消息监听器
socket.on('message',function(data) { 
  console.log('Received a message from the server!',data); 
});

// 添加一个关闭连接的监听器
socket.on('disconnect',function() { 
  console.log('The client has disconnected!'); 
}); 

// 通过Socket发送一条消息到服务器
function sendMessageToServer(message) { 
  socket.send(message); 
}

这里,socket.io为不同的协议封装了相同的api接口。
包括:
WebSocket
Flash Socket
AJAX long-polling
AJAX multipart streaming
IFrame
JSONP polling

服务端:
node.js端 socket-server.js

// 需要HTTP 模块来启动服务器和Socket.IO
var http= require('http'),io= require('socket.io'); 

// 在8080端口启动服务器
var server= http.createServer(function(req,res){ 
  // 发送HTML的headers和message
  res.writeHead(200,{ 'Content-Type': 'text/html' }); 
  res.end('<h1>Hello Socket Lover!</h1>'); 
}); 
server.listen(8080); 

// 创建一个Socket.IO实例,把它传递给服务器
var socket= io.listen(server); 

// 添加一个连接监听器
socket.on('connection',function(client){ 

  // 成功!现在开始监听接收到的消息
  client.on('message',function(event){ 
    console.log('Received message from client!',event); 
  }); 
  client.on('disconnect',function(){ 
    clearInterval(interval); 
    console.log('Server has disconnected'); 
  }); 
});

在命令行输入

node socket-server.js

现在客户端和服务器都能来回推送消息了!在NodeJS脚本内,可以使用简单的JavaScript创建一个定期消息发送器:

// 创建一个定期(每5秒)发送消息到客户端的发送器
var interval= setInterval(function() { 
  client.send('This is a message from the server! ' + new Date().getTime()); 
},5000);

服务器端将会每5秒推送消息到客户端!

为了socket.io,还要在中间架设一层node.js。感觉开发难度会变大呢。不过带给用户的体验会变好很多。

2.断线重连

如果不适用websocket机制,而是使用每隔4s去服务器get数据的方式,就没有断线重连的苦恼了。

因为,每隔4s都做了断线重连的事情。

那么,使用websocket之后,怎么实现断线重连捏?

就是在客户端关闭连接的时候,去reconnect

// 添加一个关闭连接的监听器
socket.on('disconnect',function() { 
  console.log('The client has disconnected!'); 
  reconnect();
}); 

function reconnect(){
  setTimeout(function(){
       //重连
  },5000);
}

网上的大大是这么说的。不知道会出现什么其他的问题。。。

3.本地缓存

现在我们在填写一个form的时候,还没有提交之前,网断了。但是表单的数据不应该清零,而应该保存在本地,用户刷新一次页面,填写的数据还在。

localstorage 或者 sessionstorage来存储。

4.表单多次提交

项目之前在针对表单多次提交的问题时,还没有不错的解决方案也。

前几天注意到,在github创建一个项目的时候,在国内网速慢一些,点击提交按钮之后很长时间才能刷新页面显示提交之后的页面。

在这期间,github的提交按钮由可点击变为不可点击,内容由“提交”变为“提交connecting”。

后台的实现思路可能是,未收到服务器响应之前,就设置按钮不可点击。给一个用户友好的提示,知道受到响应,然后跳转。

相关文章

ANGULAR.JS:NG-SELECTANDNG-OPTIONSPS:其实看英文文档比看中...
AngularJS中使用Chart.js制折线图与饼图实例  Chart.js 是...
IE浏览器兼容性后续前言 继续尝试解决IE浏览器兼容性问题,...
Angular实现下拉菜单多选写这篇文章时,引用文章地址如下:h...
在AngularJS应用中集成科大讯飞语音输入功能前言 根据项目...
Angular数据更新不及时问题探讨前言 在修复控制角标正确变...