国外网站速度慢,是为什么 / 随笔谈

可能你心中会直接给出一个答案。不,不提那个,我想从原理上说起。

十年前跟现在的网络慢,原因并不同

还记得十年前,我一不小心打开了 Facebook,虽然能打开,但速度极慢。

那个时候的网页都很单纯,也并不大。此时速度慢只能归结于:这是一个远在美国的网站,所有的访问需要经过海底光缆,刚好那个时候国际网络比较慢咯。

十年过去了,互联网产业也有了很多的变化。其中很重要的是,CDN 越来越普遍。很多网站用上它之后,服务器跟客户端的距离变近了。我们访问很多网站的时候,看起来是个在美国的公司,但实际上连接的却是在香港、台湾甚至境内的 CDN 服务器。现在,速度理应快了才对啊。

但为什么,越来越多的网站,打开的时候明明看到标题了,页面却要空白很久呢?除了网站离我们太远,还有别的原因。

我们先来看看一张网页的组成。

一张网页的加载流程

下图是 HTTP Archive 在 2017 年 3 月对世界上前 1000 热门网站的统计。平均每张网页会有多大呢?

先解释一下几个名词:

  • HTML:网页的基础,相当于房子的地基和砖块,通常会包含页面上的文字,并定义其它资源的地址;
  • 样式表:CSS,相当于图纸,定义网页的样式,比如你看到的文字的颜色、大小、排列、边框等等,都由它定义;
  • JS 程序:JavaScript,网页会“动”起来全是因为它,有能力改写整个网页;
  • 字体:指的是字体文件,中文网页嵌入字体并不多(因为中文字多,字体文件通常会太大);嵌入了字体之后,不用做图,即便浏览器上没装字体,也能显示嵌入的有“个性”的字体。

我们打开一个网页,载入的其实先是 HTML,然后 HTML 里面可以引用别的资源,比如样式表、JS 程序等等。这些资源可以在同一服务器,也可以在别的服务器(域名)上。

看图你就会发现,现在的网页,HTML 本身并不大,然而样式表和字体的平均大小却能和 HTML 相当,最夸张的是 JS,是 HTML 的 8 倍多。然而,如果没有样式表和 JS,我们看到的网页就没有现在这么好看、好用了。

我强调字体、样式表和 JS 程序,原因很简单。因为它们重要,所以浏览器载入网页的时候,会等它们加载完,才能显示。HTML 加载完了,还得等待样式表和 JS 程序全部下载完毕,否则浏览器就不知道页面究竟要怎么显示。

当然,如果边下载边显示,也不是不行。但这就需要不停地“重绘”页面,在屏幕上的表现就是画面不停地变化,看起来也不好看。所以有些浏览器会等到“必须”的、跟页面显示效果关系最密切的样式表和 JS 程序下载完才开始显示。这个策略,浏览器有专用的术语,叫“阻塞”。

而图片和视频并不会“阻塞”浏览器,浏览器下载的时候会做优化,会让他们延后再开始下载,所以它们虽然大小很大,但并不会影响页面“首次渲染”的时间。

为啥会慢?因为公用的资源

所以,网页加载速度缓慢,可能有下面这些原因。

  1. 下载 HTML 的速度慢,也就是连接源服务器的速度就慢,这个怨不了谁。
  2. HTML 全部下载下来了,但是 HTML 里引用的资源加载速度慢,所以 HTML 定义的标题显示出来了,内容却要空白很长时间。

你说那些浏览器的加载策略怎么这么笨,不优化一下呢?首先,大多数时候浏览器还是比较聪明的,有些资源会直接跳过,但有些浏览器认为很重要的资源是必须“阻塞”、不会跳过的,宁愿多等一会,比如样式表。你也不愿意看到下面这种没有样式表的画面吧……

模拟的样式表加载失败的效果

为什么我们在访问国外的网页时,这种情况会经常出现呢?因为国外的网页引用的资源,会经常引用一些不在自己服务器上的公用资源。比如:

  • Facebook 的点赞按钮的小程序;
  • CDN 上的 JS 程序库;
  • Google 托管的英文字体;
  • Google 的广告;
  • ……

为什么要用公用的资源呢?一个是方便,另一个则是省流量。假设 A、B 网页都引用了同一个点赞按钮的程序,你打开过 A 网页,点赞按钮的程序就下载了下来,以后你打开 B 网页的时候,因为这部分程序有缓存,所以就不用完整下载点赞按钮的程序了。

然而,只要这些资源下载失败,浏览器就会等待,直到“超时”,即便可能对你有用的 HTML 内容已经被下载到浏览器里了(这种时候你查看页面源代码,可能就已经能看到需要的信息了)。有时页面加载到一半然后卡住,也有可能是这种情况。

这个“超时”的时间是多少呢?就拿 Firefox 做例子,默认的时间从 90 秒到 300 秒不等。(下载到不同阶段,对应的超时时间也是不同的)不等完超时,页面就没法正常载入,所以,看起来就是等了十几秒,页面却一片空白,加载不出来了。

至于字体下载不下来,在有些浏览器上的效果很神奇:页面有些有字体的部分可以选中,可以复制,却什么字都看不到,一段时间之后,突然那些字的字体下载完毕,就漂漂亮亮地出现了。

这里提供一个小小的判断页面加载失败原因的方法:

在电脑浏览器上按 F12,会弹出一个只针对当前页面的调试工具。点开网络或者 Network,然后刷新页面,你就能看到每个资源的加载速度和结果了。比如在我这,jquery.min.js 是 pending 也就是等待的状态,再等一会就会变成红色的 failed(然而下图并不是 GIF),点开它们就能在右边看到具体的地址。

公用的资源为啥会慢?

最后你肯定想问,为什么那些公用的国外资源,访问就那么困难呢?简单说说原因吧:

  • Google、Facebook 等大部分的服务器并没有进驻中国大陆,所以在三四年前几乎无法访问。(不过 Google 这一两年给一些不是很敏感的公共服务在北京开了服务器,可能因为它是全球最大广告商吧)
  • 别的公用资源很多都被放在国外的 CDN 上,公用的资源有时候也会被一些反动网站利用,因此国家对反动网站采取措施的时候,免不了会误杀。这部分反而是现在主要会遇到的问题。
  • 近年来整个互联网已经进入了 HTTPS 的加密时代,进而这些公用的资源也开始了加密。对于加密的内容,传输阶段是无法读取具体访问的内容的,因而很多国外的 CDN 服务在看起来相似的加密连接下,有可能有正常请求,也有可能有反动请求。误杀的情况就更加不可避免了。

了解了原因,遇到慢到掉渣的国外网页,你还是只有两个简单而实际的方法:站起来走一圈,或者站起来跳出去。

参考文献:

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

To respond on your own website, enter the URL of your response which should contain a link to this post's permalink URL. Your response will then appear (possibly after moderation) on this page. Want to update or remove your response? Update or delete your post and re-enter your post's URL again. (Find out more about Webmentions.)