Chrome浏览器调试工具
devtools
里面的命令菜单:command+shift+P
命令菜单里面有许多非常有用好玩的东西
capture
可以在浏览器内截图的:
capture area screenshot
capture full size screenshot
这个是长截图,可以截取整个页面,这个真是宝藏capture node screenshot
截图node
节点
dock
dock to bottom
、dock to left
flex、grid
这是两种常见的布局方式,打开方式都是在父容器中打开display
,然后在水平方向和竖直方向使用justify-content
、align-item
来控制。
console API
$_
:可以返回上一条语句的结果
$0
:选择之前选择的DOM节点,输出到控制台
console.time()
、console.timeEnd()
:可以计算两个API之前代码的执行时间,并输出到控制台
控制台里换行:shift+return
console.group()
、console.groupEnd()
:两个方法之间的内容就是一个分组;
console.table([{},{}])
:传入一个数组,将数组内容以表格的形式展示出来;
LocalStorage
、SessionStorage
、Cookie
LocalStorage是一直储存在本地,直到人为删除;SessionStorage表示数据只维持在会话结束之后
浏览器渲染
首先说明,当今的浏览器属于一个多进程应用程序
,进程之间通过管道共享数据;每一个进程里面有多个线程,线程是直接共享内存数据
早期的浏览器。早期浏览器属于单进程应用程序
,会有页面线程(负责页面渲染)、JS线程(执行JS代码)、其他线程。但是有问题存在:
- 单进程显然不稳定。一个线程卡死,可能导致整个进程卡死,比如打开多个标签页,其中一个页面卡死,整个浏览器就会卡死。
- 单进程不安全。JS线程可以访问浏览器进程内的所有数据
- 单进程不流畅。一个进程要负责的事情太多了
现代多进程浏览器:主要分为浏览器进程、GPU进程、插件进程、渲染器进程、网络进程、缓存进程
- 渲染器进程会默认为每个标签页创建一个进程
- 插件进程会处理如
flash
插件这种进程
Chromium内核可以调整进程,比如使用single process
就会让渲染器进程和浏览器进程合为一个;process per site
就表示每个站点的多有页面使用一个进程;process per site instance
表示同一站点的不同页面使用不同进程
浏览器网络线程请求到数据,通过管道将数据传送到渲染器进程中的主线程,主线程将HTML解析成DOM树,然后进行CSS样式计算,根据DOM树和样式又得到layout tree
,根据layout tree
得到生成顺序表,然后又由layout tree
得到layer tree
,然后将绘制信息传给合成器线程,合成器线程将图层分成图块,然后将图块传给栅格线程,栅格线程进行栅格化,将栅格化好的draw quads图块信息
又传给合成器线程,合成器线程又将图块信息变成了合成器帧frame
,然后将合成器帧frame又传给了浏览器进程,再传给GPU渲染,就展示到屏幕上了。
DOM->Style->Layout->Paint->Layer->tiles->raster->draw quads->frame
重排:修改一次height属性,就会发生layout之后的所有动作
重绘:修改一次color属性,就会发生Paint之后的动作
我们狭义上指的渲染就是Layout
和Paint
两步
无论是重排还是重绘都会占用主线程,重排和重绘都会影响性能,尽量避免。重排会影响重绘,影响更大一些。
JS引擎
引擎其实也就是编译器了。JS常见的编译器有
+ Chrome的V8 NodeJS环境、Vue也使用这个
+ WebKit的JavaScriptCore
+ Mozila SpiderMonkey
+ QuickJS
+ Facebook Hermes
编译过程:
(JS)——解析器——(抽象语法树)——解释器——(字节码)——编译器——(机器码/汇编代码) // V8 5.9版本之前少了解释器这一步,只有parser和compiler
v8引擎
V8是C++编写。编译执行JS、处理调用栈、内存分配、垃圾回收
17年V8引擎添加了igniton
字节码解释器
5.9版本之前的V8
(JS)——解析器——(抽象语法树)——Full-codegen编译器——(机器码)——CrankShaft优化编译器——(机器码)