克服移动 safari 的连接限制

Overcoming connection limitation with mobile safari

我最近发现移动版 safari(在 iOS 9.1 上——虽然不确定旧版 safari)有一个不幸的问题,涉及多个连接和图像。如果您在加载一个页面时有六张图片,它将延迟在这六张图片之后加载的 XHR 请求一个巨大的滞后时间(大约 30 秒)。

例如,我使用标准 NodeJS/Express 服务器加载了以下内容,并在警报出现之前看到了巨大的延迟 - 尽管事实上所有图像都只有几 KB,而且我可以清楚地看到他们都装满了。开发控制台还显示加载的图像,但不显示 XHR 请求。下载文件的时间很短,但延迟很大。

这在任何其他浏览器(移动 chrome、常规 safari 等)上都不是问题。

示例问题html:

<!DOCTYPE html>
<html>
<head>

</head>
<body>

<img src="/static/images/home/payment.png">
<img src="/static/images/home/couple-present-mobile.jpg">
<img src="/static/images/general/welcome.jpg">
<img src="/static/images/general/arrow-down.png">
<img src="/static/images/general/arrow-right.png">
<img src="/static/images/general/check.png">
<script>
    
            var url = '/static/test.html'
            var xhr = new XMLHttpRequest();
            xhr.open('GET', encodeURI(url));

            xhr.onload = function() {
                  alert(url) //This takes forever
            };
            xhr.send();

</script>
</body>
</html>

奇怪的是,如果你 运行 XHR 请求在有 6 张图片之前,它会完美地工作。事实上,如果你甚至做了下面这样的事情,那也没关系。我认为这是可行的,因为背景 CSS 图像必须在启动 XHR 后检索 URL。

用背景 css 图像替换其中一个 img 标签,它起作用了:

<!DOCTYPE html>
<html>
<head>

    <style>
        .test {
            background-image: url("/static/images/home/check.png");
            height: 400px;
        }
    </style>

</head>
<body>

<img src="/static/images/home/payment.png">
<img src="/static/images/home/couple-present-mobile.jpg">
<img src="/static/images/general/welcome.jpg">
<img src="/static/images/general/arrow-down.png">
<img src="/static/images/general/arrow-right.png">
<!--<img src="/static/images/general/check.png">   REMOVE THIS LINE and add the background image instead--> 
  <div class="test"></div>
<script>
            var url = '/static/test.html;

            var xhr = new XMLHttpRequest();
            xhr.open('GET', encodeURI(url));

            xhr.onload = function() {
                console.log(url) //NO DELAYS!
            };
            xhr.send();
</script>
</body>
</html>

另外我发现只要运行 7个同时的XHR请求也不会导致这个问题(如下图):

<!DOCTYPE html>
<html>
<head>


</head>
<body>


<script>
    var urls = ['/static/images/home/payment.png',
        '/static/images/home/couple-present-mobile.jpg',
        '/static/images/general/arrow-right.png',
        '/static/images/general/arrow-down.png',
        '/static/images/general/welcome.jpg',
        '/static/images/general/check.png',
        '/static/test.html'];

    for(var i = 0, ii = urls.length; i < ii; i++){
        (function(){
            var url = urls[i];

            var xhr = new XMLHttpRequest();
            xhr.open('GET', encodeURI(url));

            xhr.onload = function() {
                console.log(url)
            };
            xhr.send();
        })()
    }




</script>
</body>
</html>

有没有人遇到过这个问题并找到了一种方法来解决它而不减少图像的数量或将它们放在精灵或其他东西中?

我最终用来解决这个问题的技巧是从不同的主机加载图像。为简单起见,如果浏览器检测到主机是 www.domain.com,我将从 domain.com 加载图像,反之亦然。您也可以让所有图像都来自某个主机,例如 images.domain.com,而将您的 api 和其他内容保留在另一个主机上。

不是最理想或最优雅的解决方案,但它实施起来非常简单并解决了问题。