SlideShare a Scribd company logo
Inside the Browser 
浏览器渲染原理 
张立理 
otakustay@gmail.com
WHY? 
HTML布局无处不在已经不局限与浏览器
Summary 
 浏览器的工作过程 
 资源下载 
 HTML解析 
 CSS计算 
 布局 
 渲染 
 浏览器对细节的具体优化手段 
 Firefox 
 Webkit / Chrome
How?
下载 
一个HTTP库能够搞定? 
 DNSClient 
 WebRequest 
 NetworkStream 
 HTMLParser 
 够了吗? 
不仅仅一个文件! 
 <script src… 
 <link href… 
 <img src… 
 <iframe src… 
 何时开始下载它们?
下载 
 <head>中的<script>和<link> 
 服务器端Response.Flush() 
 <body>中的<script> 
 document.write 
 new Image().src = … 
 defer VS async
下载 
 资源优先级 
 link[rel=stylesheet] / script 
 object / img / iframe 
 link[rel=prefetch] 
 脚本依赖 
 下载阻塞VS 执行阻塞 
 并行度 
 服务器压力VS 客户端效率 
http://www.otakustay.com/browser-strategy-loading-external-resource/
下载 
 Socket重用 
 Connection: keep-alive 
 Content-Length 
 Transfer-Encoding: chucked 
 正确性保证 
 Content-MD5 
 断点续传 
 Accept-Range 
 Content-Range
下载 
 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
下载 
 缓存年龄计算 
 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;
下载 
 缓存过期计算 
 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 – 要求浏览器向服务器请求全新内容
下载 
 输入– 资源URI 
 输出– HTML字符流 
 HTTP的超链接特性注定资源之间有关联的依赖 
 外部资源位置、类型不同影响下载时机 
 Response.Flush对下载的影响 
 缓存机制复杂但完善
解析 
• Token List 
• Normalized 
Token List 
•DOM Tree 
Demo
解析 
 只有这些? document.write
解析 
 输入– HTML字符流 
 输出– DOM Tree 
 HTML无法用自顶向下或自底向上的方法解析 
 过程– 序列化-> 转义处理-> 标签匹配 
 脚本执行会增加解析的回溯 
 DOM操作回溯至标签匹配过程 
 document.write回溯至序列化过程
CSS计算 
 元素– 匹配样式 
 div>div>div>div>div…>div { color: red; } 
 dom.parentNode istanceof HTMLDivElement && 
div.parentNode.parentNode instanceof HTMLDivElement && 
div.parentNode.parentNode.parentNode instanceof … 
 问题 
 DOM很大,对内存造成压力 
 每个元素生成一个StyleObject浪费内存 
 查找元素匹配的样式消耗时间和CPU 
 如果是div div div div … div呢?
CSS计算 
 Webkit – 特定条件下样式共享 
 鼠标状态(:hover / down / clicked)相同 
 没有id 
 标签名相同 
 class名称相同 
 attribute均相同 
 链接状态(:link / :visited)相同 
 聚焦状态(:active / :focus)相同 
 不能匹配属性选择器 
 没有内联样式 
 没有兄弟选择器(+ / :first-child / :last-child / …)
CSS计算 
 Firefox 
 Rule Tree + Style Context Tree 
Style sheets & 
rules 
Rule tree 
Style context 
tree 
DEMO 
https://developer.mozilla.org/en/Style_System_Overview
CSS计算 
 Map 
 { string: [ selector, selector, … ] } 
 以最右选择器为依据 
 匹配 
 查找id map 
 查找class map 
 查找tag map 
 确定selector完全匹配 
 遍历general map
CSS计算 
 #title { … } 
 p.error { … } 
 input[type=radio] { … } 
 #nav li~li a { … } 
 .fix-clear * { … } 
 <div class=“fix-clear”> 
<span id=“title” class=“error”>Erorr Occurred!</span> 
</div>
CSS计算 
 CSS层级(优先级) 
 来源层级 
 浏览器UA样式 
 用户样式 
 作者样式 
 作者样式+ !important 
 用户样式+ !important 
 样式层级 
 1,1,1,1算法 
 inline(0/1), count(id), count(attribute), count(tag) 
 ul#nav ol li.red
CSS计算 
DOM Tree 
document 
html 
head 
meta title 
body 
h1 p 
Render Tree 
html 
viewport 
scroll 
block 
body 
block 
h1 
block 
text 
p 
block 
text 
https://developer.mozilla.org/en/Mozilla_Style_System_Documentation
CSS计算 
 元素没有渲染对象 
 head / meta / script 
 元素有多个渲染对象 
 html / li 
 select / input[type=file] 
 通过CSS改变渲染对象 
 display: none 
 ::before / ::after
CSS计算 
 输入– DOM Tree 
 输出– Render Tree 
 目标– 内存优化、匹配效率优化 
 方法– 样式共享、选择器索引 
 DOM Tree !== Render Tree
布局 
 流布局 
 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
布局 
 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布局
布局 
 坐标系– 左上角为0,0点,右|下为正坐标 
 布局是递归过程 
 流布局可自左向右、自上而下进行,流中靠后的元素不会影响 
流中靠前的元素的布局(无回溯) 
 table布局需要回溯才能够完成(知道每一个单元格的大小,才 
能完成整个布局) 
 反对table布局的原因– 回溯对渲染的影响 
DEMO
布局 
 全局Reflow 
 整个Render Tree全部重新计算布局 
 全局布局样式变更– body { font-size: 12px; } / 添加新样式表 
 窗口大小变化 
 局部Reflow 
 仅标识为needLayout的渲染元素计算布局 
 Render Tree中插入新的渲染元素 
 渲染元素属性变化 
 Reflow会引起另一个Reflow – Reflow导致滚动条位置变化
布局 
 同步Reflow 
 全局Reflow通常同步进行 
 读取offsetWidth/offsetHeight等属性 
 异步Reflow 
 局部Reflow通常异步进行 
 FireFox:Reflow任务进入线程Queue,任务调度器负责执行 
 Webkit:定时器遍历Render Tree,布局所有needLayout对象 
 Reflow任务可合并,一次脚本执行过程中多个样式修改仅做一 
次Reflow,但是有阀值 
DEMO
布局 
 父元素确定自己的宽度 
 开始遍历子元素 
 指定子元素渲染器的x/y属性 
 判断子元素是否需要布局,调用layout函数 
 累计所有子元素的width/padding/border/margin,计算自己 
的宽度 
 同时考虑availWidth / sizing-box / min-width / max-width 
 将needLayout改为false
布局 
 文字布局 
 text-align: justified 
 white-space: nowrap / pre / pre-wrap 
 overflow: hidden / visible 
 换行计算 
 每行一个line-box负责渲染 
 当需要换行时,通知父元素,父元素创建新的line-box并重新布局 
 换行算法与文化相关 
 英文单词不能断开 
 中文标点不能在行首
布局 
 有流式布局和table布局2种 
 table布局需要回溯,流式布局通常不需要 
 Reflow的分类 
 触发类型上– 全局和局部 
 执行类型上– 同步和异步 
 布局过程递归进行 
 坐标系为左上角0,0点,右、下为正方向
渲染 
 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
渲染 
 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)] 
 完全不可见的元素不可被加到display list中 
 display: none; 
 opacity: 0;
渲染 
 Webkit – rectangle storage 
 Repaint前先将原有矩形内容保存为位图 
 计算重绘后的矩形内容的位图 
 比对2个位图,仅绘制差异部分 
 Chrome的Repaint在独立进程中 
 进程间通过事件进行传递和响应 
 绘制监听器负责监听重绘事件,把事件委托给Render Tree的根 
 Repaint永远从Render Tree的根开始,遍历并找到需要重绘的节 
点,对节点调用重绘(递归至叶子节点)

More Related Content

PPTX
Inside the-browser
PDF
编辑器设计Kissy editor
PPTX
ASP.Net MVC Framework
PPT
编辑器设计U editor
PDF
使用NodeJS构建静态资源管理系统
PDF
Berserk js
PPTX
深入淺出Node.JS
PPT
Node.js在淘宝的应用实践
Inside the-browser
编辑器设计Kissy editor
ASP.Net MVC Framework
编辑器设计U editor
使用NodeJS构建静态资源管理系统
Berserk js
深入淺出Node.JS
Node.js在淘宝的应用实践

What's hot (20)

PPTX
第三方内容开发最佳实践
PDF
百度前端性能监控与优化实践
PPTX
广告投放代码和创意代码持续优化
PDF
Kind editor设计思路
PPTX
Team Foundation Server
PPTX
淘宝开放产品前端实践
PPTX
ASP.Net WebAPI經驗分享
PPTX
Asp.net core v1.0
PDF
HTML 語法教學
PDF
用JAX-RS和Jersey完成RESTful Web Services
PDF
5.網站設計與前端框架
PDF
运维系统开发与Rails 3页面开发实践
PDF
CRUD 綜合運用
PPTX
Hbase简介与实践分享
PPTX
How to 系列 - Hosting a website
PDF
2016 Azure Bootcamp Taipei - Infrastructure as Code by Azure Resource Manager...
PDF
移动搜索在慢网速下的优化
PDF
Servlet & JSP 教學手冊第二版 - 第 9 章:整合資料庫
PDF
前端调试工具,编码相关,性能相关
PDF
Google LevelDB Study Discuss
第三方内容开发最佳实践
百度前端性能监控与优化实践
广告投放代码和创意代码持续优化
Kind editor设计思路
Team Foundation Server
淘宝开放产品前端实践
ASP.Net WebAPI經驗分享
Asp.net core v1.0
HTML 語法教學
用JAX-RS和Jersey完成RESTful Web Services
5.網站設計與前端框架
运维系统开发与Rails 3页面开发实践
CRUD 綜合運用
Hbase简介与实践分享
How to 系列 - Hosting a website
2016 Azure Bootcamp Taipei - Infrastructure as Code by Azure Resource Manager...
移动搜索在慢网速下的优化
Servlet & JSP 教學手冊第二版 - 第 9 章:整合資料庫
前端调试工具,编码相关,性能相关
Google LevelDB Study Discuss
Ad

Similar to Inside the browser (20)

PPTX
Inside the-browser
PPTX
reflow & repaint
PPTX
浅析浏览器解析和渲染
PDF
面向开发的前端性能优化
PPTX
浏览器工作原理浅析
PPTX
前端基础知识回顾
PPTX
Html5培训内容
PPT
Css性能优化
PDF
Reviews of Designing with Web Standards
PDF
郑焕义 重温网站重构
PDF
深入剖析浏览器
PDF
Html&css培训 舒克
PPTX
Script with engine
PDF
更好的文件组织
PPT
Html5和css3入门
PPTX
重构经验分享
PPTX
HTML5 介绍
 
PPTX
Rendering in browser
PPT
2010 01-07周五分享 前端的那些事儿-小米猪
PDF
Css schema by_sofish
Inside the-browser
reflow & repaint
浅析浏览器解析和渲染
面向开发的前端性能优化
浏览器工作原理浅析
前端基础知识回顾
Html5培训内容
Css性能优化
Reviews of Designing with Web Standards
郑焕义 重温网站重构
深入剖析浏览器
Html&css培训 舒克
Script with engine
更好的文件组织
Html5和css3入门
重构经验分享
HTML5 介绍
 
Rendering in browser
2010 01-07周五分享 前端的那些事儿-小米猪
Css schema by_sofish
Ad

Inside the browser

  • 1. Inside the Browser 浏览器渲染原理 张立理 otakustay@gmail.com
  • 3. Summary  浏览器的工作过程  资源下载  HTML解析  CSS计算  布局  渲染  浏览器对细节的具体优化手段  Firefox  Webkit / Chrome
  • 5. 下载 一个HTTP库能够搞定?  DNSClient  WebRequest  NetworkStream  HTMLParser  够了吗? 不仅仅一个文件!  <script src…  <link href…  <img src…  <iframe src…  何时开始下载它们?
  • 6. 下载  <head>中的<script>和<link>  服务器端Response.Flush()  <body>中的<script>  document.write  new Image().src = …  defer VS async
  • 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对下载的影响  缓存机制复杂但完善
  • 13. 解析 • Token List • Normalized Token List •DOM Tree Demo
  • 14. 解析  只有这些? document.write
  • 15. 解析  输入– HTML字符流  输出– DOM Tree  HTML无法用自顶向下或自底向上的方法解析  过程– 序列化-> 转义处理-> 标签匹配  脚本执行会增加解析的回溯  DOM操作回溯至标签匹配过程  document.write回溯至序列化过程
  • 16. CSS计算  元素– 匹配样式  div>div>div>div>div…>div { color: red; }  dom.parentNode istanceof HTMLDivElement && div.parentNode.parentNode instanceof HTMLDivElement && div.parentNode.parentNode.parentNode instanceof …  问题  DOM很大,对内存造成压力  每个元素生成一个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 Style sheets & rules Rule tree Style context tree DEMO https://developer.mozilla.org/en/Style_System_Overview
  • 19. CSS计算  Map  { string: [ selector, selector, … ] }  以最右选择器为依据  匹配  查找id map  查找class map  查找tag map  确定selector完全匹配  遍历general map
  • 20. CSS计算  #title { … }  p.error { … }  input[type=radio] { … }  #nav li~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#nav ol li.red
  • 22. CSS计算 DOM Tree document html head meta title body h1 p Render Tree html viewport scroll block body block h1 block text p block text 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
  • 24. CSS计算  输入– DOM Tree  输出– Render Tree  目标– 内存优化、匹配效率优化  方法– 样式共享、选择器索引  DOM Tree !== Render Tree
  • 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  整个Render Tree全部重新计算布局  全局布局样式变更– body { font-size: 12px; } / 添加新样式表  窗口大小变化  局部Reflow  仅标识为needLayout的渲染元素计算布局  Render Tree中插入新的渲染元素  渲染元素属性变化  Reflow会引起另一个Reflow – Reflow导致滚动条位置变化
  • 29. 布局  同步Reflow  全局Reflow通常同步进行  读取offsetWidth/offsetHeight等属性  异步Reflow  局部Reflow通常异步进行  FireFox:Reflow任务进入线程Queue,任务调度器负责执行  Webkit:定时器遍历Render Tree,布局所有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并重新布局  换行算法与文化相关  英文单词不能断开  中文标点不能在行首
  • 32. 布局  有流式布局和table布局2种  table布局需要回溯,流式布局通常不需要  Reflow的分类  触发类型上– 全局和局部  执行类型上– 同步和异步  布局过程递归进行  坐标系为左上角0,0点,右、下为正方向
  • 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)]  完全不可见的元素不可被加到display list中  display: none;  opacity: 0;
  • 35. 渲染  Webkit – rectangle storage  Repaint前先将原有矩形内容保存为位图  计算重绘后的矩形内容的位图  比对2个位图,仅绘制差异部分  Chrome的Repaint在独立进程中  进程间通过事件进行传递和响应  绘制监听器负责监听重绘事件,把事件委托给Render Tree的根  Repaint永远从Render Tree的根开始,遍历并找到需要重绘的节 点,对节点调用重绘(递归至叶子节点)

Editor's Notes

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