Web 技术研究所

我一直坚信着,Web 将会成为未来应用程序的主流

Recalculate、Layout和Paint,CSS的渲染原理

  这个话题有点难切入正题,我们先从代码的效果开始看吧。 <style>
#panel {position:absolute;top:100px;left:100px;}
</style>
<div id="panel">次碳酸钴</div>
<script>
var s,i,y,top,panel;
s=["red","green","blue"];
i=0,y=100;
var VK_SPACE=32,VK_DOWN=40;
panel=document.getElementById("panel");
document.onkeydown=function(e){
  switch(e.keyCode){
    case VK_SPACE:
      panel.style.color=s[i++%3];
    break;
    case VK_DOWN:
      panel.style.top=++y+"px";
    break;
  };
};
</script>

  加载这个代码后,我们可以在Chrome的时间线中看到,有这两个事件被触发了。当然在此之前还有很多页面和服务器通信的事件,只不过我们现在讨论的是CSS相关的,就不去管那些了。
  现在我们先来看Layout事件。这个事件的工作是计算页面上元素的布局。什么是布局呢?就是元素在文档中的位置和大小。任何有可能改变元素位置或大小的样式都会触发这个Layout事件。上面的这个例子解释这个事件也许不太直观,就算你建立一个空HTML文档,它也会触发。因为就算是BODY元素也有默认的display、width、height,等这些属性。触发Layout事件,浏览器就会开始计算元素的位置与大小。如果觉得麻烦,你可以简单的把这个理解为元素的offset*属性。我们平时写JavaScript的时候使用的element.offsetTop之类的这属性,它们就是做的和Layout同样的事情。虽然可以那么理解,但是真正的Layout是在JavaScript执行完成后才触发的。
  Paint事件一会儿再说,我们继续看上面的例子。上面的例子中包含了两个键盘事件,按下空格键的时候元素的文字颜色会改变;按下向下箭头的时候元素会向下移动。我们来触发这两个键盘事件看看它们给渲染带来了什么影响。
  
  我先按了向下的箭头,再按了空格键。上面这张图中就能看出,我按下向下箭头时触发了Recalculate和Layout,这两个是在代码的第20行被触发的。后面按下了空格键,只触发了一个Recalculate,是在代码的第17行被触发的。
  现在,我们要搞明白的是Recalculate做了什么?从字面意思上来理解就是“重新计算样式”。没错,它就是干这个的。不要被谓语动词的Recalculate所迷惑,因为宾语是Style。也就是说,它计算的是Style,和Layout做的事情完全不同。Layout计算的一个元素绝对的位置和尺寸,或者说是“Compute Layout”。我们的汉语中有些概念是比较模糊的,所以学习一些技术性的东西有时候不能全用汉语来描述。我们应该用最适合的语言去描述最适合的东西。Compute和Calculate虽然都被翻译成计算,但是Compute更倾向数值计算,Calculate则是概念比较泛的计算。具体的应该去问英语老师。废话说了一堆,现在回到正题。Recalculate被触发的时候做的事情就是处理JavaScript给元素设置的样式而已。比如element.style.color="red";这样一行代码。当我们获取计算完成的样式时,这个red在Chrome中就会被解析成rgb(255,0,0)的格式,在别的浏览器中也有不同的处理结果,但是他们的处理模式是相同的。Recalculate做的事情就和getComputedStyle或IE的currentStyle类似,就是把样式转换成计算机容易识别的模式。总而言之就是任何企图改变元素样式的操作都会触发Recalculate。同Layout一样,它也是在JavaScript执行完成后才触发的。
  还有个Paint事件,这个事件会触发的很频繁。页面上显示东西有任何变动都会触发Paint。包括拖动滚动条、鼠标选中文字,等这些完全不改变样式,只改变显示结果的动作都会触发Paint。Paint的工作就是把文档中用户可见的那一部分展现给用户。Paint是把Layout和Recalculate的计算的结果直接在浏览器窗体上绘制出来,它并不实现具体的元素计算。这个就很明显的是在JavaScript执行完成后才执行了,或者说应该是在执行完Recalculate和Layout之后才执行。这个你可以用JavaScript生成一个10万个元素的页面,就很容易在时间线条上看出它们的执行顺序和效率。
  最后,我把这个渲染过程总结为了图,看这个图应该就很容易理解了。

  以上就是CSS渲染的大概原理,如有问题,可以提出。
网名:
3.84.186.*
电子邮箱:
仅用于接收通知
提交 悄悄的告诉你,Ctrl+Enter 可以提交哦
神奇海螺
[查看全部主题]
各类Web技术问题讨论区
发起新主题
本模块采用即时聊天邮件通知的模式
让钛合金F5成为历史吧!
次碳酸钴的技术博客,文章原创,转载请保留原文链接 ^_^