布局和WEB性能

在初始页面加载问题之外,“布局颠簸”是我在动态Web应用程序中看到的最常见的性能问题。 对于单页应用程序尤其如此,它可以动态构建和销毁视图。 但是,我常常对我遇到的Web开发人员的数量感到惊讶,他们不知道导致浏览器做不必要的布局的模式(在Mozilla社区中也称为“重排”)。 如果您使用WebKit浏览器进行开发,可以使用大量工具来指出这些问题。

 

计算和无效布局

与几乎所有其他UI工具包一样,您的Web浏览器具有自动布局的概念,其中页面中的元素添加css样式并指出屏幕上每个元素应该出现的位置。 这可能是一个昂贵的过程,并且由于显而易见的原因,费用与页面中元素的数量成比例增长。 让开发人员遇到麻烦的部分是Web浏览器使用按需模型进行布局。 它避免计算页面的布局,直到它真正需要知道屏幕上的某些内容会出现。 然而,这以令人惊讶的方式与DOM API交互。 考虑以下代码:

elementA.className = "a-style";
var heightA = elementA.offsetHeight;  // layout is needed
elementB.className = "b-style";       // invalidates the layout
var heightB = elementB.o

访问offsetHeight是DOM API的一部分,需要浏览器具有最新的布局。 重要的是要意识到改变样式可能会使您刚刚完成的所有工作无效,因此第二次请求offsetHeight需要运行另一个布局。 有时这是你的意图,但更常见的是第二种布局是完全浪费的工作。 比较,例如,这个类似的片段:

elementA.className = "a-style";
elementB.className = "b-style";
var heightA = elementA.offsetHeight;   // layout is needed and calculated
var heightB = elementB.offsetHeight;   // layout is up-to-date (no work)

由于这种行为,复杂的Web应用程序在测量(计算)和更新(无效)布局时必须要注意。 在我的简单示例中,很容易发现问题,但是当使用解耦组件正确构建UI时,这可能是一项更加困难的任务。 正确封装UI组件实际上往往会使调试这些问题变得更加困难,因为每个小部件都倾向于测量构造所需的事物,以最小化其抽象泄漏的程度。

 

识别布局问题

曾经有一段时间发现这些问题非常困难。我曾经保留了所有开源浏览器的检测版本,并​​且有一套针对IE的大量黑客攻击(其中包括对本机代码进行前导修补)。虽然Chrome的情况已经好多了。幸运的是,修复Chrome中的布局问题也会延续到其他浏览器。我这样选择的工具是Speed Tracer。不过,我有点偏颇,因为我建造它(当然有很多帮助)。还有一个直接内置于Chrome的Dev Tools中的面板,名为Timeline。您在Timeline和Speed Tracer中找到的跟踪数据几乎相同,因为Timeline实际上建立在我们为Speed Tracer添加的仪器上。我仍然发现Speed Tracer对数据的呈现更加直观,但同样,我确实设计了大部分数据。如果您可以在Timeline面板中找到自己的方式,那么它确实具有积极开发并定期更新功能的好处。例如,他们最近添加了一种帧模式,用于逐帧组织定时数据。

广州VI设计公司https://www.houdianzi.com

例如

如果不举一个例子,谈论这个问题对我来说是愚蠢的。 我在下面嵌入了一个简单的图形,并添加了两个按钮来更新该图形中的一些元素。 第一种使用受布局颠簸影响的策略。 第二个没有。 我将跳过详细分析,以鼓励您尝试上面提到的工具。 但是,代码只是嵌入了我之前描述的两种模式。

示例请见原文,这里只是不能操作的图片

在我自己的笔记本电脑上使用Chrome,第一个策略大约需要250毫秒,第二个策略只需大约15毫秒。 鉴于两者表现相同,这是一个相当大的差异。 随着应用程序越来越大,DOM元素越多,应用于这些元素的样式越多,问题就越严重。 实际上,由于布局颠簸,我实际上看到非常大的应用需要几秒钟才能完成看似微不足道的更新。

 

是什么导致浏览器layout?

当开发人员意识到存在这个问题时,他们正确地想知道DOM API中可能导致布局的所有属性和功能。 有很多。 我在2010年为WebKit收集了一份清单,我在下面列出了这个清单。 然而,一个更难回答的问题是,元素风格的变化会导致其布局失效。 回答这个问题通常需要试用,错误和良好的工具,比如前面提到的两个。

 

请记住,我只列出与html相关的对象。 我故意忽略了WebKit前缀API和SVG对象,但其中许多也可能导致布局。 一个令人惊讶的条目是Element.innerText。

posted @ 2020-11-25 13:47  浅笑·  阅读(87)  评论(0编辑  收藏  举报