我们分析了Habr的加载或页面上189个请求的呈现影响力

取浓樱桃汁


不久前,我开始对网站性能,下载优化等感兴趣。 现在,我再次去哈伯(Habr),我习惯于感知给定的相当快的资源加载,甚至不考虑如何实现。 因此,我决定将业务与娱乐相结合-观察Habr的性能如何发展,以及采用何种技术解决方案对其进行优化。


对于那些有兴趣了解已完成操作以便我们尽快收到内容以及从阿根廷下载Habr的情况的人,请注意。


准备工作


我们将需要在匿名模式下运行的Chrome / Canary全新版本(确保所有扩展程序均已关闭)。 另外,在开发者控制台(Developer Tools-F12)的“网络”标签中,您必须设置“禁用缓存”标志,因为 我们将仅分析第一次启动,而缓存中尚无资源。


第一阶段-“楼上”


这部分的主要目的是了解整个站点,了解其结构并找出所需的特定资源。


我们打开开发人员工具,转到“网络”选项卡,打开站点,然后在该选项卡的最底部查看有关网络使用情况的统计信息:


还有一个白人母亲的的斗篷。


整个网站的加载时间为2.02秒,这看起来不错(考虑到Habr的负载)。 事件DomContentLoaded (以下简称DCL)通常在1.01秒内出现,看起来更好。 有了这些,该站点发出了189个请求并加载了9.6MB的资源。 这告诉我们Habra团队是一个天才(很可能是),并且文章应该在这里完成(并请他们给团队喝咖啡和饼干),或者记住我有一个100 Mb / s的频道和Core I7 。 即 您需要更加接近现实,并至少限制通道宽度。


我们打开快速3G模式并再次查看:


将果汁轻轻倒在斗篷上-


DCL恶化到3.48秒,这仍然是可以接受的。 但最终该网站在无神论者中加载了54.76秒。 现在一切都变得合乎逻辑了-连接不畅时,您不仅可以下载并下载近10兆字节。 这些家伙很可能在向我们展示尽可能快的内容方面做得很好(事实证明,即使在fast3g模式下,DCL也会足够快地出现),所有不重要的内容都留在了后台。 我们待会儿再检查一下,现在让我们看看为什么加载这么长时间。 按加载时间对所有请求进行排序:


将会出现一个斑点。
可点击


图像(前7个)的加载时间最长,一个JavaScript文件是prebid.js。 如果我们看一下它们的大小,可以假设这正是加载缓慢的原因。


关于假设

根据假设,您需要非常小心。 例如,资源的长时间加载不仅可以由文件大小引起,还可以由DNS,峰值存储负载或服务器缓存过冷等问题引起。 因此,未经验证的假设可能会导致您浪费时间解决甚至不存在的问题。


查看统计信息( TTFB :0.610毫秒,负载:40 000毫秒),我们可以得出结论,我们的假设很有可能。 让我们欣赏我们的TOP 1(png,1560X780,24bit):


现在没有景点


实际上,图像问题主要是我们与您之间的流量问题。 图像(与样式和脚本不同)不会阻止网页的呈现,因此,尽管存在这样的重量级人物(他们看到的可能更糟),但这几乎不会影响性能。 当然,尽管在此方向上进行了优化(例如,转码为jpeg2000或webp或渐进式加载不会多余)。


关于图像

正如我在上面所写,图像不会阻止页面的呈现。 但是他们使用了我们的连接池,在http 1.x中,它们的数量是有限的,并且在http 2.x和Chrome中也是如此,并不是所有事情都像我听到的那样顺利。 因此,即使在此处,某些图像也可能会减慢同步脚本的加载速度,进而已经停止渲染页面。 此外,加载图像还会导致布局重新计数,从而减慢渲染速度。 如果我们看一下Habr标记,几乎所有img标签都具有宽度和高度。 这样就消除了重新焊接对下载性能产生积极影响的需求。 您可以在此处了解更多信息。


让我们看看Habr还可以利用哪些其他资源-我们将遍历这些类型并按加载时间对其进行排序。 让我们从JavaScript开始


Java脚本


关于javascript

就网站性能而言,JavaScript存在一些问题。 首先(每个人都知道这一点很长时间了),同步js阻止了进一步的页面渲染。 即 在我们接收并执行JavaScript之前,浏览器将等待(实际上并不是完全可以,浏览器,尤其是Chrome可以优化,但这是另外一回事了),并且不会呈现其他内容。 使用头部中的同步脚本,我们推迟了用户看到至少某些内容(甚至是文本)的时间。 因此,每个人都试图将Js放在页面末尾,甚至使其异步。 这是可行的,但不能解决第二个问题,即JavaScript仍然是一种脚本语言。 因此,浏览器不足以仅下载它-还需要“理解”。 在这里,事实证明这是一个问题,因为较弱的处理器(例如,廉价电话或上网本,甚至性能有限的出色笔记本电脑)运行缓慢,阻塞了主线程! 下面是一个示例,说明异步广告脚本如何进入Habr渲染的关键部分,尽管有一点,但仍然破坏了性能。 如果有人对此感兴趣,那么有一篇非常(非常非常)关于该主题的文章


Habr脚本负载很多-1.1 MB(这已经是压缩形式)可以处理40个请求。 坦率地说,这很重要,它仍然会重新出现在我们的脑海中,我们需要为此做点事情。 将我们的脚本“按瀑布”排序。 我们的任务是找到在蓝线之前加载的脚本,因为(最有可能的)脚本阻止了我们尽快渲染网站。


在我母亲的披风上
可点击


我们打开Habr提供给我们的html(查看答案很重要,因为最终的html看起来会有所不同)并逐一列出。 如您所见-jQuery,raven.js,advertise.js和adriver.js是直接从head标记同步加载的(即它们完全阻止了所有内容)。 Gpt和发布者是从头开始加载的,但已经是异步加载的(即,它们不阻止任何内容,浏览器将在加载时进一步渲染页面)。 供应商,Main和Math,checklogin会在最后加载,但会同步加载(即,文本已经存在,我们可以阅读它,但DCL直到加载后才会显示)。 其余的没有出现在初始答案中-它们是动态添加的,但这是另一个主题。


因此,我们发现了那些以某种方式影响我们在页面上看到文本的速度的脚本。 这些是最优化的候选对象。 理想情况下,应将它们设为异步或放置得尽可能低,以使浏览器能够为我们呈现内容。 但是,理想是无法实现的,因为站点上很可能还有其他脚本依赖于同一jQuery。 尽快下载乌鸦的愿望-用于跟踪客户端发生的各种错误的库也可以理解。 但是advertise.js和adriver.js已经是至少在页面上向下移动的真正候选人,并且在异步模式下也是如此。 与gpt和发布者类似的故事。 是的,它们是异步加载的,但是尽管如此,它们在加载时仍会(并且会)干扰我们。 因此,它们也可以发送到页面的最底部。 此外,您可以尝试使用“ 资源提示”属性-preload / prefetch / dns-prefetch来告知浏览器要预先加载的内容。 顺便说一句,我建议您阅读有关资源提示的信息-一种非常有趣的工具,尽管支持有限(到目前为止)。


现在按文件大小对列表进行排序:


斗篷必须全部塞入
https://github.com/Drag13/articles/blob/habrformance/habrformance/scripts.PNG


我们看到一个脚本加载了两次(发布)。 我们还注意到prebid.js是从not-ford文件夹中加载的


在浓稠的的樱桃汁中。


为了澄清我们的良心,我们检查所有脚本是否都已缩小。 突然,脚本最小化了check-login.js和adriver.js。 特别满意后者的内容:


拿一个樱桃妈妈的斗篷


使用脚本,您可以暂时结束。


款式


关于样式

有了样式,一切也不是那么简单。 首先,样式的同步加载还会阻塞主线程(尽管它们的解析速度比JavaScript快得多)。 其次,一切都有些复杂。 为什么浏览器需要CSS? 构建CSSOM 。 JavaScript能与CSS一起做什么? 是的-改变。 如果还没有构建CSSOM,而js已经在尝试更改CSSOM,将会发生什么? 答案是谁知道。 因此,浏览器会延迟JavaScript的执行,直到计算CSSOM。 正如在另一篇非常有用的文章中正确编写的那样-没有CSS =没有JavaScript。 因此,加载CSS会阻止JS执行。


以下是Habr加载的样式:


和一杯牛奶。
可点击


如您所见,其中只有三个,第二个和第三个装载在单独的框架中,因此我们将其忽略。 但是第一组样式对于整个网站至关重要。 而且我们下载了很长时间。 怎么了 首先,他们等待了很长时间以等待服务器的响应(TTFB 570毫秒,我们将在第三部分中返回到它),其次,加载了713毫秒的时间很长。 在这里可以做什么。 第一个也是最简单的方法是尝试添加preload属性。 这将提示浏览器尽快开始加载CSS。 第二个选项是突出显示关键的CSS并将其直接嵌入到网页中,然后同步(甚至异步)加载其余的CSS。 这将导致页面大小增加(但已经不小的页面了,+ 5kb不会破坏任何内容),并且可能会重新绘制布局(时间浪费),但是您可以尝试。


我什至不显示字体。 它只是在那里,尽管出于某种原因它是直接从Habr服务器而不是CDN加载的(并且很可能是有原因的)。 但我要感谢只有一种字体的事实。


这样,可以认为站点分析的概述部分已完成。 是时候更深入了。


第二阶段-“手动模式”


在最后一个阶段,我们看到哈勃的负载。 现在我们将看到如何渲染。


转到分析选项卡。 我们检查什么是fast3g减速(然后不受限制地再次运行)并运行。 首先,我们对首次出现内容丰富的绘画(FCP)事件之前发生的一切以及为以防万一的DCL感兴趣。 我们从加载到FCP的开始选择一个区域,然后查看最终图表。


干净地倒牛奶-


一切都进行得非常快-在FCP之前2.161秒(速度更快,但显然已经发生了变化),但是正如您所看到的,大多数时间浏览器处于空闲状态。 有效负载仅花费了14%的时间(约310毫秒)。 理想情况下,主浏览器线程连续运行-解析html,CSS,执行JS。 在这里-什么都没有。 怎么了 因为浏览器无事可做。 还记得我们减少了流量吗? 浏览器已发出请求,现在仅等待它们完成。 如果打开网络过程图(最顶层的图),一切将立即变得清晰。


将会出现一个斑点。
可点击


在2029年,浏览器看到main.bundle.css,发送了一个接收请求,并开始等待。 这时,预扫描程序(智能chrome,可以继续运行)发现下面有同步脚本,并且没有等待CSS到达,而是发送了脚本请求。 然后做广告并加载驱动程序(但我们记住,虽然未创建CSSOM,但是您无法触摸JS),因此浏览器将其忽略。 之后,gpt和raven已加载,但是CSS仍在加载,因此它们也被忽略。 最终,加载了CSS,浏览器在12毫秒内对其进行了解析,并立即解析了嵌入在页面中的JS。 然后,浏览器再次在将近150 ms的时间内“入睡”,等待jQuery.min.js。 在那之后,我已经开始认真工作-我找出了加载的jQuery(20毫秒),解析了raven.js(4毫秒),解析了几乎整个页面(36毫秒),重新计算了样式(28毫秒),计算了布局(78毫秒+ 8毫秒),然后,最终,在大约6毫秒内,我们绘制了页面。 在这里,我们得到了FCP。 接下来,我们解析页面,解析脚本-没人问好(publishertag.js,gpt.js在DCL之前进入主线程),玩弄了一些样式(由于布局重新计算而造成了一些时间损失)并开始等待供应商。 bundle.js。 为了等待供应商,我们几乎闲置又花了1100毫秒。 没错,与此同时,我们还加载了main.bundle.js(顺便说一句,它启动速度更快),因此并不是所有事情都那么糟糕。 然后,一切又恢复了。 我们解析了供应商,解析了主捆绑包,解析了Math.Jax,最后解析了页面并获得了DCL。 没错,某种处理程序在那里工作,我的I7在80 ms时停止了主线程(即,该站点似乎在80 ms时冻结了)。 现在我们几乎没有注意到这一点,但是从理论上讲,在一个性能较弱的处理器上,这是可以注意到的。


我能说什么 同样,尽管事实看起来还不错。 主要问题已传达给我们:


  • 一个大型的简单浏览器(包括由于计算机的计算能力和通道宽度之间的人为失衡,但这也是一个相当有效的方案)
  • 长时间的CSS加载会延迟关键JS的工作
  • 同步加载jQuery,供应商和主要捆绑软件,从而阻止了内容的出现。

我们已经讨论了可以做什么:


  • 尝试为CSS和一些JS添加preload属性
  • 减少或内联CSS
  • 尽量使脚本退出同步加载(至少一些)

现在让我们重复同样的事情,而对通道宽度没有任何限制。 画面已经好多了:FMP只需0.452秒,这是最简单的! 13毫秒 DCL-953毫秒,简单15毫秒。 这就是我梦dream以求的下载。 这就是发生的原因,因为我打开了一个新选项卡并没有删除缓存。 让我们尝试同样的事情,但是没有缓存:


现在没有景点


一切也都还不错,FCP / FMP-1689,有效载荷45%。 顺便说一下,将负载调整为100%也是不好的,因为较弱的机器将过载。 因此,最好保留停机时间。 但是,这出乎意料地在渲染上花费了很多时间-FMP为400毫秒。 其中200毫秒用于样式的重新计算和布局的重新计算。


顺便说一句,另一个有趣的观点。 还记得第一部分提到的广告脚本-gpt.js和Publishertag.js吗? 现在您可以看到,尽管它们具有异步性,但它们仍然能够(尽管有一点)破坏了我们的统计数据。 发生这种情况是因为异步脚本的执行是根据脚本本身的准备情况完成的。 即 这可以随时发生,包括在3309年发生的FCP / DCL之前。


因此,我们进行了手动拆卸。 是时候揭示自动化了。


第三阶段-“我们必须从此开始”


关于集体农场

我想每个人都知道这项研究非常武断。 至少,因为在我测试新文章的过程中一直出现,所以服务器上的负载和网络主干上的负载都发生了变化。 以一种好的方式,您需要部署一台专用服务器,在该服务器中,任何人都不会写任何东西,以相关的延迟模拟相关的负载,然后才进行概要分析。 否则,您可以做一些假设(例如,关于需要在CSS上添加preload属性),添加它,将其部署到生产中,然后证明测试期间的负载急剧增加,并且服务器在500毫秒后为我们提供了相同的样式。 事实证明,预加载是不好的-它只会使一切变得更糟。 而作者根本就是萝卜。 此外,手动配置文件(如第二部分中所述),直到您用尽了所有自动工具并解决那里发现的问题,这也没有什么意义,因为在您进行第一次更改后,图片将发生变化。


因此,在进行任何实验之前,我们需要最稳定的环境。 这回 第二个-您从一开始就不应该深入(例如,进行概要分析)。 首先启动自动工具,让它们为您服务。 收集报告,查看可以在最短的时间内完成的工作。 尝试做。 如果可能,您可能已经足够了。 例如,您的css.bundle重100kb,但是实际上您需要45kb(顺便说一句,实际情况是:他们占据了整个引导区,但只需要网格)。 他们缩小了样式的大小,几乎毫无收获地赢得了半秒。 这是两个。 始终仔细检查。 似乎内联了样式,所有内容都应该变得更好,但是会变得更糟。 怎么了 而且因为采用50kb base64图片的样式,并且我们的页面仅加载了200kb的资源。 请记住,没有灵丹妙药和通用脚本。 这是三个。 最后一个,即使它与前面的句子相矛盾。 如果您没有复杂的网站,则只需监视TTFB(服务器问题),下载资源的大小(徽标大小为2MB,您好),并且不能访问Google跟踪代码管理器(任何人)。 这很可能已经足够了。


我们不会走太远,在同一开发人员工具中,打开审核选项卡并使用以下设置启动LightHouse(LH):台式机,仅性能,无节流,清晰的存储。 等待一会儿(不要离开正在执行审核的页面,也不要做其他任何更好的事情),我们得到的数字非常棒(即使禁用了缓存)


在我母亲的披风上


在我看来,它们尤其是针对这些数字量身定制的。


但是,LH仍然抱怨:


  • 图片格式过时(建议使用webp,jpeg2000等)
  • DOM node – : 2533, 1500.
  • — 23
  • document.write

. (), DOM — node (-), ( ), document.write- writer ( - )


( ) . , , , . , , . CSS, — , , JavaScript. , , . .


, fast3g , , ( I7, celeron):


斗篷必须全部塞入


( FCP 3500 ms, FMP 5.7):


  • , . LH next-gen , , , 11
  • . adriver.js advertise.js 50 , .
  • CSS , 5kb 45kb.
  • main thread. JavaScript — (8.5 script evaluation 2186 ms raven.js). ?

? . - . :


  • DOM
  • JavaScript

, , (, raven.js).


, , — webpagetest.org


— , , . — , . , . , , . , , , — -.


https://habr.com ( ru/en ).


在锅里加牛奶。


( , )


. ( ) DNS (500 ms ), , ssl . , 1150 ms c ( ). , ( habrastorage).


main.bundle.css. , dr.habracdn.net , dns lookup — 36 ms ( 400 ms). SSL negotiation 606 ms, TTFB 601 ms, . . DCL — 4100 ms , .


image analysis , , . - PNG 1.4, webp + downscaling ( , ) — 17.7 KB. , , png 154. . , :


  • ( , , .. ).
  • . , .
  • TTFB (webpagetest F ) —
  • , ( )

结论


. :


:


  • TTFB 500 ms ( dns, ssl initial connection)
  • habrastorage

:


  • DOM-a

, , . , , . , SPA, , JS — . . //,




PS。对于大量的英国主义(特别是布局)和Longrid,我深表歉意。但是没有它们,这真的很难,而所有这些第1、2、3部分,我已经厌倦了订购。

Source: https://habr.com/ru/post/zh-CN454444/


All Articles