专栏名称: 前端外刊评论
最新、最前沿的前端资讯,最有深入、最干前端相关的技术译文。
目录
相关文章推荐
商务河北  ·  经开区“美•强•优”三重奏 ·  10 小时前  
前端早读课  ·  【第3453期】圈复杂度在转转前端质量体系中的应用 ·  20 小时前  
奇舞精选  ·  从 DeepSeek 看25年前端的一个小趋势 ·  昨天  
奇舞精选  ·  从 DeepSeek 看25年前端的一个小趋势 ·  昨天  
51好读  ›  专栏  ›  前端外刊评论

到底是用 Ajax 还是 Socket.IO? 用测试数据说话!

前端外刊评论  · 公众号  · 前端  · 2019-11-19 09:00

正文

本文译自 A Node.js speed dilemma: AJAX or Socket.IO?。

当我开始写自己的第一个 Node.js 项目时,发现处理浏览器(客户端)和中间件之间的通信是不可避免的。

我已经非常熟悉 Ajax 了,但是在学习 Node.js 时,我发现了 Socket.IO 模块,甚至在互联网上发现了一些非常不错的代码案例,非常好用。

所以这很快成为一个难题: 应该选哪个,Ajax 还是 sockets.io?

显然,由于我的经验非常有限,所以我需要更多的信息。换句话说应该好好的 Google 一番。

显然相关的信息非常多,但是需要过滤掉那些没用的 "噪音",才能得到真正有用的内容。先和大家分享一些相关的链接:

  • http://stackoverflow.com/questions/7193033/nodejs-ajax-vs-socket-io-pros-and-cons
  • http://podefr.tumblr.com/post/22553968711/an-innovative-way-to-replace-ajax-and-jsonp-using
  • http://stackoverflow.com/questions/4848642/what-is-the-disadvantage-of-using-websocket-socket-io-where-ajax-will-do?rq=1
  • http://howtonode.org/websockets-socketio

总而言之,以下是我发现的东西:

  1. Socket.IO 在客户端和服务器间的用的是持续连接,所以很容易就会达到服务器端所允许的并发连接数的上限,而相同的资源可以支持更多的 Ajax 异步请求。
  2. 使用AJAX,你可以请求 RESTful 接口。这意味着你可以利用现有的 HTTP 服务,例如:代理 缓存 请求和带条件的GET请求。
  3. 与 Socket.IO 相比,Ajax 的开销更大(例如:HTTP头,Cookie等)。
  4. Ajax 通常比 Socket.IO快 …
  5. Socket.IO 可以进行双向通信,其中客户端或服务器端都可以发起请求。在 AJAX 中,只有客户才能发起请求。

现在对于我自己的程序,最感兴趣的是 发起请求并从(Node.js)服务器获取数据的速度!

所以我决定对 Ajax 和 socket 速度进行测试,看看哪一个更快(至少在我的硬件和软件环境下)!我的硬件环境是:i5 处理器,8GB 内存和英特尔 X25 SSD 硬盘。

严格来说,任何性能测试都取决于你的硬件和软件配置,一定要在你自己的环境中去测试,不要过于依赖你在互联网上找到的各种信息,因为还有更多的问题需要你自己去发现。

我要做的测试需要满足以下要求:

  • 测试:
    • Ajax
    • Socket.IO 持续连接模式
    • Socket.IO 非持续链接模式
  • 测试客户端与服务器之间进行 10、100,、250、500 条数据交换时的情况
  • 中间件服务器(Node.js Web 服务器)和客户端(浏览器)之间交换的每条数据都是一个 4KBytes 的随机数据串
  • 在 release(非调试)模式下运行服务器
  • 用 Firefox 作为客户端
  • 最小化控制台消息输出,不管是服务器端还是客户端
  • 在客户端页面硬性重新加载后进行每个测试
  • 每次测试至少重复 3 次,以确保结果一致

测试 Socket.IO,使用持久连接

我写了一小型的 小Node.js 服务器,用来处理客户端请求:

io.sockets.on('connection', function (client) {    client.on('send_me_data', function (idx) {        client.emit('you_have_data', idx, random_string(4096));    });});

这是我用于测试的 JS 客户端脚本:

var socket = io.connect(document.location.href); socket.on('you_have_data', function (idx, data) {    var end_time = new Date();    total_time += end_time - start_time;    logMsg(total_time + '(ms.) [' + idx + '] - Received ' + data.length + ' bytes.');    if (idx++ < countMax) {        setTimeout(function () {            start_time = new Date();            socket.emit('send_me_data', idx);        }, 500);    }});

测试 Socket.IO,使用非持久连接

这次测试中的每次数据交换,我都打开一个新的 socket-io 连接。

Node.js 服务器代码与上一个类似,但是我决定在连接之后立即发送客户端数据,因为每次数据交换都会启动一个新的连接:

io.sockets.on('connection', function (client) {    client.emit('you_have_data', random_string(4096));});

客户端测试代码:

function exchange(idx) {    var start_time = new Date();    var socket = io.connect(document.location.href, {'force new connection' : true});     socket.on('you_have_data', function (data) {        var end_time = new Date();        total_time += end_time - start_time;        socket.removeAllListeners();        socket.disconnect();        logMsg(total_time + '(ms.) [' + idx + '] - Received ' + data.length + ' bytes.');                 if (idx++ < countMax) {            setTimeout(function () {                exchange(idx);            }, 500);        }    });}

测试 Ajax

最后是 Ajax 测试。

Node.js 服务器代码与以前的代码不同:

res.writeHead(200, {'Content-Type' : 'text/plain'});res.end('_testcb(\'{"message": "' + random_string(4096) + '"}\')');

至于客户端代码,这是我以前测试的:

function exchange(idx) {    var start_time = new Date();     $.ajax({        url : 'http://localhost:8080/',        dataType : "jsonp",        jsonpCallback : "_testcb",        timeout : 300,        success : function (data) {            var end_time = new Date();            total_time += end_time - start_time;            logMsg(total_time + '(ms.) [' + idx + '] - Received ' + data.length + ' bytes.');                         if (idx++ < countMax) {                setTimeout(function () {                    exchange(idx);                }, 500);            }        },        error : function (jqXHR, textStatus, errorThrown) {            alert('Error: ' + textStatus + " " + errorThrown);        }    });}

需要注意的是在 Node.js 中使用 Ajax 时,需要考虑到可能的跨域请求和同源策略问题,所以应该用基于 JSONP 的格式。

测试结果的数据

我分别运行了 10、100、250 和 500 个数据交换的测试,这是最终测试结果:

Data exchanges Socket.IO非持续连接 (ms.) AJAX (ms.) Socket.IO 持续连接 (ms.)
10 90 40 32
100 900 320 340
250 2,400 800 830
500 4,900 1,500 1,600

我们从测试结果结果中注意到:







请到「今天看啥」查看全文