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