连续刷新HTML表(SPA)的最佳选择

时间:2019-12-17 14:11:59

标签: javascript ajax reactjs vue.js frontend

我们正在寻找一种连续更新HTML表(SPA)以显示收到的“订单”的简单方法。当前,每次我们要查看新订单时都必须刷​​新页面。凭借有限的前端知识,我可以想到3种方法。我希望您能从最好的方法中获得建议:

1-定期(每10秒一次)发出AJAX请求,然后使用JS框架(Vue或React)更新表。

2-使用WebSocket(而不是HTTP)使服务器能够在收到新订单时推送数据。

3-使用通知服务:后端将通知发送到订阅了客户端浏览器的主题。这会触发前端框架中的一些代码来向服务器请求新订单。那可行吗?

同样,我对前端框架(VueJS,React)如何或不能做到的知识非常有限。我不希望这成为一个全面的项目。我们只是在寻找一个(很希望!)非常常见的用例的简单解决方案。谢谢。

3 个答案:

答案 0 :(得分:3)

这完全取决于您希望在给定时间运行多少个Web客户端实例。

即使没有更改,也要轮询数据更改,并且同时从许多Web客户端进行操作可能会导致对您自己的基础结构的DoS攻击。

WebSockets甚至是Server-sent-events应该是一个更可靠的解决方案。

实现客户端很简单,但是在后端进行实际的更改检测会涉及到数据的某种版本控制。在数据库行级别上的哈希应该可以解决问题。还有更复杂的解决方案。

您可以进一步详细说明用例吗?

答案 1 :(得分:1)

正如您提到的,主要有两种方法。我见过的大多数应用程序都在使用React js(因为我对vue没有任何想法),因此呈现数据的速度很快(更新dom-适合您的情况)。

因此,对于我们的一个应用程序,我们还使用了15秒的轮询,并且运行良好。在这种情况下,您可以做的基本上是如果该选项卡未处于活动状态,则可以通过选中visibiltyState(chrome和firefox可以正常工作)来关闭轮询,并且可以在该选项卡处于非活动状态时暂停轮询this感谢@oriol,效果很好。

如所讨论的,另一个好的方法是套接字。您需要一个像nodejs或golang这样的后端,在那里您将有需要发送数据的空间,并且将使用一些称为socket-io

的库在前端对它们进行侦听。

我听说过使用appollo graphql,但从未尝试过,您也可以进行检查。

我认为这样可以更好地理解问题。

因此,我认为,如果您能够负担得起数据量和时间,那么使用setInterval进行轮询很容易,否则大多数人都会建议使用套接字。

因此,我认为对于一个更好的解决方案,套接字将是一个不错的选择,但易于实现,并且易于从客户端setInterval买得起。

答案 2 :(得分:1)

编辑后的答案

正如评论中提到的,如果您打算有多个并发请求,Websocket实际上是提高性能的一种方法。 Lelio Faieta在有关长轮询性能的评论中链接了一个有趣的帖子:In what situations would AJAX long/short polling be preferred over HTML5 WebSockets?

旧答案

如果必须每10秒钟刷新一次数据,则上面的注释中提到的ajax调用就可以了。正如您提到的那样,使用jQuery或更高级的框架很容易实现。 请在下面找到一个真正的简短代码段,例如,每10秒调用一次API并更新表的第一行。

window.setInterval(function() {
  $.getJSON("https://reqres.in/api/users?page=2", function( data ) {
    let length = data.data.length;
    let index = Math.floor(Math.random() * length);
    $("#myTable td:eq(1)").html(data.data[index].first_name);
  })
}, 10000)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="myTable">
  <tr>
    <td>Name</td>
    <td>Value</td>
  </tr>
</table>

如您所见,除了您自己的数据逻辑需求之外,这很容易实现。

但是,您可能有动机使用Websocket而不是Ajax查询。这些已在本文Why use AJAX when WebSockets is available?

中进行了讨论