《浏览器性能优化实战.docx》由会员分享,可在线阅读,更多相关《浏览器性能优化实战.docx(38页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、浏览器性能优化实战rosefang腾讯PCG前端开发工程师当我们在做性能优化的时候我们终究在优化什么阅读器底层是一个什么架构阅读器渲染的本质终究是什么哪些方面对用户的体验影响才是最大的有没有业内一些通用的标准或者标杆参考都1202年度了雅虎军规还有没有用性能分析工具都有哪些我们怎么进展打点分析才是适宜的本文为你一一讲解这些。解析了这些问题可能你在做性能优化的时候才能更加得心应手。1.性能优化的本质1.1展示更快响应更快性能优化的目的就是为了提供应用户更好的体验这些体验包含这几个方面展示更快、交互响应快、页面无卡顿情况。更详细的讲就是指在用户输入url到站点完好把整个页面展示出来的经过中通过各种
2、优化策略以及方法让页面加载更快在用户使用经过中让用户的操作响应更及时有更好的用户体验。对于前端工程师来讲要做好性能优化需要理解阅读器加载以及渲染的本质。理解了本质原理才能更好的去做优化。所以我们先来看看阅读器架构是如何的。1.2理解阅读器多进程架构从大的方面来讲阅读器是一个多进程架构。它可以是一个进程包含多个线程可以以是多个进程中每个进程有多个线程线程之间通过IPC通讯。每个阅读器有不同的实现细节并没有标准规定阅读器必须怎样去实现。这里我们只议论chrome架构。下面这张图是目前chrome的多进程架构图。图片引自MarikoKosaka的?Insidelookatmodernwebbrows
3、er?我们来看看这些进程分别对应阅读器窗口中的哪一局部图片引自MarikoKosaka的?Insidelookatmodernwebbrowser?那么怎么看阅读器对应启动了什么进程呢chrome中我们可以通过更多-MoreTools-TaskManager看到启动的进程。从chrome官网以及源码我们可以以得知多进程架构中包含这些进程Browser进程翻开阅读器后始终只有一个。该进程有UI线程、Network线程、Storage线程等。用户输入url后首先是Browser进程进展响应以及恳求效劳器获取数据。然后传递给Renderer进程。Renderer进程每一个tab一个负责html、cs
4、s、js执行的整个经过。前端性能优化也与这个进程有关。Plugin进程与阅读器插件相关例如flash等。GPU进程阅读器共用一个。主要负责把Renderer进程中绘制好的tile位图作为纹理上传到GPU并调用GPU相关方法把纹理draw到屏幕上。这里的话只是简单介绍一下阅读器的多进程架构让大众对阅读器整体架构有个初步认识其实背后的细节还有很多这里就不一一展开。有兴趣可以细看这一系列文章以及介绍。1.3理解页面渲染相关进程1.3.1RendererProcessGPUProcess从以上的多架构我们解析到与前端渲染、性能优化相关的其实主要是Renderer进程以及GPU进程。那么它们又是什么架构
5、呢来看一下这张我们再熟悉不过的图。图片引自Paul的Renderer进程包括3个线程。合成线程CompositorThread、主线程MainThread、CompositorTileWorker。GPU进程只有GPU线程负责接收从Renderer进程中的CompositorThread传过来的纹理显示到屏幕上。1.3.2RendererProcess详解Renderer进程中3个线程的作用为CompositorThread首先接收vsync信号(vsync信号是指操作系统指示阅读器去绘制新的帧)任何事件都会先到达Compositor线程。假如主线程没有绑定事件那么Compositor线程将防
6、止进入主线程并尝试将输入转换为屏幕上的挪动。它将更新的图层位置信息作为帧通过GPU线程传递给GPU进展绘制。当用户在快速滑动经过中假如主线程没有绑定事件Compositor线程是可以快速响应并绘制的这是阅读器做的一个优化。MainThread主线程就是我们前端工程师熟知的线程这里会执行解析Html、款式计算、布局、绘制、合成等动作。所以关于性能的问题都发生在了这里。所以应该重点关注这里。CompositorTileWorker由合成线程产生一个或者多个worker来处理光栅化的工作。ServiceWorkers以及WebWorkers可以暂时理解也在Renderer进程中这里不展开讨论。1.3
7、.2.1MainThreadmain-thread主线程需要重点讲下。因为这是我们的代码真实存在的环境。从上一小节Render进程以及GPU进程的图中我们可以看到有个红色的箭头从RecalStyles以及Layout指向了requestAnimationFrame这意味着有ForcedSynchronousLayout(orStyles)(强迫回流以及重绘)发生这一点在性能方面十分要注意。在MainThread中有这几个需要注意一下requestAnimationFrame因为布局以及款式计算是在rAF之后所以在rAF是进展元素变更的理想时机。假如在这里对一个元素变更100个类不会进展100次
8、计算它们会分批以后处理。需要注意的是不能在rAF中查询任何计算款式以及布局的属性例如el.style.backgroundImage或者el.style.offsetWidth因为这样会导致重绘以及回流。Layout布局的计算通常是针对整个文档的并且与DOM元素的大小成正比这点十分要注意假如一个页面DOM元素过多也会导致性能问题主线程的顺序始终都是InputEventHandler-requestAnimationFrame-ParseHtml-ReculateStyles-Layout-UpdateLayerTree-Paint-Composite-commit-requestIdleCal
9、lback只能从前往后例如必须先是ReculateStyles然后Layout、然后Paint。但是假如它只需要做最后一步Paint那么这就是它全部要做的事情不会再发生前面的ReculateStyles以及Layout。这里其实给了我们一个启示假如要让fps保持60即每帧的js执行时间少于16.66ms那么让这个主线程执行的经过尽可能地少是我们的性能优化目的。根据主线程的这些步骤理想的情况下我们只祈望阅读器只发生最后一个步骤Composite(合成)。CSS的属性是我们需要关注一下的模块。这里有描绘了哪些会引起重绘、回流以及合成。例如让我们给一个元素进展挪动位置时transform以及opac
10、ity可以直接触发合成但是left以及top却会触发Layout、Paint、Composite3个动作。所以显然用transform时更好的方案。但这并不是讲我们不应该用left以及top这些可能引起重绘回流的属性而是应该关注每个属性在阅读器性能中引起的效果。2.看看经典雅虎军规多年度前雅虎的NicolasC.Zakas提出7个类别35条军规至今为止很多前端优化准那么都是围绕着这个展开。假如严格按照这些规那么去做其实我们有很多优化工作可以做只要认真践行性能提升不是问题。我们来看看它7个分类都是围绕哪些方面展开Server与页面提议恳求的相关Cookie与页面提议恳求相关Mobile与页面恳求
11、相关Content与页面渲染相关Image与页面渲染相关CSS与页面渲染相关Javascript与页面渲染以及交相互关。从上面的描绘可以看到其实雅虎军规是围绕页面提议恳求那一刻到页面渲染完成页面开场交互这几个方面来展开提出的一些原那么。很多原那么大众也都耳熟能详就不全部展开了有兴趣的同学可以去查看。这里主要想提一些忽略但是又值得注意的点减少DOM节点数量为什么要减少DOM节点的数量当遍历查询500以及5000个DOM节点进展事件绑定时会有所差异。当一个页面DOM节点太多应该考虑使用无限滚动方案来使视窗节点可控。可以看看。减少cookie大小cookie传输会造成带宽浪费影响响应时间可以这样做消
12、除不必要的cookies静态资源不需要cookie可以采用其他的域名不会主动带上cookie。防止图片src为空图片src为空时不同阅读器会有不同的副作用会重新提议一起恳求。3.性能指标3.1什么样的性能指标才能真正代表用户体验要衡量性能我们必须有一些客观的、可衡量的指标来进展监控。但是客观且定量可衡量的指标不一定能反映用户的真实体验。以前我们会用load事件的触发来衡量一个页面是否加载或者显示完成。但是设想会不会有这样的情况一个页面的load事件已经被触发但是却在load事件之后几秒才开场加载内容以及渲染页面所以这个时候load事件并不能真实反映用户看到内容的时刻。在过去几年度google团
13、队以及致力于提供标准的性能API来真正衡量用户的体验。主要是从这4个方面考虑考虑点详细内容Isithappening?导航是否成功效劳器是否响应了Isituseful?是否已经渲染了足够的内容让用户可以开场介入其中Isitusable?用户是否可以与页面交互页面是否处于繁忙状态Isitdelightful?交互是否流畅、自然、没有滞后反映或者卡顿通常有2种途径来衡量性能。本地实验衡量本地模拟用户的网络、设备等情况进展测试。通常在开发新功能的时候实验测量是很重要的因为我们不知道这个功能发布到线上会有什么性能问题所以提早进展性能测试可以进展预防。线上衡量实验测量虽然可以反映一些问题但无法反映在用户
14、那里真实的情况。同样的在用户那里性能问题会以及用户的设备、网络情况有关而且还跟用户怎样与页面进展交互有关。有这几个类型与用户感悟性能相关。页面加载时间页面以多快的速度加载以及渲染元素到页面上。加载后响应时间页面加载以及执行js代码后多久能响应用户交互。运行时响应页面加载完成后对用户的交互响应时间。视觉稳定性页面元素是否会以用户不期望的方式挪动并干扰用户的交互。流畅度过渡以及动画是否以一致的帧率渲染并从一种状态流畅地过渡到另一种状态。对应上面几种分类Google以及W3C性能工作组提供了对应这几种性能指标:测量页面开场加载到某一块内容显示在页面上的时间。:测量页面开场加载到最大文本块内容或者图片
15、显示在页面中的时间。:测量用户首次与网站进展交互(例如点击一个链接、按钮、js自定义控件)到阅读器真正进展响应的时间。:测量从页面加载到可视化呈现、页面初始化脚本已经加载并且可以可靠地快速响应用户的时间。:测量从FCP到TTI之间的时间这个时间内主线程被阻塞无法响应用户输入。:测量从页面开场加载到状态变为隐藏经过中发生不可预期的layoutshifts的累积分数。这些指标能从一定程度上衡量页面性能但不一定都是有效的。举个例子。LCP指标主要用户衡量页面的主要内容是否完成加载但会有这样的情况最大的元素并不是主要内容那么这个时候LCP指标并不是那么重要。每个不同的站点有自己的特殊性可以参考以上角度
16、进展衡量也需要因地制宜。3.2CoreWebVitals在以上列出的指标中Google定义了3个最核心的指标作为CoreWebVitals。它们分别代表着加载、交互、视觉稳定性。image-20210426192204425:测量加载性能。为了能提供较好的用户体验LCP指标建议页面首次加载要在2.5s内完成。:测量交互性能。为了提供较好用户体验交互时间建议在100ms或者以内。:测量视觉稳定性。为了提供较好用户体验页面应该维持CLS在0.1或者以内。当页面访问量有75%的数据到达了以上以上Good的标准那么认为性能是不错的了。CoreWebVitals是作为核心性能指标但是其他指标也同样在重要
17、是做为核心指标的一个辅助。例如TTFB以及FCP都可以用来衡量加载性能(效劳器响应时间以及渲染时间)它们作为LCP的一个问题手段辅助。同样的TBT以及TTI对于衡量交互性能也很重要是FID的一个辅助但是它们无法在线上进展测量也无法反映以用户为中心的结果。Google官方提供了一个库线上或者本地都可以测量上面提到的3个指标importgetCLS,getFID,getLCPfromweb-vitalsfunctionsendToAnalytics(metric)constbodyJSON.stringify(metric);/Usenavigator.sendBeacon()ifavailabl
18、e,fallingbacktofetch().(navigator.sendBeaconnavigator.sendBeacon(/analytics,body)|fetch(/analytics,body,method:POST,keepalive:true);getCLS(sendToAnalytics);getFID(sendToAnalytics);getLCP(sendToAnalytics);下面分别说说这3个指标定义的原因、怎样测量、怎样优化。3.2.1LargestContentfulPaint(LCP)3.2.1.1LCP怎样定义图片来自LCP是指页面开场加载到最大文本块内容
19、或者图片显示在页面中的时间。那么哪些元素可以被定义为最大元素呢img标签image在svg中的image标签videovideo标签CSSbackgroundurl()加载的图片包含内联或者文本的块级元素3.2.1.2怎样测量LCP线上测量工具实验室工具原生的JSAPI测量LCP还可以用JSAPI进展测量主要使用PerformanceObserver接口目前除了IE不支持其他阅读器根本都支持了。newPerformanceObserver(entryList)for(constentryofentryList.getEntries()console.log(LCPcandidate:,entr
20、y.startTime,entry);).observe(type:largest-contentful-paint,buffered:true);我们看一下结果是如何的LCP-exampleGoogle官方web-vitals库Google官方也提供了一个库底层还是使用这个API只是帮我们处理了一些需要测量以及不需测量的场景、和一些细节问题。3.2.1.3怎样优化LCPLCP可能被这四个因素影响效劳端响应时间Javascript以及CSS引起的渲染卡顿资源加载时间客户端渲染更加详细的优化建议就不展开了可以参考。3.2.2FirstInputDelay(FID)3.2.2.1FID怎样定义图片
21、来自我们都知道第一印象的重要性比方初次遇到某人形成的印象会在后续交往中起重要的影响。对于一个网站也是如此。网站以多快的速度加载完成是其中一项指标加载后以多快的速度对用户进展响应也同样重要。FID就是指后者。可以通过下面的图来更详细解析FID处于哪个位置图片来自从上图可以看出当主线程处于繁忙的时候FID是指从阅读器接收到了用户输入到阅读器对用户的输入进展响应的延迟时间。通常当我们在写代码的时候会认为只要用户输入信息我们的事件回调就会立即响应但实际上并不是这样。这是主线程可能处于繁忙阅读器正忙着解析以及执行其他js。如上图所示的FID时间主线程正在处理其他任务。当FID的时间为100ms或者以内那
22、么为Good。上面的例子中用户刚好在主线程最繁忙的时刻进展了交互但是假如用户在主线程空闲的时候交互那么阅读器可以立即响应。所以FID的值需要重点查看它的分布情况。FID实际上测量的是输入事件被感悟到到主线程空闲的这段时间。这意味着即使没有输入事件被注册FID可以以测量。因为用户的输入相应并不一定需要事件被执行但一定需要主线程是空闲的。例如下面这些HTML元素都需要在交互响应之前等待主线程上的正在执行的任务完成输入框例如input、textarea、radio、checkbox下拉框例如select链接例如a为什么要考虑测量第一次的输入延迟有如下原因因为第一次输入延迟是用户对你的网站形成的第一个
23、印象网站是否有质量且可靠在今天web中最大的交互问题第一次加载之后对于网站应该怎样解决较高的首次输入延迟(例如代码分割、减少JavaScript的预加载)的建议解决方案(TTI是指衡量这一块)不一定与在页面加载后解决输入延迟(FID是指衡量这一块)的解决方案一样。所以FID是在TTI的根底上更准确的细分。为什么FID只是包含从用户输入到主线程开场相应的时间而没有包含事件处理到阅读器绘制UI的时间尽管主线程处理以及绘制的这段时间也很重要但是假如FID把这段时间也包含进来开发者可能会使用异步API(例如setTimeout、requestAnimationFrame)来把这个task拆分到下一帧以
24、较少FID的时间这样不仅没有进步用户体验反而使用户体验降低。3.2.2.2怎样测量FIDFID可以在实验环境可以以在线上环境测量。线上测量工具原生的JSAPI测量newPerformanceObserver(entryList)for(constentryofentryList.getEntries()constdelayentry.processingStart-entry.startTime;console.log(FIDcandidate:,delay,entry);).observe(type:first-input,buffered:true);PerformanceObserver
25、目前除了在IE上没有兼容其他阅读器根本都兼容了。我们看一下结果是如何的FID-exampleGoogle官方web-vitals库Google官方也提供了一个库底层还是使用这个API只是帮我们处理了一些需要测量以及不需测量的场景、和一些细节问题。3.2.2.3怎样优化FIDFID可能被这四个因素影响减少第三方代码的影响减少Javascript的执行时间最小化主线程工作减小恳求数量以及恳求文件大小更加详细的优化建议可以参考。3.2.3CumulativeLayoutShift(CLS)3.2.3.1CLS怎样定义图片来自CLS是一个非常重要的、以用户为中心的测量指标。它能衡量页面是否排版稳定。页
26、面挪动会经常发生在资源异步加载、或DOM元素动态添加到已存在的页面元素上面。这些元素有可能是图片、视频、第三方广告或者小图标等。但是我们开发经过中可能不会发觉到这些问题因为调试经过中刷新页面图片都已经缓存在本地。调试接口的时候我们使用的是mock或在局域网接口速度都很快这些延迟都可能被我们忽略。CLS就是帮我们去发现这些真实发生在用户端的问题的指标。CLS是测量页面生命周期中每个发生意外布局挪动的分数。当一个可视元素在下一帧挪动到另外一个位置就是指布局挪动。CLS的分数在0.1或者以下那么为Good。那么意外布局挪动的分数怎样计算阅读器会监控两桢之间发生挪动的不稳定元素。布局挪动分数由2个元素
27、决定impactfraction以及distancefraction。layoutshiftscoreimpactfraction*distancefraction可视区域内在前一帧到下一帧之间所有不稳定的元素的并集会影响当前帧的布局挪动分数。举个例子下面这张图中左边是当前帧的一个元素下一帧中元素下移了可视区域内25%的高度。红色虚线框标出了两桢中当前元素的并集占适口的75%所以这个时候impactfaction是0.75。另外一个影响布局挪动分数的是distancefraction指这个元素相对视口挪动的间隔。不管是横向还是竖向取最大值。下面例子中竖向间隔更大该元素相对适口挪动了25%的间隔
28、所以distancefraction是0.25。所以布局挪动分数是0.75*0.250.1875.impact-fraction-example但是要注意的是并不是所有的布局挪动都是不好的很多web网站都会改变元素的开场位置。只有当布局挪动是非用户预期的才是不好的。换句话讲当用户点击了按钮布局进展了改动这是ok的CLS的JSAPI中有一个字段hadRecentInput用来标识500ms内是否有用户数据视情况而定可以忽略这个计算。3.2.3.2怎样测量CLS线上测量工具实验室工具原生的JSAPI测量letclsnewPerformanceObserver(entryList)for(const
29、entryofentryList.getEntries()if(!entry.hadRecentInput)clsentry.value;console.log(CurrentCLSvalue:,cls,entry);).observe(type:layout-shift,buffered:true);我们看一下结果是如何的CLS-exampleGoogle官方web-vitals库Google官方也提供了一个库底层还是使用这个API只是帮我们处理了一些需要测量以及不需测量的场景、和一些细节问题。3.2.3.3怎样优化CLS我们可以根据这些原那么来防止非预期布局挪动图片或者视屏元素有大小属性或
30、给他们保存一个空间大小设置width、height或使用。不要在一个已存在的元素上面插入内容除了相应用户输入。使用animation或者transition而不是直接触发布局改变。更详细的内容可以看。4.性能工具工欲善其事必先利其器Google开发的都支持CoreWebVitals的测量。工具如下APItools-all这些工具对CoreWebVitals的支持如下tools4.1Lighthouse翻开F12就可以看到Lighthouse点击GenerateReport即可生成报告。当然可以以添加chrome插件使用。lighthouseLighthhouse是一个实验室工具本地模拟挪动端以
31、及PC端对这几个方面进展测试。同时lighthouse还会针对这几个方面提出建议在产品上线前值得一测。lighthouse-funcLighthouse还提供了把Lighthouse集成到CI流水线中。举个例子每次在上线之前跑50次流水线对Lighthouse的各项指标进展测试取平均值一旦发现异常立即进展排查。把性能问题排查提早到发布之前。这块后面会细讲。4.2PageSpeedInsightsPageSpeedInsights(PSI)是一个可以分析线上以及实验室数据的工具。它是根据线上环境用户真实的数据(在ChromeUX报告中)以及Lighthouse结合出一份报告。以及Lighthou
32、se类似它也会给出一些分析建议可以知道页面的CoreWebVitals是否达标。PageSpeed-demoPageSpeed只是提供对单个页面的性能测试而SearchConsole是正对整个网站的性能测试。PageSpeedInsights也提供了供我们使用。同样的我们可以以把它集成到CI中。4.3CrUXChromeUXReport(CrUX)是指会聚了成千上万条用户体验数据的数据报告集它是经过用户同意才进展上报的目前存储在GoogleBigQuery上可以使用账号登陆进展查询。它测量了所有的CoreWebVitals指标。上面提到的PageSpeedInsights工具就是结合CrUX的
33、数据进展分析给出的结论。当然CrUX如今也提供了API共我们进展查询可以查询的数据包括LargestContentfulPaintCumulativeLayoutShiftFirstInputDelayFirstContentfulPaint原理如下CrUX通过API的查询的数据每日都更新并聚集了过去28天的数据。详细的使用方式可以参考官方给出的。4.4ChromeDevToolsPerformance面板Performance是我们最常用的本地性能分析工具。devtools-panel这里像提几点可以关注下的功能Frame、Timings、Main、Layers、FPS。下面一一讲解。4.4
34、.1Frame点击Frame展开后会看到有一个一个红色或者绿色小块这些代表着每帧的消耗时间。目前大多数设备的屏幕刷新率为60次/秒阅读器渲染页面的每一帧的速率假如与设备屏幕的刷新率保持一致即60fps时我们是不会感悟到页面卡的情况的。我们把鼠标移上去看看frame-58这种是体验顺畅的情况。再比方frame-32提示这一帧耗时了30.9ms当前是32fps并且是掉帧状态。4.4.2Timings这里可以看到几个关键指标的时间点。FPFirstPaintFCPFirstContentfulPaintLCPLargestContenfulPaintDCLDOMContentLoadedEventL
35、OnLoadEvent。timings4.4.3MainMain是DevTools中最常用也是最重要的功能。main通过record我们可以查看页面上所有操作在主线程中的执行经过。也就是我们常讲的流程main-thread一旦有任何一个流程时间过长或者频繁发生比方UpdateLayerTree时间过长、频繁出现RecalcStyles、Layout(重绘回流)那么需要引起注意。后面会举一个例子。4.4.4LayersLayers是阅读器在绘制经过中生成的一个层。因为阅读器底层渲染的本质是纵向分层、横向分块。这一块的知识点是发生在RendererProcess进程中。后面会以一个例子展开讲。这里
36、想提Layers的原因是Layer的渲染也会影响性能问题而且有时候还不容易被发现Layers面板一般不会默认展示出来点击更多-moretools-Layers即可翻开。点击Layers面板点击左边下三角展开按钮可以看见页面最终生成的合成层。右边左上角可以选择不同纬度进展查看。layers-detail选中某个层可以查看该层生成的原因。layer-reasonChrome的Blink内核给出了54种会生成合成层的原因constexprCompositingReasonStringMapkCompositingReasonsStringMapCompositingReason:k3DTransfo
37、rm,transform3D,Hasa3dtransform,CompositingReason:kTrivial3DTransform,trivialTransform3D,Hasatrivial3dtransform,CompositingReason:kVideo,video,Isanacceleratedvideo,CompositingReason:kCanvas,canvas,Isanacceleratedcanvas,orisadisplaylistbackedcanvasthatwaspromotedtoalayerbasedonaperformanceheuristic.,C
38、ompositingReason:kPlugin,plugin,Isanacceleratedplugin,CompositingReason:kIFrame,iFrame,IsanacceleratediFrame,CompositingReason:kSVGRoot,SVGRoot,IsanacceleratedSVGroot,CompositingReason:kBackfaceVisibilityHidden,backfaceVisibilityHidden,Hasbackface-visibility:hidden,CompositingReason:kActiveTransform
39、Animation,activeTransformAnimation,Hasanactiveacceleratedtransformanimationortransition,CompositingReason:kActiveOpacityAnimation,activeOpacityAnimation,Hasanactiveacceleratedopacityanimationortransition,CompositingReason:kActiveFilterAnimation,activeFilterAnimation,Hasanactiveacceleratedfilteranima
40、tionortransition,CompositingReason:kActiveBackdropFilterAnimation,activeBackdropFilterAnimation,Hasanactiveacceleratedbackdropfilteranimationortransition,CompositingReason:kXrOverlay,xrOverlay,IsDOMoverlayforWebXRimmersive-armode,CompositingReason:kScrollDependentPosition,scrollDependentPosition,Isf
41、ixedorstickyposition,CompositingReason:kOverflowScrolling,overflowScrolling,Isascrollableoverflowelement,CompositingReason:kOverflowScrollingParent,overflowScrollingParent,Scrollparentisnotanancestor,CompositingReason:kOutOfFlowClipping,outOfFlowClipping,Hasclippingancestor,CompositingReason:kVideoO
42、verlay,videoOverlay,Isoverlaycontrolsforvideo,CompositingReason:kWillChangeTransform,willChangeTransform,Hasawill-change:transformcompositinghint,CompositingReason:kWillChangeOpacity,willChangeOpacity,Hasawill-change:opacitycompositinghint,CompositingReason:kWillChangeFilter,willChangeFilter,Hasawil
43、l-change:filtercompositinghint,CompositingReason:kWillChangeBackdropFilter,willChangeBackdropFilter,Hasawill-change:backdrop-filtercompositinghint,CompositingReason:kWillChangeOther,willChangeOther,Hasawill-changecompositinghintotherthantransformandopacity,CompositingReason:kBackdropFilter,backdropF
44、ilter,Hasabackdropfilter,CompositingReason:kBackdropFilterMask,backdropFilterMask,Isamaskforbackdropfilter,CompositingReason:kRootScroller,rootScroller,Isthedocument.rootScroller,CompositingReason:kAssumedOverlap,assumedOverlap,Mightoverlapothercompositedcontent,CompositingReason:kOverlap,overlap,Ov
45、erlapsothercompositedcontent,CompositingReason:kNegativeZIndexChildren,negativeZIndexChildren,Parentwithcompositednegativez-indexcontent,CompositingReason:kSquashingDisallowed,squashingDisallowed,Layerwasseparatelycompositedbecauseitcouldnotbesquashed.,CompositingReason:kOpacityWithCompositedDescend
46、ants,opacityWithCompositedDescendants,Hasopacitythatneedstobeappliedbycompositorbecauseofcompositeddescendants,CompositingReason:kMaskWithCompositedDescendants,maskWithCompositedDescendants,Hasamaskthatneedstobeknownbycompositorbecauseofcompositeddescendants,CompositingReason:kReflectionWithComposit
47、edDescendants,reflectionWithCompositedDescendants,Hasareflectionthatneedstobeknownbycompositorbecauseofcompositeddescendants,CompositingReason:kFilterWithCompositedDescendants,filterWithCompositedDescendants,Hasafiltereffectthatneedstobeknownbycompositorbecauseofcompositeddescendants,CompositingReason:kBlendingWithCompositedDescendants,blendingWithCompositedDescendants,Hasablendingeffectthatneedstobeknownbycompositorbecauseofcompositeddescendants,CompositingReason:kPerspectiveWith3DDescendants,perspectiveWith3DDescendants,Hasaperspec