避免复杂的layout

layout是浏览器计算元素的几何信息:元素在页面上的的大小和位置。

每个元素都有明确的亦或含蓄的大小信息,这些信息基于我们使用的css以及元素的内容被高和父亲元素。

这个过程在 Chrome, Opera, Safari, 和Internet Explorer中叫做Layout.在火狐浏览器中叫做Reflow。

  • Layout的范围是整个文档
  • DOM元素的数量将会影响表现性能:你应该尽可能的禁止触发layout
  • 估计layout模型的性能:新的FlexBox比原来的基于float的layout模型要快的多

影响layout性能的是:

  1. 需要layout的元素数量
  2. layout的复杂程度

尽可能避免使用layout

当你修改样式的时候,浏览器会检查你的修改是否会要求layout被计算,如果有的话讲更新render tree。

会触发layout的属性都是“几何的属性”,例如: widths, heights, left, or top 等

.box {
  width: 20px;
  height: 20px;
}

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

layout作用于整个文档,所以如果有许多的元素的话,将花费很长的时间来计算元素的位置和大小。

如果不可避免使用layout,那么使用Chrome开发者工具的timeline来追踪查看每个layout的耗费。

我们可以看见上面我们在layout上面花费了20ms多,如果我们在动画上花费了16ms,那么这个动画就耗费太多资源了。

你同样可以看见开发者工具总告诉我们树的大小(在上面的情况中有1618个元素),也告诉我们多少节点需要被layout。

Note

  • 想要一个确切的css属性清单确认哪些属性触发layout,paint和 dimensions ?点击这里:CSS Triggers.

用flexbox替代老的layout模型

网络有一系列的layout模型,一些的支持性相对于其他模型支持性更好。

旧的layout模型允许我们将元素相对定位,亦或绝对定位,亦或float布局在屏幕上。

下面的截图展示了一个layout(在1300个box上使用float布局)的耗费,这是一个手动的例子,因为现实的应用中我们会使用一系列的定位方式来定位元素。

如果我们使用FlexBox来定位元素,下面将展示不同:

现在我们在布局上节省了一些时间(例子中3.5msVS14ms),记住上面的对比是作用在相同的元素且产生相同的效果。

虽然很少的浏览器支持flex布局,但是为了很好的性能,你还是要进行尝试!

查看flexbox布局支持比float少的文档: less widely supported than floats

总而言之,不管你使用的浏览器是否支持flexBox,你都应该尽可能的避免触发layout.

避免强制执行layout

将帧运输到屏幕上的顺序是下面这样的:

先运行js,之后计算样式,然后layout。

但是,我们可以强迫浏览器在js之前执行layout。这被叫做强制执行layout。

首先要知道的是在所有旧的layout上面js可以访问之前帧的任何内容。

下例中,我们想在帧的开始书写一个元素(让我们把它叫做“盒子”)的高度,我们书写代码如下:

// 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);
}

如果我们在js获取盒子高度之前就改变了盒子的高度样式,那么会产生问题:

function logBoxHeight() {

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

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

现在,浏览器为了计算js中的高度问题,浏览器必须先运行样式的改变(因为代码中加入了super-class样式),然后运行layout。只有这样才能返回正确的高度。这是不必要且耗费巨大的工作。

因为你总是要先读取样式(样式信息保存在之前的帧的layout值中),然后再进行任何的书写操作:

正确的代码是这样的:

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

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

在大多数情况下你不必要先应用样式然后计算值;使用最后一帧的值将变得绰绰有余。强制layout在js之前运行将会耗费巨大,且浏览器将会进入瓶颈,这是我们不想看到的。

避免layout thrashing

比上面强制执行layput更加糟糕的是:连续执行强制layout。

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的offWidth的值并且将其赋值给一个paragraph(paragraphs[i].style.width)。在洗一次循环的时候,浏览器会计算已经更改的布局,然后再进行layout,每一个循环都会这样的进行!

更改之后变得更加可度:

// Read.
var width = box.offsetWidth;

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

如果你想确保安全性,你可以在 FastDOM网站上检查。该网站好处。。。。你试过就知道了

原文:https://developers.google.com/web/fundamentals/performance/rendering/avoid-large-complex-layouts-and-layout-thrashing?hl=en

时间: 2024-12-10 03:34:06

避免复杂的layout的相关文章

Android新建项目手动添加Layout布局

前言: 这是看<第一行代码>学习到的第一章,之前使用Eclipse创建Android项目都是自动生成MainActivity.java文件和layout文件夹下的activity_main.xml布局文件,今天把自动生成这些文件的对勾去掉后,手动创建了这两个           文件,于是就写下随笔来记录一下加深印象,同时这也是申请博客以来第一次发表一些东西,就是想把记笔记当做一个习惯保持下去,OK,到这里了.... 1.所有创建项目的步骤都是一样的,只有到最后把Create Activity

寒假学干货之------初步布局Layout

在开发的最初,需要设计好我们的Activity,在res/layout下,找到**activitymian(名字都差不多的)的.xml文件,打开他就可以开始编辑. http://www.tuicool.com/articles/3uUZbmu(参考,转载文献网址) 下面是几个比较常用的布局: LinearLayout(线性布局).FrameLayout(单帧布局).AbsoluteLayout(绝对布局).TablelLayout(表格布局).RelativeLayout(相对布局).其中最常用

如何解决Xamarin for VS:Disconnected from layout renderer

最近学习Xamarin for Android,我用的是for VS2013版本.由于开始使用的Xamarin是低版本的,所以在和VS2013配合后,可以编译,可以release,但是不能查看layout文件的布局文件.总是出现: Disconnected from layout renderer.后来从Xamarin的官网论坛上查到是因为Android SDK tools的版本过高才导致的此问题.?当时论坛的信息比较老,没有给出我当时使用版本的对应解决方案.于是我就只能自己试验了.最后结合论坛

HTML框架布局 - layout.border

经常用到上下左右,中间填充满这样的布局,在java swing中有BorderLayout,HTML中通常使用CSS来实现布局,但要实现border layout这样的效果有些麻烦,很多第三方实现,比如easyui, extjs,功能过于强大,我只是想要一个简单的布局而已,于是自己写了个jquery布局插件,支持嵌套布局以及小功能,方便团队使用,项目地址:https://github.com/samsha/layout.border 简介 简单的布局效果,实现上下左右,中间充满的布局 依赖 需要

【Css】Layout布局(二)

css定位(Positioning) 所谓定位,即允许你定义元素框相对于其正常位置应该出现的位置,或者相对于父元素.另一个元素甚至浏览器窗口本身的位置. css提供了三种基本的定位机制:普通流.浮动和绝对定位. position语法:  position : static absolute relative  普通流(static): 也有叫做文档流的,即元素按照其在 HTML 中的位置顺序决定排布的过程.并且这种过程遵循标准的描述. 相对定位(relative): 元素框偏移某个距离.元素仍保

皮内的预检模块i-Cut Layout Essential & Preflight v14.0

i-Cut Layout Essential & Preflight v14.0 for MacOSX 2CD 皮内的预检模块  皮内的预检 对于Mac windowstrial试验  一个简单的PDF预检,预检带来PstI酶切和大幅面打印编辑解决方案.  皮内的准备是一个真正的工作流的起点.问题自动报告,在打印前.没有必要去Adobe?插画?和浪费时间试图找出为什么文件将不能正确打印.皮内的预检会告诉自动.  真正的形状与皮内的布局模块嵌套  皮内的布局至关重要  皮内的布局基本符合所有基本功

View的layout机制

View框架的工作流程为:测量每个View大小(measure)-->把每个View放置到相应的位置(layout)-->绘制每个View(draw). 源代码分析 在View的源代码中,提取到了下面一些关于layout过程的信息. 我们知道,整棵View树的根节点是DecorView,它是一个FrameLayout,所以它是一个ViewGroup,所以整棵View树的测量是从一个ViewGroup对象的layout方法开始的. View: 1.layout //分配一个位置信息到一个View

网站前端_EasyUI.基础入门.0009.使用EasyUI Layout组件的最佳姿势?

1. 基础布局 <div id="l" class="easyui-layout" data-options="width:500,height:250">     <div data-options="region:'north',title:'north',height:50"></div>     <div data-options="region:'west',tit

Android中,如何提升Layout的性能?

Layout 是 Android 应用中直接影响用户体验的关键部分.如果实现的不好,你的 Layout 会导致程序非常占用内存并且 UI 运行缓慢.Android SDK 带有帮助你找到 Layout 性能问题的工具. 主题一:优化Layout层级 一个常见的误区是,用最基础的Layout结构可以提高Layout的性能.然而,因为程序的每个组件和Layout都需要经过初始化.布局和绘制的过程,如果布局嵌套导致层级过深,上面的初始化.布局和绘制操作就更加耗时.例如,使用嵌套的LinearLayou

布局 - layout

边框布局(border layout)提供五个区域:east.west.north.south.center.以下是一些通常用法: north 区域可以用来显示网站的标语. south 区域可以用来显示版权以及一些说明. west 区域可以用来显示导航菜单. east 区域可以用来显示一些推广的项目. center 区域可以用来显示主要的内容. <div class="easyui-layout" style="width:400px;height:200px;&quo