Inside the Browser<br />浏览器渲染原理<br />
WHY?<br />HTML布局无处不在<br />已经不局限与浏览器<br />
Summary<br />浏览器的工作过程<br />资源下载<br />HTML解析<br />CSS计算<br />布局<br />渲染<br />浏览器对细节的具体优化手段<br />Firefox<br />Webkit / Chrom...
How?<br />
下载<br />一个HTTP库能够搞定?<br />DNSClient<br />WebRequest<br />NetworkStream<br />HTMLParser<br />够了吗?<br />不仅仅一个文件!<br /><scrip...
下载<br /><head>中的<script>和<link><br />服务器端Response.Flush()<br /><body>中的<script><br />document.write<br />new Image().src =...
下载<br />资源优先级<br />link[rel=stylesheet] / script<br />object / img / iframe<br />link[rel=prefetch]<br />脚本依赖<br />下载阻塞 VS...
下载<br />Socket重用<br />Connection: keep-alive<br />Content-Length<br />Transfer-Encoding: chucked<br />正确性保证<br />Content-M...
下载<br />BS的精髓 – 缓存<br />验证型缓存<br />Last-Modified & If-Modified-Since / If-Unmodified-Since<br />ETag &If-Match / If-None-M...
下载<br />缓存年龄计算<br />age_value – Age响应头的值<br />date_value – Date响应头的值<br />request_time – 发起请求的本地时间<br />response_time – 收到...
下载<br />缓存过期计算<br />freshness_lifetime = <br />使用max-age时为max-age的秒数<br />使用Expires时为(Expires - Date)<br />response_is_fre...
下载<br />输入 – 资源URI<br />输出 –HTML字符流<br />HTTP的超链接特性注定资源之间有关联的依赖<br />外部资源位置、类型不同影响下载时机<br />Response.Flush对下载的影响<br />缓存机制...
解析<br />Demo<br />
解析<br />只有这些?<br />document.write<br />Tokenizer<br />Tree Construct<br />Script<br />DOM Tree<br />
解析<br />输入 – HTML字符流<br />输出 – DOM Tree<br />HTML无法用自顶向下或自底向上的方法解析<br />过程 – 序列化 -> 转义处理 -> 标签匹配<br />脚本执行会增加解析的回溯<br />DO...
CSS计算<br />元素 – 匹配样式<br />div>div>div>div>div…>div { color: red; }<br />dom.parentNodeistanceofHTMLDivElement && div.paren...
CSS计算<br />Webkit – 特定条件下样式共享<br />鼠标状态(:hover / down / clicked)相同<br />没有id<br />标签名相同<br />class名称相同<br />attribute均相同<b...
CSS计算<br />Firefox<br />Rule Tree + Style Context Tree<br />DEMO<br />https://developer.mozilla.org/en/Style_System_Overvi...
CSS计算<br />Map<br />{ string: [ selector, selector, … ] }<br />以最右选择器为依据<br />匹配<br />查找id map<br />查找class map<br />查找gen...
CSS计算<br />#title { … }<br />p.error { … }<br />input[type=radio] { … }<br />#navli~li a { … }<br />.fix-clear * { … }<br ...
CSS计算<br />CSS层级(优先级)<br />来源层级<br />浏览器UA样式<br />用户样式<br />作者样式<br />用户样式 + !important<br />作者样式 + !important<br />样式层级<b...
CSS计算<br />DOM Tree<br />Render Tree<br />https://developer.mozilla.org/en/Mozilla_Style_System_Documentation<br />
CSS计算<br />元素没有渲染对象<br />head / meta / script<br />元素有多个渲染对象<br />html / li<br />select / input[type=file]<br />通过CSS改变渲染对...
CSS计算<br />输入–DOMTree<br />输出 –Render Tree<br />目标– 内存优化、匹配效率优化<br />方法– 样式共享、选择器索引<br />DOM Tree !== Render Tree<br />
布局<br />流布局<br />display: inline / inline-block / block<br />float: left / right<br />clear: left / right / both<br />posi...
布局<br />table布局<br />display: table / inline-table / table-row-group / table-header-group / table-footer-group / table-row...
布局<br />坐标系 – 左上角为0,0点,右|下为正坐标<br />布局是递归过程<br />流布局可自左向右、自上而下进行,流中靠后的元素不会影响流中靠前的元素的布局(无回溯)<br />table布局需要回溯才能够完成(知道每一个单元格...
布局<br />全局Reflow<br />整个RenderTree全部重新计算布局<br />全局布局样式变更 – body { font-size: 12px; }/ 添加新样式表<br />窗口大小变化<br />局部Reflow<br ...
布局<br />同步Reflow<br />全局Reflow通常同步进行<br />读取offsetWidth/offsetHeight等属性<br />异步Reflow<br />局部Reflow通常异步进行<br />FireFox:Ref...
布局<br />父元素确定自己的宽度<br />开始遍历子元素<br />指定子元素渲染器的x/y属性<br />判断子元素是否需要布局,调用layout函数<br />累计所有子元素的width/padding/border/margin,计...
布局<br />文字布局<br />text-align: justified<br />white-space: nowrap/ pre / pre-wrap<br />overflow: hidden / visible<br />换行计算...
布局<br />有流式布局和table布局2种<br />table布局需要回溯,流式布局通常不需要<br />Reflow的分类<br />触发类型上 – 全局和局部<br />执行类型上 – 同步和异步<br />布局过程递归进行<br /...
渲染<br />transform / filter / z-index / color / visibility…<br />Reflow VS Repaint – display: none VS visibility: hidden<br...
渲染<br />Firefox – display list<br />找到Render Tree中在指定Repaint区域内的渲染对象<br />Render Tree的渲染对象经Stacking Order排序后生成<br />[backg...
渲染<br />Webkit– rectangle storage<br />Repaint前先将原有矩形内容保存为位图<br />计算重绘后的矩形内容的位图<br />比对2个位图,仅绘制差异部分<br />Chrome的Repaint在独立...
Upcoming SlideShare
Loading in...5
×

Inside the-browser

947
-1

Published on

Published in: Technology, News & Politics
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
947
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
8
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide
  • 因此,开发人员已经不局限与针对浏览器提供的功能进行编程,往往会涉及到对HTML / CSS /javascript容器的实现
  • 课程内容
  • 浏览器基本工作过程Q:是不是需要等整个HTML下载完成才能够开始解析?
  • 下载只是一个HTTP库的问题吗?
  • 影响下载的因素1、&lt;head&gt;中的内容会优先下载,Chrome对head中的内容串行下载,阻塞body中的内容2、Flush提供浏览器提前解析、渲染的机会,BigPipe的核心机制,Flush的本质是Transfer-Encoding: chucked3、IE6-7阻塞下载、解析、执行,其他浏览器并行下载、顺序执行4、DOM树的同步,以及IE的诡异BUG5、唯一不连接DOM树也可以发起请求的元素,响应的Content-Type非图片则只接收1个字节6、defer保证执行时机,async不保证defer在DOMTree构建完成之后,DOMContentLoaded事件触发之前
  • 下载优化方面其它细节举例
  • Q:max-age=0和no-cache有什么区别?
  • 总结
  • HTML解析的过程
  • 各种因素的影响,可能导致解析过程中要进行回溯Q:什么样的script会影响到Tokenizer
  • 总结
  • 正常思维下,匹配样式只需要写2层循环即可完成但是完成不代表可用,存在着种种问题
  • Q:一般来说怎么解决内存占用过大的问题
  • Firefox采取了更为复杂的解决方案,在CSS计算的过程中引入了2棵树
  • Q:一般来说,需要频繁查询的场合,如何优化查询的效率
  • Q1:将以上选择器对应到4个Map中Q2:红色部分的span元素的样式匹配过程该部分为“如何优化选择器匹配”,不要当作“如何写优化的选择器”的参考,写CSS永远以语义和结构为最优先,不要在意性能
  • Q:ul#navolli.red的CSS仅重是多少inline – 0id – 1attribute – 1tag – 3output – 0,1,1,3
  • DOM Tree和RenderTree的关系
  • Q:什么情况下出现该现象
  • 总结
  • list-item: generate a block box and a inline box for the list markerA run-in box behaves as follows:If the run-in box contains a block box, the run-in box becomes a block box.If a sibling block box (that does not float and is not absolutely positioned) follows the run-in box, the run-in box becomes the first inline box of the block box. A run-in cannot run in to a block that already starts with a run-in or that itself is a run-in.Otherwise, the run-in box becomes a block box.
  • 并不是用table标签才是table布局
  • 有人会说ol下的li前的数字标识,随着数字位数的增加,也会因为宽度增大影响布局用示例说明,li的marker-box是设定为普通的流式布局中的box,默认样式为overflow: hidden
  • Reflow在触发类型上的分类
  • Reflow在执行环境上的分类经常有人提到在遍历数组的时候要缓存length属性,个人是比较反感这种说法的,事实上缓存length属性对性能的影响微乎其微但是有一些属性,缓存与不缓存却能产生极大的性能差距,看一下offsetWidth属性缓存对性能的影响
  • 布局计算流程
  • 元素内部文字布局过程
  • 总结Q:style标签在head和body中的区别?
  • 影响渲染的CSS属性渲染的顺序
  • Firefox对渲染过程的优化
  • Webkit对渲染过程的优化Chrome的特殊性
  • Inside the-browser

    1. 1. Inside the Browser<br />浏览器渲染原理<br />
    2. 2. WHY?<br />HTML布局无处不在<br />已经不局限与浏览器<br />
    3. 3. Summary<br />浏览器的工作过程<br />资源下载<br />HTML解析<br />CSS计算<br />布局<br />渲染<br />浏览器对细节的具体优化手段<br />Firefox<br />Webkit / Chrome<br />
    4. 4. How?<br />
    5. 5. 下载<br />一个HTTP库能够搞定?<br />DNSClient<br />WebRequest<br />NetworkStream<br />HTMLParser<br />够了吗?<br />不仅仅一个文件!<br /><script src…<br /><link href…<br /><imgsrc…<br /><iframesrc…<br />何时开始下载它们?<br />
    6. 6. 下载<br /><head>中的<script>和<link><br />服务器端Response.Flush()<br /><body>中的<script><br />document.write<br />new Image().src = …<br />defer VS async<br />
    7. 7. 下载<br />资源优先级<br />link[rel=stylesheet] / script<br />object / img / iframe<br />link[rel=prefetch]<br />脚本依赖<br />下载阻塞 VS 执行阻塞<br />并行度<br />服务器压力 VS 客户端效率<br />http://www.otakustay.com/browser-strategy-loading-external-resource/<br />
    8. 8. 下载<br />Socket重用<br />Connection: keep-alive<br />Content-Length<br />Transfer-Encoding: chucked<br />正确性保证<br />Content-MD5<br />断点续传<br />Accept-Range<br />Content-Range<br />
    9. 9. 下载<br />BS的精髓 – 缓存<br />验证型缓存<br />Last-Modified & If-Modified-Since / If-Unmodified-Since<br />ETag &If-Match / If-None-Match<br />If-Range<br />非验证型缓存<br />Cache-Control<br />Expires<br />缓存失效<br />Vary/ Via / Date / Age<br />http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html<br />
    10. 10. 下载<br />缓存年龄计算<br />age_value – Age响应头的值<br />date_value – Date响应头的值<br />request_time – 发起请求的本地时间<br />response_time – 收到响应的本地时间<br />now – 当前本地时间<br />apparent_age = max(0, response_time - date_value);<br />corrected_received_age = max(apparent_age, age_value);<br />response_delay = response_time - request_time;<br />corrected_initial_age = corrected_received_age + response_delay;<br />resident_time = now - response_time;<br />current_age = corrected_initial_age + resident_time;<br />
    11. 11. 下载<br />缓存过期计算<br />freshness_lifetime = <br />使用max-age时为max-age的秒数<br />使用Expires时为(Expires - Date)<br />response_is_fresh= (freshness_lifetime > current_age)<br />max-age=0 VS no-cache<br />max-age=0 – 要求浏览器向服务器验证缓存<br />no-cache– 要求浏览器向服务器请求全新内容<br />
    12. 12. 下载<br />输入 – 资源URI<br />输出 –HTML字符流<br />HTTP的超链接特性注定资源之间有关联的依赖<br />外部资源位置、类型不同影响下载时机<br />Response.Flush对下载的影响<br />缓存机制复杂但完善<br />
    13. 13. 解析<br />Demo<br />
    14. 14. 解析<br />只有这些?<br />document.write<br />Tokenizer<br />Tree Construct<br />Script<br />DOM Tree<br />
    15. 15. 解析<br />输入 – HTML字符流<br />输出 – DOM Tree<br />HTML无法用自顶向下或自底向上的方法解析<br />过程 – 序列化 -> 转义处理 -> 标签匹配<br />脚本执行会增加解析的回溯<br />DOM操作回溯至标签匹配过程<br />document.write回溯至序列化过程<br />
    16. 16. CSS计算<br />元素 – 匹配样式<br />div>div>div>div>div…>div { color: red; }<br />dom.parentNodeistanceofHTMLDivElement && div.parentNode.parentNodeinstanceofHTMLDivElement && div.parentNode.parentNode.parentNodeinstanceof …<br />问题<br />样式表很大,对内存造成压力<br />每个元素生成一个StyleObject浪费内存<br />查找元素匹配的样式消耗时间和CPU<br />如果是div div div div … div呢?<br />
    17. 17. CSS计算<br />Webkit – 特定条件下样式共享<br />鼠标状态(:hover / down / clicked)相同<br />没有id<br />标签名相同<br />class名称相同<br />attribute均相同<br />链接状态(:link / :visited)相同<br />聚集状态(:active / :focus)相同<br />不能匹配属性选择器<br />没有内联样式<br />没有兄弟选择器(+ / :first-child / :last-child / …)<br />
    18. 18. CSS计算<br />Firefox<br />Rule Tree + Style Context Tree<br />DEMO<br />https://developer.mozilla.org/en/Style_System_Overview<br />
    19. 19. CSS计算<br />Map<br />{ string: [ selector, selector, … ] }<br />以最右选择器为依据<br />匹配<br />查找id map<br />查找class map<br />查找general map<br />确定selector完全匹配<br />遍历general map<br />
    20. 20. CSS计算<br />#title { … }<br />p.error { … }<br />input[type=radio] { … }<br />#navli~li a { … }<br />.fix-clear * { … }<br /><div class=“fix-clear”><span id=“title” class=“error”>Erorr Occurred!</span></div><br />
    21. 21. CSS计算<br />CSS层级(优先级)<br />来源层级<br />浏览器UA样式<br />用户样式<br />作者样式<br />用户样式 + !important<br />作者样式 + !important<br />样式层级<br />1,1,1,1算法<br />inline(0/1), count(id), count(attribute), count(tag)<br />ul#navolli.red<br />
    22. 22. CSS计算<br />DOM Tree<br />Render Tree<br />https://developer.mozilla.org/en/Mozilla_Style_System_Documentation<br />
    23. 23. CSS计算<br />元素没有渲染对象<br />head / meta / script<br />元素有多个渲染对象<br />html / li<br />select / input[type=file]<br />通过CSS改变渲染对象<br />display: none<br />::before / ::after<br />
    24. 24. CSS计算<br />输入–DOMTree<br />输出 –Render Tree<br />目标– 内存优化、匹配效率优化<br />方法– 样式共享、选择器索引<br />DOM Tree !== Render Tree<br />
    25. 25. 布局<br />流布局<br />display: inline / inline-block / block<br />float: left / right<br />clear: left / right / both<br />position: static / relative / absolute / fixed<br />HTML三条流<br />文档流、浮云流、定位流<br />其它因素<br />display: list-item<br />display: run-in<br />http://www.w3.org/TR/css3-box/#the-lsquo<br />
    26. 26. 布局<br />table布局<br />display: table / inline-table / table-row-group / table-header-group / table-footer-group / table-row / table-column-group / table-column / table-cell / table-caption<br />div VS table – 流布局 VS table布局<br />
    27. 27. 布局<br />坐标系 – 左上角为0,0点,右|下为正坐标<br />布局是递归过程<br />流布局可自左向右、自上而下进行,流中靠后的元素不会影响流中靠前的元素的布局(无回溯)<br />table布局需要回溯才能够完成(知道每一个单元格的大小,才能完成整个布局)<br />反对table布局的原因– 回溯对渲染的影响<br />DEMO<br />
    28. 28. 布局<br />全局Reflow<br />整个RenderTree全部重新计算布局<br />全局布局样式变更 – body { font-size: 12px; }/ 添加新样式表<br />窗口大小变化<br />局部Reflow<br />仅标识为needLayout的渲染元素计算布局<br />Render Tree中插入新的渲染元素<br />渲染元素属性变化<br />Reflow会引起另一个Reflow – Reflow导致滚动条位置变化<br />
    29. 29. 布局<br />同步Reflow<br />全局Reflow通常同步进行<br />读取offsetWidth/offsetHeight等属性<br />异步Reflow<br />局部Reflow通常异步进行<br />FireFox:Reflow任务进入线程Queue,任务调度器负责执行<br />Webkit:定时器定时遍历RenderTree,布局所有needLayout对象<br />Reflow任务可合并,一次脚本执行过程中多个样式修改仅做一次Reflow,但是有阀值<br />DEMO<br />
    30. 30. 布局<br />父元素确定自己的宽度<br />开始遍历子元素<br />指定子元素渲染器的x/y属性<br />判断子元素是否需要布局,调用layout函数<br />累计所有子元素的width/padding/border/margin,计算自己的宽度<br />同时考虑availWidth / sizing-box / min-width / max-width<br />将needLayout改为false<br />
    31. 31. 布局<br />文字布局<br />text-align: justified<br />white-space: nowrap/ pre / pre-wrap<br />overflow: hidden / visible<br />换行计算<br />每行一个line-box负责渲染<br />当需要换行时,通知父元素,父元素创建新的line-box并重新布局<br />换行算法与文化相关<br />英文单词不能断开<br />中文标点不能在行首<br />
    32. 32. 布局<br />有流式布局和table布局2种<br />table布局需要回溯,流式布局通常不需要<br />Reflow的分类<br />触发类型上 – 全局和局部<br />执行类型上 – 同步和异步<br />布局过程递归进行<br />坐标系为左上角0,0点,右、下为正方向<br />
    33. 33. 渲染<br />transform / filter / z-index / color / visibility…<br />Reflow VS Repaint – display: none VS visibility: hidden<br />渲染顺序(CSS2):<br />background color<br />background image<br />border<br />children<br />outline<br />http://www.w3.org/TR/CSS21/zindex.html<br />
    34. 34. 渲染<br />Firefox – display list<br />找到Render Tree中在指定Repaint区域内的渲染对象<br />Render Tree的渲染对象经Stacking Order排序后生成<br />[background(A), border(A), border(B), outline(A)]<br />避免多次遍历Render Tree<br />[background(A, B), border(A, B), outline(A, B)]<br />完全不可见的元素不可被加到displaylist中<br />display: none;<br />opacity: 0;<br />
    35. 35. 渲染<br />Webkit– rectangle storage<br />Repaint前先将原有矩形内容保存为位图<br />计算重绘后的矩形内容的位图<br />比对2个位图,仅绘制差异部分<br />Chrome的Repaint在独立进程中<br />进程间通过事件进行传递和响应<br />绘制监听器负责监听重绘事件,把事件委托给Render Tree的根<br />Repaint永远从Render Tree的根开始,遍历并找到需要重绘的节点,对节点调用重绘(递归至子节点)<br />
    1. A particular slide catching your eye?

      Clipping is a handy way to collect important slides you want to go back to later.

    ×