web 应用开发最佳实践之一:避免大型、复杂的布局和布局抖动

Avoid Large, Complex Layouts and Layout Thrashing

布局是浏览器计算元素几何信息的地方:即元素在页面中的大小和位置。 每个元素都将具有基于所使用的 CSS、元素的内容或父元素的显式或隐式大小信息。 该过程在 Chrome、Opera、Safari 和 Internet Explorer 中称为布局(Layout).

在 Firefox 中,它被称为回流(reflow),但实际上过程是相同的。

与样式计算类似,布局成本的直接关注点是:

  • 需要布局的元素数量。

  • 这些布局的复杂性。

简而言之:

  • 布局通常限定于整个文档。

  • DOM 元素的数量会影响性能; 你应该尽可能避免触发布局。

  • 评估布局模型性能; 新的 Flexbox 通常比旧的 Flexbox 或基于浮动的布局模型更快。

  • 避免强制同步布局和布局抖动; 读取样式值然后进行样式更改。

Avoid layout wherever possible

当您更改样式时,浏览器会检查是否有任何更改需要计算布局,以及是否需要更新渲染树。 更改“几何属性”,例如宽度、高度、左侧或顶部都需要执行布局过程。

.box {
  width: 20px;
  height: 20px;}/** * Changing width and height * triggers layout. */.box--expanded {
  width: 200px;
  height: 350px;}

布局几乎总是作用于整个文档。 如果您有很多元素,则需要很长时间才能弄清楚它们的位置和尺寸。

如果无法避免布局,那么关键是再次使用 Chrome DevTools 来查看需要多长时间,并确定布局是否是造成瓶颈的原因。 首先,打开 DevTools,转到 Timeline 选项卡,点击记录并与您的站点进行交互。 当您停止录制时,您会看到您的网站表现的细分:

在上例中深入研究帧时,我们看到在布局内部花费了超过 20 毫秒,当我们有 16 毫秒在动画中在屏幕上显示帧时,这太高了。 您还可以看到 DevTools 会告诉您树的大小(在本例中为 1,618 个元素),以及需要布局的节点数量。

Avoid forced synchronous layouts

将网页运送到屏幕具有以下顺序:

首先运行 JavaScript,然后是样式计算,然后是布局。 但是,可以使用 JavaScript 强制浏览器提前执行布局。 它被称为强制同步布局。

首先要记住的是,当 JavaScript 运行时,前一帧中的所有旧布局值都是已知的,可供您查询。 因此,例如,如果您想在帧的开头写出元素的高度(让我们称其为“框”),您可以编写如下代码:

// Schedule our function to run at the start of the frame.requestAnimationFrame(logBoxHeight);function logBoxHeight() {
  // Gets the height of the box in pixels and logs it out.  console.log(box.offsetHeight);}

如果你在询问高度之前改变了盒子的样式,事情就会变得有问题:

function logBoxHeight() {

  box.classList.add('super-big');

  // Gets the height of the box in pixels  // and logs it out.  console.log(box.offsetHeight);}

现在,为了回答高度问题,浏览器必须先应用样式更改(因为添加了超大类),然后运行布局。 只有这样,它才能返回正确的高度。 这是不必要的并且可能是昂贵的工作。

因此,您应该始终批量读取样式并首先执行(浏览器可以使用前一帧的布局值),然后执行任何写入:

正确完成上述功能将是:

function logBoxHeight() {
  // Gets the height of the box in pixels  // and logs it out.  console.log(box.offsetHeight);

  box.classList.add('super-big');}

在大多数情况下,您不需要应用样式然后查询值; 使用最后一帧的值就足够了。 同步运行样式计算和布局并早于浏览器的预期是潜在的瓶颈,而不是您通常想要做的事情。

Avoid layout thrashing

有一种方法可以使强制同步布局变得更糟:快速连续地进行大量布局。 看看这段代码:

function resizeAllParagraphsToMatchBlockWidth() {

  // Puts the browser into a read-write-read-write cycle.  for (var i = 0; i < paragraphs.length; i++) {
    paragraphs[i].style.width = box.offsetWidth + 'px';
  }}

此代码遍历一组段落并设置每个段落的宽度以匹配名为“box”的元素的宽度。 它看起来无害,但问题是循环的每次迭代都会读取一个样式值(box.offsetWidth),然后立即使用它来更新段落的宽度(paragraphs[i].style.width)。 在循环的下一次迭代中,浏览器必须考虑自上次请求 offsetWidth(在前一次迭代中)以来样式已更改的事实,因此它必须应用样式更改并运行布局。 这将在每次迭代中发生!。

此示例的修复方法是再次读取然后写入值:

// Read.var width = box.offsetWidth;function resizeAllParagraphsToMatchBlockWidth() {
  for (var i = 0; i < paragraphs.length; i++) {
    // Now write.    paragraphs[i].style.width = width + 'px';
  }}
(0)

相关推荐

  • 软件需求分析和开发最佳实践

    作者:人月神话,新浪博客同名 简介:多年SOA规划建设,私有云PaaS平台架构设计经验,长期从事一线项目实践 今天准备谈下软件需求分析和开发方面的话题,软件需求是整个软件生命周期中最重要的一个环境,但 ...

  • 大型开发项目中 git 工作流的最佳实践

    Gitflow Workflow 是一个 Git 工作流,有助于持续软件开发和实施 DevOps 实践. 它由文森特·德里森 (Vincent Driessen) 在 nvie 首次出版并广受欢迎. ...

  • 价值定位和数据治理:某大型保险企业CMDB平台建设经验分享 | 最佳实践

    [摘要]CMDB似乎是运维中永恒的老话题,方法论很多,落地却发现理想与现实间存在巨大差距.本文试图从各类复杂的解决方案背后寻找决定性的深层逻辑,将围绕CMDB价值定位和数据治理两个核心问题,揭示主数据 ...

  • BAT 大厂测试开发技能成长最佳实践 | 霍格沃兹测试学院课程体系

    霍格沃兹测试学院简介 霍格沃兹测试学院是中国领先的测试技术高端教育品牌,致力于为 IT 行业提供高级测试开发技术培训和优秀人才内推服务.我们的愿景是成为测试开发工程师的黄埔军校. 霍格沃兹测试学院课程 ...

  • Spring Boot快速开发REST服务最佳实践

    一.为什么选择Spring Boot Spring Boot是由Pivotal团队提供的全新框架,被很多业内资深人士认为是可能改变游戏规则的新项目.早期我们搭建一个SSH或者Spring Web应用, ...

  • Android开发之漫漫长途 XIII——Fragment最佳实践

    作者:忘了12138 地址:http://www.cnblogs.com/wangle12138/p/8385990.html 声明:本文是 忘了12138 原创投稿,转发等请联系原作者授权. 该文章 ...

  • 7种人力资源最佳实践

    什么是人力资源最佳实践? 最佳实践是一套通用的人力资源管理流程和行动.在人力资源管理研究中,有两种关于如何管理人员的思想流派:第一个是最合适的,第二个是最佳实践. 最合适的观点指出,为了增加价值,人力 ...

  • 培训的定义、作用和最佳实践

    一.什么是人力资源开发? 人力资源开发一词最早是在1969年提出的,指的是劳动力的培训,教育和发展.它旨在弥合学校教育和工作场所要求之间的差距. 在早期,HRD会进行严格的动手培训,重点是掌握硬技能. ...

  • 从最佳实践的焦虑中解脱出来

    几乎每天都会出现关于最佳实践的头条新闻.例如: 1.参加一个会议:"XX公司会议创新管理提高效率,我们现在没有." 2.行业文章:"人力资源部即将消失." 3. ...