ob_start是否会影响存储在CDN上的文件的性能


Does ob_start affect performance of files stored on CDN?

我使用对象缓冲来缓冲使用ob_start('ob_gzhandler');的php页面的输出。这是否会影响存储在CDN中的文件的性能?

提出这个问题的原因是,其中一个网站指出了以下内容:"输出缓冲是一种简单的方法,可以极大地提高PHP脚本的性能和速度。如果没有输出缓冲,脚本将在页面上显示HTML处理过程中的片段。添加输出缓冲可以使PHP将HTML存储为变量,并将其发送到浏览器。"

你能澄清一下吗?

使用ob_start肯定会影响页面的加载时间——而不是"PHP脚本的性能",这是IMHO完全误导性的表达。但让我们从头开始。

用户感知加载时间

您提到的一侧似乎指的是用户感知的页面加载时间。也就是说,假设您有10KB的HTML要发送,并且每50ms发送1KB。还假设浏览器在这个过程中没有放入任何自己的逻辑,它只是以读取传入数据的速度进行渲染(这肯定不是真的!)。50ms的长度足以被人类感知,因此用户将看到一个接一个加载的页面。

另一方面,假设所有10KB的HTML在500ms后一次性发送。虽然这会导致用户等待相同的总时间,但页面会一下子呈现出来,用户会认为这会更快,因为"加载时花费的时间更少"。

我还应该提到的是,如果你举一个完全相同的例子,将加载时间增加到5秒(或10个0.5秒),那么用户的看法就会逆转:现在第二个页面的速度慢了,因为"运行起来花了很长时间"。

很明显,这种分析很好地进入了心理学领域,所以我就到此为止,建议如果你对这些东西感兴趣,可以在网上找到好的材料。这就是浏览器在接收数据时呈现页面的过程中加入自己的特殊酱汁的原因:每个供应商都希望让他们的浏览器感觉更快,尽管就网络而言,他们都同样快。

输出缓冲

让我们还考虑一下服务器端。web服务器堆栈上的任何东西——Apache、PHP,以及介于两者之间的任何东西,也可以选择在发送数据之前缓冲数据。通常情况下,即使没有明确的文档记录或开发人员的请求,也会发生这种情况,这就是为什么你会看到应该显示"已发送标头"通知的代码没有这样做的原因。

现在,如果你在服务器端做缓冲处理,你真正要做的是迫使浏览器适应你的想法。让我们回到客户端渲染示例,并考虑一个浏览器,该浏览器接收小块中的HTML,但为了显得更敏捷而选择延迟渲染。这样做并不意味着浏览器在延迟期间不必执行任何操作;事实上,它很可能解析HTML并立即开始加载依赖项(样式表、图像等),即使它还不打算渲染页面。这是合乎逻辑的:通过领先,它最终会更早地获得这些资产的内容,并赢得"感知速度"战争。

问题是,如果你假设缓冲的军事命令浏览器不能再这样做了。它必须等待内容被发送,然后开始寻找这些资产。由于我们谈论的是CDN,如果不是即时的(由于缓存),获取资产将非常快,但这仍然是一个小到零的延迟,您不必承受。

当然,我们必须考虑到,以压缩为目的的输出缓冲可以使页面实际加载更快,因为要发送的数据更少。这种差异对于联系缓慢的人来说尤其明显。

TL;DR版本

如果你已经测量到压缩对页面加载速度有很大影响,那么就使用它。如果你不压缩,不要试图根据具有未知凭据的网站的建议来猜测浏览器供应商(他们在研究上花费了无数资源)。

使用php生成页面时,会生成一个文本文件,通常使用echo来渲染html。因此,将由发送到客户端的输出页面是在您的"echo"时间分段创建的。

当您使用缓冲时,回声渲染在内存缓冲区中(例如,下一步可以使用ob_get_content调用)。当您需要为客户端提供输出时,您可以在一次操作中打印出缓冲区的内容。

简单来说:默认输出的写操作很慢,但内存缓冲区中的写操作更快。因此,在内存缓冲区中渲染,然后在默认输出上回显块,这样可以提高输出速度。

另一个好处是,它允许您创建自己的自定义缓存系统。

我不知道你对CDN的用途是什么,但如果是存储图像,它不受php缓冲的影响。

使用CDN时,使用ob_start()不会影响性能。CDN将在从您的网站获得内容后交付您的内容。使用ob_start()的事实是透明的。您使用ob_gzhandler的事实会被CDN看到,但不会影响其自身的性能。

CDN会要求您的网站提供内容。它将对其进行压缩(使用ob_gzhandler)或不进行压缩。如果客户端要求,CDN将提供压缩后的内容(大多数浏览器都这样做)。

这个答案不是为了解释ob_start的作用,它只是一个基准

我刚刚用我自己的网站做了一些测试,每个请求加载大约70个PHP文件,并进行了一些MySQL查询

 Size|Finish|DOM Loaded|Load
 //Procedural output
 16 KB 543 ms 440 ms 544 ms
 --    598 ms 465 ms 599 ms
 --    604 ms 469 ms 604 ms
 --    598 ms 474 ms 599 ms
 --    595 ms 465 ms 596 ms
 --    595 ms 465 ms 596 ms
 //echo ob_get_clean();
 --    1140 ms 740 ms 1140 ms
 --    852 ms 654 ms 853 ms
 --    7xx ms 5xx ms 7xx ms
 --    8xx ms 6xx ms 8xx ms
 --    7xx ms 5xx ms 7xx ms
 --    8xx ms 6xx ms 8xx ms

在我的案例中,它影响了很多加载时间(PHP 7.1)