首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Http性能-许多小请求或一个大请求

Http性能-许多小请求或一个大请求
EN

Stack Overflow用户
提问于 2017-04-29 04:31:06
回答 4查看 25.5K关注 0票数 44

场景:

  1. 在我的网站上,我展示书籍。
  2. 用户可以将每本书添加到“稍后阅读”列表中。

行为:

当用户进入网站时,他们会收到一份图书列表。其中一些已经出现在他们的“稍后阅读”列表中,有些则没有。

用户在每本书旁边都有一个指示,告诉他们是否将书添加到列表中。

我的问题

我正在辩论哪一种选择是我的理想选择。

选项1:

  1. 对于每一本书,询问服务器是否已经存在于用户的列表中。
  2. 更新每本书的指示符。

Pro:对服务器的请求非常小,并且响应非常容易(真或假)。

Con:在一个包含30本书的页面中,我将发送30个单独的http请求,这些请求可以阻止套接字,并且考虑到浏览器和服务器必须对每个事务执行整个握手,速度相当慢。

备选方案2:

  1. 我对服务器进行了一次查询,并将"Read“列表中的全部图书列表作为数组获得响应。
  2. 在浏览器中,我检查数组,并根据是否存在于数组中更新每本书的指示。

Pro:我只提出一个请求,并同时更新所有书籍的指示符。

Con:“稍后阅读”列表可能有数百本书,而传递一个大数组可能会被证明是缓慢和过度的。特别是当屏幕上没有出现30本书,但只有2-3本时.(也就是说,我想检查列表中是否有一本书,为此,我让服务器从列表中向客户机发送整个图书列表)。

So,

你会用哪种方式来最大化性能:1还是2?

我还有其他选择吗?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2017-04-29 07:40:26

选项1听起来不错,但在可伸缩性方面有一个很大的问题。

选项2缓解了这个可伸缩性问题,我们可以改进它的设计:

客户端,通过javascript,只收集一次显示的图书ids和查询一次,通过ajax获取一系列阅读--稍后的信息,仅用于这30本书。通过这种方式,您仍然可以快速地为页面提供服务,并请求一小组附加信息,一次只需一个http请求。

服务器端,您可以进一步提高缓存内存中的每个用户的读-后ids数组。

票数 14
EN

Stack Overflow用户

发布于 2017-04-29 04:42:19

我认为2017年及以后,解决方案更多的不是关于整体性能,而是关于用户体验和用户期望。

现在,用户不允许,而不是,可以容忍延迟。在这个意义上,复杂的用户界面试图尽快响应。因此:如果您可以使用这些小请求来使用户能够快速完成某件事情(而不是等待2秒来等待这个大请求的返回),那么您应该更喜欢这个解决方案。

据我所知,有许多“高保真度”的网站,其中一个网页可能发送50,100个请求。因此,我认为这是常见的做法!

也许它在这里是有帮助的:SE-Radi.net播客第277集在尾部延迟的背景下深入讨论了这个主题。

票数 37
EN

Stack Overflow用户

发布于 2022-05-17 11:56:19

实时测试、解决方案和真实世界数据

这个答案是用JavaScript编写的,包括易于理解的代码示例。

引言

OP询问了向“稍后阅读”API发出请求的最有效方法,每个请求都需要等待一段时间,而后端保存了这本书。

对于这个答案,我创建了一个“读取后”API端点的演示,每个请求都随机地等待从70-130毫秒来保存每本书。

我每一次都在测试30本书。

最后,我们将通过测量我们将采取的每一个操作的专业实际运行时来看到每个方法的最佳结果。

同步请求(OP的选项1)

在这里,我们将通过JS来运行每个调用,一个接一个同步运行。

守则:

代码语言:javascript
复制
async function saveBooksSync() {
    console.time('save-books-sync');

    // creates 30 book IDs
    const booksIds = Array.from({length: 30}, (_, i) => i + 1);

    // creates 30 API links for each request
    const urls = booksIds.map(bookId => `http://localhost:7777/books/read-later?bookId=${bookId}`);

    for(let url of urls) {
        const response = await fetch(url);
        const json = await response.json();
        console.log(json);
    }
    console.timeEnd('save-books-sync');
}

运行时: 3712.40087890625 ms

一个大请求

虽然我们不会创建到服务器的许多请求连接,但运行时本身就说明了这一点。

守则:

代码语言:javascript
复制
async function saveAllBooksAtOnce() {
    console.time('save-all-books')
    const booksIds = Array.from({length: 30}, (_, i) => i + 1);
    const url = `http://localhost:7777/books/read-later?all=1`;

    const response = await fetch(url);
    const json = await response.json();
    console.timeEnd('save-all-books');
}

运行时: 3486.71484375 ms

并行异步请求(解决方案)

这里发生了神奇的事情,解决方案来问,什么是最有效的请求方法。

这里我们制作了30并行小请求,并取得了惊人的效果。

守则:

代码语言:javascript
复制
async function saveBooksParallel() {
    console.time('save-books')
    const booksIds = Array.from({length: 30}, (_, i) => i + 1);
    const urls = booksIds.map(bookId => `http://localhost:7777/books/read-later?bookId=${bookId}`);

    const promises = urls.map((url) =>
        fetch(url).then((response) => response.json())
    );

    const data = await Promise.all(promises);

    console.log(data);
    console.timeEnd('save-books');
}

在这个异步并行示例中,我使用了Promise.all方法。

Promise.all()方法将可迭代的承诺作为输入,并返回一个解析为输入承诺的结果数组的承诺

运行时: 668.47705078125 ms

结论

结果很清楚,发出这些多个请求的最有效方法是在异步并行中这样做。

更新:我遵循@Iglesias的请求删除数据输出的console.log(),因为(大概)它占用了大量的资源。

--这些是运行时的结果:

  • 同步请求:3371.695 ms
  • 一大请求:3358.269 ms
  • 并行异步请求:613.506

更新结论:运行时几乎保持不变,从而反映了并行异步请求被速度无法匹配的现实

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43691808

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档