前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >听说有个能优化性能的属性 contain

听说有个能优化性能的属性 contain

原创
作者头像
kmokidd
发布2019-04-16 13:51:52
8080
发布2019-04-16 13:51:52
举报

- 2017年的老文,搬运存档用 -

有优化效果,但限制较多,X5 兼容 iOS 不行

属性值列表

  • layout:防止元素内 layout 改变影响元素外,也防止其他元素改变影响这个元素。
  • paint:元素的子元素必须在元素的 content-box 中,不能超出,否则显示不出。子元素发生的任何改变都不会影响到与该元素之外的其他元素;同样该元素之外的其他元素都不会影响到子元素
  • size:用子元素是撑不开这个元素的(声明都不给它的尺寸会一直是 0x0),必须声明尺寸,且子元素不能超出元素的范围,这个属性能够阻止子元素不断变大 -> 改变父元素尺寸 -> 影响更多节点 -> 发成大面积重排。本身提供不了太大性能优化,一般是和 layout 搭配使用。
  • style:有些 CSS 属性会影响不只宿主元素和其子元素,比如 counter。为了限制这样的属性影响到别的元素,让它的影响力限制在宿主元素和其子元素范围内。强行生成一棵 DOM 子树,变成像 shadow dom 那样的情况,外面的变量不会影响里面的;里面的也不会影响到外面。
  • strict:layout style paint size
  • content:layout style paint

适用场景

  1. 元素在屏幕外不可见时
  2. 第三方插件
  3. container queries

Use Case

注意:实验环境都是 macOS 10.12.6 Chrome stable 61。第三方插件和 cotainer queries 用得少,所以没研究。

case 1

If you build a off-screen navigation or similar, the browser paints the content completely although it is not visible on load. By setting contain: paint; the user agent can skip the paint off the off-screen element and therefore paint all the other content faster.

上文的意思是“如果构建一个屏幕外的导航栏(汉堡侧边栏),虽然看不到,但浏览器其实还会渲染那部分节点的。如果设置了 cotain: paint 那浏览器就不会去渲染屏幕外的东西,所以相对的屏幕内的内容就会被更快地渲染出来”。

为了验证这个理论,将 FMP (first meaningful page) 和首次可操作时间 (First interactive) 作为主要的衡量标准,毕竟对于用户来说最有感知的应该也是这两个特性了。推理过程是这样的:

第一个页面:侧边栏有一个高斯模糊的图片,并动态加上了 1000 个高斯模糊的纯色点;通过改变 left 值实现的移入移出视口。(实验原则就是,怎么慢怎么来,满足了自己的破坏欲= =)

点击右上角「按钮」,控制侧边栏的移动:

多次实验后结果差不多是下面这样(Chrome devTools 的 Audits 面板):

二者的区别是在侧边栏上有无 contain: paint需要特别注意的是,添加了 contain: paint 相当于给元素加了一个 position:relative; overflow: clip,所以子元素会相对这个父元素来定位了:

代码语言:javascript
复制
aside {
   position: absolute;
   z-index: 1;
   top: 0;
   bottom: 0;
   left: -101%;
   transition: left 500ms ease;

   width: 80vw;
   overflow: hidden; /* 为了和有 contain:paint 时的视觉效果一样*/

   background-color: #414529;
   background-image: url('http://qzonestyle.gtimg.cn/aoi/sola/20170707104843_SfolTLGT5s.jpg');
   background-size: contain;
   background-repeat: no-repeat;
   filter: blur(10px);

   contain: paint;
}

aside.open {
  left: 0;
}

结论:FMP 和 First Interactive 都有优化,其中 FMP 优化了40ms。

内存使用情况如下图,这是多次试验以后取了效果对比最明显的:

case 2

按道理来说我们不应该看 FMP 而是应该看渲染的节点个数,但是因为侧边栏本身就是在复合层上,不参与 layout 时被影响的节点统计,通过开发者工具也没有检测到明显的效果(从上图中的 'layout' 可以看出)。所以写了另一个 demo,用来验证 Paul Lewis 文章中的效果:

实验内容就是,一个从上到下排列的页面结构,在中间颜色为黄色的节点内不断插入新的子节点,将会触发重排:

多次试验后的结果如下:

二者区别在于黄色节点有没有 contain: layout size。另外 overflow: hidden 不会影响 layout root,但会影响 Nodes That Need Layout 这一栏。需要特别注意的是这两个属性值的使用场景,元素一定要有固定尺寸的。代码如下:

代码语言:javascript
复制
article {
  position: relative;
  z-index: 1;
  background-color: #FFE32A;

 /* no containment */
 /* height: 200px;
  * overflow: hidden;
  */

  /* has containment */
  height: 200px;
  contain: layout size;
  overflow: hidden;
}

结论是,在会引起重排的场景下,可以有效缩小重排的范围。

兼容性

感谢 TBS 的同事,TBS 线上版本已经支持,也就是大安卓市场可以用起来了!但是 iOS…

参考资料

  1. CSS containment
  2. container-queries-issue3
  3. W3C - containment
  4. MDN - contain
  5. CSS Containment in Chrome 52

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 属性值列表
  • 适用场景
  • Use Case
  • case 1
  • 兼容性
  • 参考资料
相关产品与服务
云开发 CLI 工具
云开发 CLI 工具(Cloudbase CLI Devtools,CCLID)是云开发官方指定的 CLI 工具,可以帮助开发者快速构建 Serverless 应用。CLI 工具提供能力包括文件储存的管理、云函数的部署、模板项目的创建、HTTP Service、静态网站托管等,您可以专注于编码,无需在平台中切换各类配置。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档