引入“布局边界”
“布局”是浏览器在开始绘制像素之前计算文档中每个元素的位置和大小的过程。布局的过程可能是昂贵的,特别是在低功耗移动设备上。
作为周到的前端开发人员,我们的工作是将布局保持在最低限度,以确保我们的应用保持畅通。尽管如此,布局必须完成。DOM结构更改,元素的尺寸或位置的更改以及通过JavaScript对元素位置或大小的请求,都可以触发布局。
不常见的是布局事件有范围。大多数情况下,布局强制更改到您应用的一小部分,将导致整个文档被回填; 这可能意味着数千个节点。
引入“布局边界”
通过一些小的CSS调整,我们可以在我们的文档中强制布局边界。这意味着如果在布局边界元素的范围内进行任何强制更改的布局,则只需要“部分回流”,这样便宜得多!
要作为布局边界,元素必须:
- 作为SVG根(
<svg>
)。 - 成为文本或搜索
<input>
字段。
要么:
- 不显示
inline
或inline-block
- 没有百分比高度值。
- 没有隐含或
auto
高度值。 - 没有隐含或
auto
宽度值。 - 有一个显式的溢出值(
scroll
,auto
或hidden
)。 - 不是
<table>
元素的后代。
Paul Lewis的 Boundarizr工具可用于突出显示应用程序中哪些元素作为“布局边界”。
Facebook的例子
为了证明我的观点,我在Facebook上发现了一个可以进行优化的布局案例。当自动完成搜索下拉列表打开时,我们可以在时间轴上看到相当激进的布局,因为元素在列表中被插入和操作。
通过在Chrome Devtools时间轴中悬停布局事件,我们可以看到“布局范围”标记为“整个文档”(以蓝色突出显示),“布局树大小”为2551个节点,“持续时间”为2.142ms。
潜入“元素”面板中,我找到一个合适的父节点,其中DOM发生变化。我设置一个基于像素的高度,并设置overflow: hidden
。元素已经已经有position: absolute
,已经有一个宽度设置,所以我不必介绍这些更改。
这应该强制执行布局边界来将回流范围缩小到文档的一小部分。
我现在运行相同的例程,并在“时间轴”面板中再次观察布局事件。
当我们悬停在布局事件上,我们可以看到蓝色突出显示的区域现在只覆盖我们新推出的“布局边界”元素。“布局范围”现在标记为“部分”,“布局树大小”为228个节点(减少91%),“持续时间”为1.255ms(减少41%)。
这是微型优化吗?
在每个布局事件的持续时间方面,〜1ms的保存似乎相当微不足道,但是我们再考虑一点:
- 这个事件是当下拉菜单被显示时触发的大约20个类似的事件之一,并且每个事件在CSS调整之后获得类似的保存。
- 我们正在Chrome浏览器中的高功率MacBook Air上进行分析。这种类型的环境中的布局速度大大优于即使是最优秀的移动设备。如果我们将布局时间缩短了40%,那么布局速度较慢的设备的增益可能会很大。
- 这个特定的布局比较简单。在更复杂的(flexbox,表,浮动等)布局中,我们可能会看到更大的收益。
这个怎么用?
TBH我不是100%肯定的。我猜想通过约束父元素的大小,并确保后代元素不能通过设置overflow: hidden;
流出边界,通过假设不需要检查布局边界之外的节点,布局引擎优化。
这只适用于Chrome吗?
TBH我不确定,但是我猜想,其他浏览器布局引擎会在元素样式属性允许时进行类似的优化。
在撰写本文时(AFAIK),我们在其他浏览器的开发人员工具中没有提供与我们相同的布局分析。
如果有一些方法可以测量Chrome以外的浏览器,我很想听到它:)
结论
对我来说,这似乎是我们应该更多地考虑发展的东西。如果我们可以做出一些强化布局边界的超快速风格的改变,那么浏览器的工作量就会减少,我们得到更快的布局时间。
尝试在您的应用程序,让我们知道,如果你能够提高一些快速的性能提升。