最近看到的不熟悉的词挺多的,只能一个个找资料一个个字看,然后自己根据自己的理解进行一定的总结,若有不对之处,还请路过的大佬不吝指正。
一.什么是渲染
页面渲染引擎的基本操作,简单而言是从一个网页的Url开始,根据Url所对应的网页各项资源,输出可视化的结果的过程;
基本流程可大致分为:
- Compute Style。根据Url读取解析Html、Css文件,根据Html代码形成Dom(文本对象模型)Tree,根据Css形成Css Rule Tree(Css规则树);
- Construct Frames。在根据Dom Tree和Css Rule Tree之上,创建一颗由一组待生成对象组成的Rendering Tree (渲染树);
- Layout。计算每个Element(对象)的位置,定位坐标和大小,是否换行,各种position, overflow, z-index属性等等等等;
- Painting。将Rendering Tree(渲染树)上的元素展现在浏览器上,形成可视化结果。
整个过程中可以注意的一些小问题:
1. 浏览器载入 HTML 代码,检测到 <head> 中有 <link> 引用外部 CSS 文件,则浏览器立即发送CSS文件请求,获取浏览器返回的CSS文件; (CSS文件合并,减少HTTP请求) 2. 浏览器载入 HTML 中 <body> 部分的代码,并且 CSS 文件已经加载,开始渲染页面; (CSS文件需要放置最上面,避免网页重新渲染) 3. 浏览器在代码中发现一个 <img> 标签引用了一张图片,向服务器发出请求。此时浏览器不会等到图片下载完,而是继续渲染后面的代码; (图片文件合并,减少HTTP请求) 4. 服务器返回图片文件,由于图片占用了一定面积,影响了后面段落的排布,因此浏览器需要回过头来重新渲染这部分代码; (最好图片都设置尺寸,避免重新渲染) 5. 浏览器检测到了一个包含JavaScript 代码的 <script> 标签,会立即运行该js代码; (script最好放置页面最下面) 6. js脚本执行了语句,它令浏览器隐藏掉代码中的某个 <div>,突然就少了一个元素,浏览器不得不重新渲染这部分代码; (页面初始化样式不要使用js控制)
二.影响渲染速度的两个因素
repaint(重绘)
如果只是改变某个元素的背景色、文 字颜色、边框颜色等等不影响它周围或内部布局的属性,譬如background-color(背景色), border-color(边框色), visibility(可见性),将只会引起浏览器 repaint(重绘)。repaint 的速度明显快于 reflow(在IE中例外,reflow 要比 repaint 更缓慢)。
reflow(回流)
说到页面为什么会慢?那是因为浏览器要花时间、花精力去渲染,尤其是当它发现某个部分发生了点变化影响了布局,需要倒回去重新渲染, 该过程称为reflow(回流)。
reflow 几乎是无法避免的。现在界面上流行的一些效果,比如树状目录的折叠、展开(实质上是元素的显 示与隐藏)等,都将引起浏览器的 reflow。鼠标滑过、点击……只要这些行为引起了页面上某些元素的占位面积、定位方式、边距等属性的变化,都会引起它内部、周围甚至整个页面的重新渲 染。通常我们都无法预估浏览器到底会 reflow 哪一部分的代码,它们都彼此相互影响着。
如何尽量避免reflow(回流)
reflow(回流)是导致DOM脚本执行低效的关键因素之一。页面上任何一个结点触发reflow,都会导致它的子结点及祖先结点重新渲染。
在哪些情况下会导致reflow发生:
–改变窗囗大小
–改变文字大小
– 添加/删除样式表
–内容的改变,如用户在输入框中敲字
–激活伪类,如:hover (IE里是一个兄弟结点的伪类被激活)
– 操作class属性
–脚本操作DOM
–计算offsetWidth和offsetHeight
–设置style属性
reflow是不可避免的,只能将reflow对性能的影响减到最小。可行方法包括:
– 尽可能限制reflow的影响范围。需要改变元素的样式,不要通过父级元素影响子元素。最好直接加在子元素上。
– 通过设置style属性改变结点样式的话,每设置一次都会导致一次reflow。所以最好通过设置class的方式。
–实现元素的动画,它的position属性应当设为fixed或absolute,这样不会影响其它元素的布局。
– 权衡速度的平滑。比如实现一个动画,以1个像素为单位移动这样最平滑,但reflow就会过于频繁,CPU很快就会被完全占用。如果以3个像素为单位移动就会好很多。
– 不要用tables布局的另一个原因就是tables中某个元素一旦触发reflow就会导致table里所有的其它元素reflow。在适合用table的场合,可以设置table-layout为auto或fixed,这样可以让table一行一行的渲染,这种做法也是为了限制reflow的影响范围。
–如果css里有expression,每次都会重新计算一遍。
– 减少不必要的 DOM 层级(DOM depth)。因为改变 DOM树中的一级会导致所有层级的改变,上至根部,下至被改变节点的子节点,这导致大量时间耗费在执行 reflow 上面。
– 避免不必要的复杂的 CSS 选择器,尤其是后代选择器(descendant selectors),因为为了匹配选择器将耗费更多的 CPU。
其中有一些是其他大佬的博文中的观点,因为知识储备问题,咸鱼对于少部分词并没有完全的理解,所以只将在大佬博文中出现的较多的观点也记了下来,以备之后会回头看时能产生新的领悟。
以上。