浏览器链路
- performance 查看整体耗时;
- performance.getEntries()可以查看所有资源的消耗时间;
- performance.getEntriesByType(type);
- performance.getEntriesByName(name, type);
5.performance.timing
浏览器结构
(1)用户界面
(2)浏览器引擎
(3)渲染引擎
chrome解析js的引擎为V8
,在safari中为JS core
;
内联JS会阻塞其下的html标签解析,虽然不会阻塞其上的标签解析,但是会阻塞其渲染成可见图形
外联JS也会阻塞html标签解析和渲染,不一样的地方在于html解析到外联的script标签时会停止解析,浏览器优先渲染一次,再去下载JS文件,下载的过程会阻塞解析和渲染
async 和defer 属性则会并行下载JS文件,下载过程不阻塞解析和渲染,不同的是async 下载完毕后会立即执行,其阻塞行为与内联JS一致,而defer 则是在html标签解析完以后才执行里面的代码
CSS不会阻塞html标签解析,但是会阻塞其下的内联JS执行;故CSS下面还有内联JS的时候同样会阻塞html的渲染,其下没有JS时则不会阻塞渲染
JS需要将调用栈清空,并且将任务队列中的微任务取出到调用栈执行完毕,然后才会渲染图形;之后再从任务队列中取出宏任务执行;任务队列中同时有宏任务和微任务时,会优先执行微任务;dom事件则是触发时就立即将回调函数放入调用栈中执行
在浏览器的宿主环境中暴露了两个重要的api,requestAnimationFrame
和requestIdleCallback
;requestAnimationFrame在下一帧之前执行,它接受一个函数作为参数;requestIdleCallback则是在浏览器空闲时间执行,它同样接受一个函数作为参数,在这个函数中可以使用IdleDeadline
来得到空闲时间;如果一秒刷新60次,那么每帧时间为16.6ms,每帧执行完1~6后剩余时间即为空闲时间,有空余时间了才会执行requestIdleCallback;此时下一帧需要在requestIdleCallback执行结束才能继续渲染,如果requestIdleCallback长时间未将控制权交还给浏览器,则会影响下一帧的渲染,导致页面出现卡顿和事件响应不及时。
【1】接受输入事件
【2】执行事件回调
【3】开始一帧
【4】执行 RAF (RequestAnimationFrame)
【5】页面布局,样式计算
【6】绘制渲染
【7】执行 RIC (RequestIdelCallback)
渲染树生成后进行布局,布局是针对渲染树,计算其各个元素的大小、位置等布局信息;然后将窗口大小的数据交给GPU进行绘制,将渲染完毕的数据(像素点)保存在显存中,之后进行展示;
(4)网络
(5)xml解析器
(6)显示后端
(7)数据持久层
chrome浏览器的架构
browser
:控制程序的 chrome 部分;
renderer
: 负责显示网站的选项卡内的所有内容;chrome属于多进程浏览器,打开一个域名的时候就会生成一个渲染进程,当一个页面崩溃的时候,只会崩溃同一域名下的资源,其他渲染进程不会崩溃;
plugin
:控制网站使用的所有插件,例如flash;
GPU
:负责渲染到显示器上,独立的进程;
(GPU只能进行浮点运算,CPU既能进行浮点运算又能进行整数运算);
V8内存与垃圾回收机制
V8中的内存分为新生代
和老生代
,新生代中为存活时间较短的对象;老生代中为存活时间较长的对象,比如全局window、Dom、Web API等对象;
主垃圾回收器-Major GC主要负责老生代垃圾回收;
副垃圾回收器-Minor GC主要负责新生代垃圾回收;
三色标记法
黑色表示内存节点被GC Root引用到了,白色表示还没有被访问到,如果本轮遍历结束时还是白色,则该内存会被收回;
当执行例如window.a = value写操作后,v8会插入写屏障代码,将value的内存标记为灰色,然后GC扫描时,将value内存标记为黑色,原来window.a的内存地址标记为白色;
node观察者
idle观察者
例如:process.nextTick()
效率最高,消耗资源小,但会阻塞CPU的后续调用;
IO观察者
例如:setTimeout()
精确度不高,可能有延迟执行的情况发生,且因为动用了红黑树,消耗资源大;
check观察者
例如:setImmediate()
消耗的资源小,也不会造成阻塞,但效率也是最低
执行顺序:idle观察者 > Promise.then > IO观察者 > check观察者