二三面_渲染机制类
Posted 煜成'Studio
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二三面_渲染机制类相关的知识,希望对你有一定的参考价值。
二三面_渲染机制类
二三面js面试技巧
1.知识面要广*
一面更看重基础,二面更看重知识面是不是广,是不是你了解的比较多
2.理解要深刻*
知识体系的深度,比如说做前端除了html、css、js,打交道最多的是浏览器,所以对浏览器的一些特性要掌握,对js引擎要掌握,等等深度,多准备,多涉猎,二面过程中一般都会问到
3.内心要诚实
这东西你了解过就是了解过,没了解过也不要说自己忘了之类的,直接承认没了解过,问一下面试官我应该去学哪些资料去快速地把这块知识的漏洞补上,这是你应该有的态度
4.态度要谦虚
自己不懂不要觉得是对方出题难为你,也不要你会了你就觉得他没有你掌握的多,就开始膨胀,这都不应该是求职者在面试过程中应该出现的两种心态
5.回答要灵活
每个人学习知识的方向、资料、来源和渠道都可能不一样,那么谁看的最准那,面试官也不一定是权威的是对的,但是谁对谁错,在面试中千万不要去争论这个东西,所以回答要灵活,这东西要把握一个度,如果面试官对你的这方面很质疑的话,你可以有一个回旋的余地,你说我可以查一下资料去验证一下这个到底是不是对的,这个就是个小聪明的技巧,你没有否认自己说的是错的,也没承认对方是对的,所以这个部分核心的点是不要和面试官争对错,非常重要,一个团队合作不能总认为自己是对的,至少在查清楚之前不能急于下结论,这是做程序员应该有的一个严谨的态度,如果你觉得凡事都是自己是正确的,那么这个肯定是不符合任何公司的文化的
6.要学会赞美
比如说这块问的浏览器本身的机制和原理特别多,也特别深,平时工作中也没接触过,自己也没深入地学习过,被问住了很正常,那么怎么去快速地结束这个话题,又不让面试官对自己有过低的评价那,就是说好话,赞扬面试官,就说他研究的深,自己没研究的那么深,就OK了,他不可能给你更高的级别但是他会让你通过,不是说你只要赞美他什么做就能通过,是说相对的情况下,比如问到你了,一直是不会不会不会,面试官是很反感这种回答问题的方式的,说好话谁的爱听
正文:
什么是DOCTYPE及作用
DTD(document type definition,文档类型定义【HTML和XML就是一种文档,而且他俩是不同类型的文档】)是一系列的语法规则,用来定义XML或(X)HTML的文件类型。浏览器会使用它来判断文档类型,决定使用何种协议解析,以及切换浏览器模式。
【DTD就是告诉浏览器我是什么文档类型,浏览器根据这个来判断用什么引擎来解析它和渲染它】
DOCTYPE是用来声明文档类型和DTD规范的,一个主要的用途便是文件的合法性验证。如果文件代码不合法,那么浏览器解析时便会出一些错误。
【DOCTYPE就是直接告诉浏览器什么是DTD的,也就是说,DOCTYPE通知浏览器告诉当前的文档包含的是哪个DTD,也就是哪个文档类型】
面试官追问:
常见的DOCTYPE有哪些,然后写一下html5的DOCTYPE怎么写
HTML5
<!DOCTYPE html>
HTML 4.01 Strict
该DTD包含所有的HTML元素和属性,但不包含展示性和弃用的元素(比如foot)
下面两种写法的DOCTYPE的头不用记住,知道4.01版本有两个模式,一个是传统模式,一个是严格模式,和他们之间的区别
<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01//EN” “http://www.w3.org/TR/html4/strict.dtd”>
HTML 4.01 Transitional
该DTD包含所有的HTML元素和属性,包含展示性和弃用的元素(比如foot)
<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01Transitional//EN” “http://www.w3.org/TR/html4/loose.dtd”>
浏览器渲染过程(或者这么问,在浏览器中输入一个url,发生了哪些事情,一步步描写清楚,其中有一步就是浏览器的渲染过程)
浏览器渲染页面(我们能看到的html)涉及html、css、js,这三方面都会影响你最后页面的呈现形式
html和css分别经过整合为DOM Tree和CSSOM Tree,再到Render Tree(在layout之前,它不包含html的具体内容,也不知道这个位置是什么,就是在layout之前,它不知道div等具体应该画在屏幕的什么位置),通过layout精确地计算到DOM元素要显示的位置、宽、高、颜色都可以在Render Tree呈现出来,Painting就是浏览器根据GUI就开始画图了,把内容基本都呈现出来,DIsplay就是大家能在浏览器上看到的效果。
通过下面的图进行理解
CSSOM Tree里面的属性值是计算完最终的
再把DOM Tree和CSSOM Tree重新结合进行计算,再经过一个Layout过程(Layout的任务是计算每一个DOM的位置、宽、高),生成Render Tree,再交给浏览器Painting
重排Reflow(问完了渲染过程,一般情况下都会紧接着问Reflow)
定义:
DOM结构中的各个元素都有自己的盒子(模型),这些都需要浏览器根据各种样式来计算并根据计算结果将元素放到它该出现的位置,这个过程称之为Reflow
触发Reflow:
1.当你增加、删除、修改DOM节点时,会导致Reflow或Repaint;(导致了Reflow会导致Repaint)
2.当你移动DOM的位置,或是搞个动画的时候;
3.当你修改CSS样式的时候;(CSS改变宽、高、diaplay: none、visibility: hidden等,满足了重新Reflow的条件也会触发Reflow)
4.当你Resize窗口的时候(移动端没有这个问题),或是滚动的时候,有可能会触发Reflow,要看一下浏览器的一些具体的规则;
5.当你修改网页的默认字体时;(这个影响是非常严重的,不建议当它所有的页面都渲染完的时候去改变默认字体,这样做会导致一些性能问题的,或者是大家能看到的那种闪的情况)
面试官要问你什么是重排,你要把重排的这个概念说出来,他一般情况下会追问什么情况下会触发Reflow,这五条中随便说出两条都可以,不一定要把这五条都记住,都记住更好,但至少记住两条,至少让面试官知道你是知道Reflow这个概念和也知道怎么会发生Reflow,当然有的面试官会比较聪明,会问你什么情况会避免触发Reflow,这个也是一个点,总之考察的都是触发Reflow的条件
重绘Repaint
定义:
当各种盒子的位置、大小以及其他属性,例如颜色、字体大小等都确定下来后,浏览器于是便把这些元素都按照各自的特性绘制了一遍,于是页面的内容出现了,这个过程称之为Repaint。
【页面要呈现的内容统统画在屏幕上,这个就叫Repaint】
触发Repaint:
主要是判断现在呈现的内容有没有发生变化
1.DOM改动;
2.CSS改动;
面试官会问:如何尽量减少Repaint的频率/如何最大程度的降低Repaint
页面必定会发生Repaint,否则就是个静态页面了。比如说,页面中有一个计算结果,通过用户输入最后把结果展示出来,再把他输入的内容隐藏掉(这里有两个交互,第一个是让用户输入,第二个是输入完后把输入隐藏掉把结果显示出来,呈现的内容肯定不一样,发生Repaint),尽量少地Repaint:不要一个一个节点添加到浏览器上去,先创建一个document.fragment片段,把这些东西都放到这个片段中,在浏览器中一次添加这个片段,只Repaint一次,不然的话,加一个节点Repaint一次,这就是不行的。
布局Layout(浏览器的Layout)(这部分视频中没有了,是网上找的)
当渲染对象被创建并添加到树中,它们并没有位置和大小,计算这些值的过程称为layout或reflow。
Html使用基于流的布局模型,意味着大部分时间,可以以单一的途径进行几何计算。流中靠后的元素并不会影响前面元素的几何特性,所以布局可以在文档中从右向左、自上而下的进行。也存在一些例外,比如html tables。
坐标系统相对于根frame,使用top和left坐标。
布局是一个递归的过程,由根渲染对象开始,它对应html文档元素,布局继续递归的通过一些或所有的frame层级,为每个需要几何信息的渲染对象进行计算。
根渲染对象的位置是0,0,它的大小是viewport-浏览器窗口的可见部分。
所有的渲染对象都有一个layout或reflow方法,每个渲染对象调用需要布局的children的layout方法。
Dirty bit系统
为了不因为每个小变化都全部重新布局,浏览器使用一个dirty bit系统,一个渲染对象发生了变化或是被添加了,就标记它及它的children为dirty——需要layout。存在两个标识——dirty及children are dirty,children are dirty说明即使这个渲染对象可能没问题,但它至少有一个child需要layout。
全局和增量layout
当layout在整棵渲染树触发时,称为全局layout,这可能在下面这些情况下发生:
1.一个全局的样式改变影响所有的渲染对象,比如字号的改变。
2.窗口resize。
layout也可以是增量的,这样只有标志为dirty的渲染对象会重新布局(也将导致一些额外的布局)。增量layout会在渲染对象dirty时异步触发,例如,当网络接收到新的内容并添加到Dom树后,新的渲染对象会添加到渲染树中。
异步和同步layout
增量layout的过程是异步的,Firefox为增量layout生成了reflow队列,以及一个调度执行这些批处理命令。WebKit也有一个计时器用来执行增量layout-遍历树,为dirty状态的渲染对象重新布局。
另外,当脚本请求样式信息时,例如“offsetHeight”,会同步的触发增量布局。
全局的layout一般都是同步触发。
有些时候,layout会被作为一个初始layout之后的回调,比如滑动条的滑动。
优化
当一个layout因为resize或是渲染位置改变(并不是大小改变)而触发时,渲染对象的大小将会从缓存中读取,而不会重新计算。
一般情况下,如果只有子树发生改变,则layout并不从根开始。这种情况发生在,变化发生在元素自身并且不影响它周围元素,例如,将文本插入文本域(否则,每次击键都将触发从根开始的重排)。
layout过程
layout一般有下面这几个部分:
1.parent渲染对象决定它的宽度
2.parent渲染对象读取chilidren,并:
a. 放置child渲染对象(设置它的x和y)
b. 在需要时(它们当前为dirty或是处于全局layout或者其他原因)调用child渲染对象的layout,这将计算child的高度
c. parent渲染对象使用child渲染对象的累积高度,以及margin和padding的高度来设置自己的高度-这将被parent渲染对象的parent使用
d. 将dirty标识设置为false
Firefox使用一个“state”对象(nsHTMLReflowState)做为参数去布局(firefox称为reflow),state包含parent的宽度及其他内容。
Firefox布局的输出是一个“metrics”对象(nsHTMLReflowMetrics)。它包括渲染对象计算出的高度。
宽度计算
渲染对象的宽度使用容器的宽度、渲染对象样式中的宽度及margin、border进行计算。例如,下面这个div的宽度:
<div />
webkit中宽度的计算过程是(RenderBox类的calcWidth方法):
- 容器的宽度是容器的可用宽度和0中的最大值,这里的可用宽度为:contentWidth=clientWidth()-paddingLeft()-paddingRight(),clientWidth和clientHeight代表一个对象内部的不包括border和滑动条的大小
- 元素的宽度指样式属性width的值,它可以通过计算容器的百分比得到一个绝对值
- 加上水平方向上的border和padding
到这里是最佳宽度的计算过程,现在计算宽度的最大值和最小值,如果最佳宽度大于最大宽度则使用最大宽度,如果小于最小宽度则使用最小宽度。最后缓存这个值,当需要layout但宽度未改变时使用。
Line breaking
当一个渲染对象在布局过程中需要折行时,则暂停并告诉它的parent它需要折行,parent将创建额外的渲染对象并调用它们的layout。
以上是关于二三面_渲染机制类的主要内容,如果未能解决你的问题,请参考以下文章