Google Chrome浏览器不与http2进行多路复用 [英] Google Chrome does not do multiplexing with http2

查看:113
本文介绍了Google Chrome浏览器不与http2进行多路复用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在构建一个Webapp,并通过http2对其进行服务.但是,当我在Google Chrome浏览器(版本59.0.3071.115(正式版本)(64位))的开发人员工具中分析网络时,很明显,多路复用不起作用,因为只有6个活动连接(例如使用http1.1)其余的连接排队.

I am building a webapp and serving it over http2. However when I analyze network in Google Chrome (Version 59.0.3071.115 (Official Build) (64-bit))'s developers tools, it is clear that multiplexing does not work as there are only 6 active connections (like with http1.1) and the rest of connections are queued.

这是为什么?还是我的期望不正确?

Why is this? Or are my expectations not correct?

屏幕截图(您可以看到协议为http2):

The screenshot (you can see that protocol is http2):

更新#1:

  • 后端在nginx 1.13上运行;
  • 我正在使用自定义模块加载程序,该模块一次加载所有脚本(通过在循环中使用async属性创建脚本标签);
  • 该屏幕快照显示,对于第8行及以后的浏览器,浏览器已收到开始下载资源的请求,但该行的白色部分显示此脚本已排队,并且仅在插槽可用时才开始实际下载(请参见第8行,第2、3和4行完成后,第7和9行开始加载;第11、12、13和5、6、7行也是如此.
  • The backend runs on nginx 1.13;
  • I am using custom modules loader which loads all the scripts at once (by creating script tag with async attribute in a loop);
  • The screenshot shows that for line 8 and beyond the browser has received request to start downloading resources, but the white portion of line shows that this scripts were queued and the actual downloading started only when slots became available (see how line 8, 7 and 9 start loading once lines 2, 3 and 4 are done; the same goes for lines 11, 12, 13 and 5, 6, 7).

推荐答案

我认为这是Chrome中的错误,或者至少是不必要的限制.

I think this is a bug in Chrome, or at least a needless restriction.

这很容易测试.

我创建了一个简单的示例HTML文件,该文件下载了25个相同的javascript文件的副本(带有查询参数,使其看起来像不同的资源):

I created a simple example HTML file, which downloads 25 copies of the same javascript file (with a query param to make it look like a different resource):

<!DOCTYPE HTML>
<html>
<head>
        <title>Test for Lots of JS files</title>
        <meta name="robots" content="noindex">
<body>
</body>
        <h1>This is a test for Lots of JS files</h1>

        <script src="/assets/js/test.js?v=01"></script>
        <script src="/assets/js/test.js?v=02"></script>
        <script src="/assets/js/test.js?v=03"></script>
        <script src="/assets/js/test.js?v=04"></script>
        <script src="/assets/js/test.js?v=05"></script>
        <script src="/assets/js/test.js?v=06"></script>
        <script src="/assets/js/test.js?v=07"></script>
        <script src="/assets/js/test.js?v=08"></script>
        <script src="/assets/js/test.js?v=09"></script>
        <script src="/assets/js/test.js?v=10"></script>
        <script src="/assets/js/test.js?v=11"></script>
        <script src="/assets/js/test.js?v=12"></script>
        <script src="/assets/js/test.js?v=13"></script>
        <script src="/assets/js/test.js?v=14"></script>
        <script src="/assets/js/test.js?v=15"></script>
        <script src="/assets/js/test.js?v=16"></script>
        <script src="/assets/js/test.js?v=17"></script>
        <script src="/assets/js/test.js?v=18"></script>
        <script src="/assets/js/test.js?v=19"></script>
        <script src="/assets/js/test.js?v=20"></script>
        <script src="/assets/js/test.js?v=21"></script>
        <script src="/assets/js/test.js?v=22"></script>
        <script src="/assets/js/test.js?v=23"></script>
        <script src="/assets/js/test.js?v=24"></script>
        <script src="/assets/js/test.js?v=25"></script>

</html>

然后我做了同样的事情,但是添加了async属性,以防Chrome决定在处理Javascript时阻止下载:

I then did the same, but adding the async attribute, in case Chrome decide to block downloading while processing the Javascript:

        <script src="/assets/js/test.js?v=01" async=""></script>
        <script src="/assets/js/test.js?v=02" async=""></script>
        ....etc.

相同,但具有defer属性:

and the same again but with the defer attribute:

        <script src="/assets/js/test.js?v=01" defer=""></script>
        <script src="/assets/js/test.js?v=02" defer=""></script>
        ....etc.

/assets/js/test.js文件为空.因此,除了浏览器添加的延迟之外,不会有执行延迟,也不会存在任何依赖关系.

The /assets/js/test.js file was empty. So there would be no execution delays, nor dependencies except those that the browser added.

我看到了一些有趣的结果! Chrome 60.0.3112.78或60.0.3112.101都是这样,我使用的是Apache,但结果与Nginx相同.

I saw some interesting results! This is all with Chrome 60.0.3112.78 or 60.0.3112.101, and I'm using Apache, but saw same results as you saw for Nginx.

使用HTTP/2服务器,我们将看到以下结果:

With an HTTP/2 server we see the following results:

使用普通的script标记可以并行加载所有脚本(但可以按顺序执行). HTTP/1.1下没有6个连接限制:

With a plain script tag all the scripts are loaded in parallel (but presumably executed in order). There is no 6 connection limit as under HTTP/1.1:

使用异步script标记,脚本以6组为一组并行加载-完全如您所述:

With an async script tag the scripts are loaded in parallel in groups of 6 - exactly as you noted:

单击它们将显示它们已通过HTTP/2下载.

Clicking on them shows they WERE downloaded over HTTP/2.

使用defer script标签,脚本与使用async标签的结果相同-一次限制6次下载.

With a defer script tag the scripts is the same as the results for using the async tag - a throttling to 6 downloads at a time.

这没有道理-Chrome会限制您的Javascript下载,但前提是您使用async或defer来改善下载以阻止呈现!

This does not make sense - Chrome is restricting your Javascript downloads, but only if you use async or defer to improve your downloads from blocking rendering!

正如sbordet所述,视口中的图像不会发生这种情况-因此多路复用确实可以在Chrome上运行,但对于异步或延迟模式下的Javascript来说,它似乎受到了不必要的限制.如果您不打算在HTTP/2下不再将脚本捆绑在一起,这是一个真正的限制,因为许多人建议您不再需要这样做.

As sbordet stated, the same does not happen for images in the viewport - so multiplexing DOES work on Chrome, it just appears to be needlessly limited for Javascript in async or defer mode. This is a real limitation, if you are considering not bundling scripts together any more under HTTP/2, as many advise you no longer need to do.

在Firefox和Edge上,不会也会发生同样的情况.尽管它确实发生在Opera(基于Chromium的浏览器)上.

The same does not happen on Firefox, nor Edge. Though it does happen on Opera (a Chromium based browser).

所以这是个坏消息.好消息是他们可能"已经修复了它.当我尝试Chrome Canary(62.0.3190.0)时,我无法重复此行为.但是,当我将Web Page Test与Canary一起使用时(它在用户代理字符串中提供62.0.3190.1,因此实际上应该是相同的),它是可重复的,因此不能100%地确定他们在此之后已解决此问题.全部...

So that's the bad news. The good news is that they "may" have fixed it. When I try Chrome Canary (62.0.3190.0) I can't repeat this behaviour. However when I use Web Page Test with Canary (which it gives 62.0.3190.1 in the user agent string, so should be practically the same) it is repeatable, so not 100% sure they have fixed this after all...

为此向Chrome团队提出了一个错误,因此将看到他们在说什么:

Have raised a bug with the Chrome team for this so will see what they say: https://bugs.chromium.org/p/chromium/issues/detail?id=757191

总而言之,目前服务器和客户端上的HTTP/2似乎有些变化,因为双方都在调整和调整其实现以从这个相对较新的协议中获得最佳使用.不过,自从Google从其SDPY实现开始(HTTP/2很大程度上基于它)开始以来,就看到Chrome受到了冲击,这令人感到惊讶,因此您可以期望它们领先于曲线而不会落后……

All in all, HTTP/2 on both server and client does seem a little in flux at the moment, as both sides tweak and tune their implementations to get optimal use out of this still relatively new protocol. Still, it's surprising to see Chrome hit with this since Google started this off with their SDPY implementation (which HTTP/2 is heavily based upon) so you would expect them to be ahead of the curve not behind...

**更新**

Chrome小组返回并确认这是对当前在Chrome中实施HTTP/2的限制.当HTTP/2允许立即调用许多资产时,他们看到了性能问题,因此将非关键项目(包括异步/延迟和在视口中不可见的项目)限制为6的HTTP/1.1限制.

Chrome team got back and confirm this is a restriction of current implementation of HTTP/2 in Chrome. They were seeing performance issues when many assets very called at once, as HTTP/2 allows, so restrict non-critical items (including async/defer and items not visible in the viewport) to HTTP/1.1 limit of 6.

即使HTTP/2具有在请求发送之后对请求进行优先级排序的概念,但是在对请求进行优先级分配和发送之前(例如,检查缓存,Cookie等)就已经看到了性能问题,因此HTTP/2优先级排序无济于事在这里.

Even though HTTP/2 has concept of prioritisation of requests after they are sent, the performance issues were seen before they were prioritised and sent (e.g. checking cache, cookies... etc) so HTTP/2 prioritisation doesn't help here.

他们希望将来能改善这一点.

They hope to improve this in future.

所以我猜对了,这是一个实现问题,因为我们已经习惯了新的HTTP/2世界,并且必须为此优化浏览器和服务器!

So guess I was right that it's an implementation issue as we get used to the new HTTP/2 world and have to optimise our browsers and servers for it!

这篇关于Google Chrome浏览器不与http2进行多路复用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆