浏览器布局、绘制界面

作者: Miss____Du | 来源:发表于2014-11-08 18:31 被阅读814次

之前的内容里已经说了浏览器是如何进行加载解析渲染的,接下来浏览器就要根据渲染树中各个节点的顺序,实际样式属性值进行布局啦,也称Layout或是Flow。
之前的部分一直在说css、dom树。这一回js该出场了。
前二者好不容易生成渲染树,进行布局啦,js就来开始鼓捣啦,先将一个元素改改宽度,然后就放大招来个display=none,这些都在一定程度上改变着原有的布局位置。
js潇洒的走后,css、dom树又要忙叨起来,重新进行渲染布局。把他们两个这个过程就叫做reflow、repaint

科普一下这两只

repaint

当dom属性改变的仅是元素的外观,并不对布局造成影响,浏览器则会重新渲染这个元素,此过程称为repaint。

reflow

如果此次变化涉及元素的布局(width),则浏览器将抛弃原有属性值,进行重新渲染、布局。此过程称为reflow。
reflow必将引起repaint,repaint不一定会引起reflow,(repaint的概念范围应该包括reflow)

什么操作会引起浏览器进行reflow、repaint呢??

  1. DOM元素的添加、修改(内容)、删除。
  2. 隐藏元素。
    display=none;//reflow
    visibility=hidden;//repaint(需要css知识理解)
  3. 应用新的样式,或是修改任何影响元素外观的属性。
  4. 用户的操作,如改变浏览器的大小,改变浏览器的字体大小等。

当然这时候浏览器也会出来干点事,不能这样被玩啊,,
很多浏览器会维护一个队列,把所有会引起repaint与reflow的操作放入这个队列,等队列中的操作累积了一定数量,或者到了一定的时间间隔,浏览器就会对这个队列进行批处理。这样就会让多次重绘变成一次。

但是呢,js也不会善罢甘休,
当js想要获得dom的一些属性时,浏览器为了给出最精确的值,会flush队列,及把缓冲区的数据强行输出。
像这些属性:

  • offsetTop, offsetLeft, offsetWidth, offsetHeight
  • scrollTop/Left/Width/Height
  • clientTop/Left/Width/Height
  • width,height

How 如何才能尽可能的减少重绘的次数呢?

  1. 离线操作DOM

使用documentFragment(指文档碎片)进行缓存。然后将对dom节点的进行一次性的增加。
var oFragment = document.createDocumentFragment();
for(var i = 0 ; i < 10; i ++) {
var p = document.createElement("p");
var oTxt = document.createTextNode("段落" + i);
p.appendChild(oTxt);
oFragment.appendChild(p);
}
document.body.appendChild(oFragment);//一次性的添加子节点,只进行一次渲染刷新。
还有一种是如果你预先想在某个元素内进行dom节点的改动,你可以对这些元素的属性进行设置。
display=none;

  1. 集中修改样式
    这个理解起来比较简单。看一下例子(网上还有前辈进行了测试,大赞)。
    //逐一style
    testNode.style.color=‘#eee’;
    testNode.style.border=‘1px solid red’;
    testNode.style.fontSize=‘20px’;
    testNode.style.background=‘blue’;
    testNode.style.width=“200px”;
    //添加类名
    .className1 {color:#eee;border:1px solid red;font-size:20px;background:blue;width:200px’;}
    //...
    testNode.className = ‘className1’;
    //添加csstext
    testNode.style.cssText = ‘color:#eee;border:1px solid red;font-size:20px;background:blue;width:200px’;
    对比一下不同方法带来性能上的提升。所以建议大家采用增加样式类这种方式,进行集体修改样式。

    性能对比.png
  2. 缓存布局属性值
    // 别这样写
    for(循环) {� el.style.top = el.offsetTop + 5 + "px";�}
    ��// 这样写好点
    �var top = el.offsetTop;//缓存属性值,不要动态获得这个值。
    s = el.style;�
    for(循环) {� top += 10;� s.top = top + "px";�}

  3. 权衡动画帧宽
    关于动画帧宽
    动画帧宽英文
    我理解了一下,帧指的是一个静止画面,在网页动画里,这应该是界面内元素拥有的一组静态属性值时的界面。帧宽,两个界面之间的时间,可以理解为界面属性值改变的时间长度。即setinterval的时间值,而显示屏有自己的刷新频率,大概是在16.667ms,浏览器的repaint的时间是1ms。权衡一下设置的setinterval的时间值,使之尽可能与显示频的时间吻合,以减少重绘次数?这一点我说的不太肯定,得多看点资料才能肯定。

还有一个被忽略的元素<img>

遍历dom树时遇到这个标签,浏览器会发出一个异步请求,然后继续渲染dom树的其他节点。
但是可想而知,当图片资源获得后,又会改变原有的布局。
所以我们在为网页添加图片时,记得设置width与height属性。这样可以预先设置布局。

之后就是绘制啦,,
这就依靠浏览器的native GUI(这是浏览器的一个组成部分)啦
参考资源:
浅析浏览器解析和渲染
一次性处理添加节点的操作

欢迎补充与指正☺

相关文章

  • 浏览器布局、绘制界面

    在之前的内容里已经说了浏览器是如何进行加载解析渲染的,接下来浏览器就要根据渲染树中各个节点的顺序,实际样式属性值进...

  • 上下两排textView用RelativeLayout布局

    有效的减少布局结构加快界面绘制速度

  • 界面布局autoresizing

    一.界面布局过程 super view -layoutSubviews -setNeedsLayout 下次绘制之...

  • Android进阶实录1

    APP性能优化: 1:界面布局优化 在开发者选项中可以开启界面过渡绘制预览,查看自己app界面绘制使用情况,一般从...

  • 2020-05-29

    1. 浏览器进程 浏览器主进程:负责浏览器界面显示,各个页面的管理,创建以及销毁,将渲染进程的结果绘制到用户界面上...

  • 组件的布局

    简介 组件的布局就是实现onlayout方法,把子视图绘制在界面上。比如LinearLayout可以水平的布局,也...

  • 组件的测量

    1、简介 组件在显示到界面上要经过三个过程测量、布局、绘制。测量就是计算组件的大小,布局就是摆放组件的位置,而绘制...

  • Android绘制优化(二)布局优化

    相关文章 Android绘制优化(一)绘制性能分析 前言 我们知道一个界面的测量和绘制是通过递归来完成的,减少布局...

  • Android单位换算

    我们在开发过程中,一般使用xml进行界面布局的绘制,在设置界面布局宽高方面,Android提供了多种计量单位如di...

  • inflate方法的三种形式

    我们绘制布局界面,一般通过xml文件,以标签的形式去完成界面的开发,然后通过setContentView去解析就可...

网友评论

  • Miss____Du:@le_frank 凡事都会有一个过程,慢慢来,只要坚持,就可以
  • Miss____Du:@le_frank 四篇都看完了?我关于浏览器历史那部分还没写完,我是今年7月份开始学,像你一样只学了html、css,js,可以做做网页,简单的动画。那时候在实习,就没有了解具体原理,导致设计的代码缺乏优化。现在有时间,就想仔细研究研究,这些知识,我都是在写之前明确要些什么,然后在网上招大量的资料,看,自己理解,写出来大家分享,纠错。所以等有一天你觉得自己学的还可以的时候,回头再来看,我的文章,就会觉得我写的也漏洞百出,到时候再来评论啊 :grin:
  • lihuishan050638:哈,先mark下。从你基础文章的开始看。
    萌妹子学web前端,小握爪一下。我刚刚开始学iOS开发,嘻。
    还有UI啥的。

本文标题:浏览器布局、绘制界面

本文链接:https://www.haomeiwen.com/subject/laybtttx.html