image.png

这是在腾讯课堂白嫖 京程一灯 的视频直播课。课程网址如下: 面试必备:三步带你吃透浏览器原理,如果你对视频感兴趣可以联系客服1块钱购买。

《三步带你吃透浏览器原理》[ ] 书籍 [ ] 讲座 [x] 视频
作者 京程一灯 出版社
阅读日期 2020年2月 更新日期 2020年2月
相关链接 面试必备:三步带你吃透浏览器原理 备注 三节直播课

课程分三节:

  • 浏览器架构及原理
  • js执行机制及v8原理
  • 浏览器页面及安全知识要点

现在做个笔记如下。

1. 浏览器架构及原理

提到的一些零碎无关知识点:

  • webGL编程指南
  • for in of 元编程
  • 微任务 宏任务
  • 单进程
  • 协程 generator

语雀内容

1.1 前端网络

1.1.2 HTTP请求

输入网址发生了什么。这里也有其他文章更仔细完整。

  1. 构建请求,一般是 HTTP1.1
  2. 查找缓存,强缓存、协商缓存304
  3. 准备ip和端口:DNS
  4. 等待TCP连接。这里同一域名同时最多6个TCP连接
  5. 建立TCP连接。也就是三次握手
  6. 发送HTTP请求,HTTP的组成:请求行、请求头、请求体
  7. 服务器响应。响应行状态码、响应头、响应体
  8. 断开连接。或者keep-alive

常规流程。收获不大。

1.2 HTTP历史和未来

这里看https://www.yuque.com/xinbao37/high_performance/about-network-protocol

1.3 浏览器拿到了返回数据

https://www.yuque.com/xinbao37/high_performance/page-render

2 js执行机制及v8原理

学技术很孤独,剩者为王,靠坚持。
最好的是凭借兴趣。

2.1 js执行机制

理解执行上下文

2.1.1 变量提升

看这段代码:

  1. showName()
  2. console.log(myName)
  3. var myName = 'xx'
  4. function showName(){console.log('yy')}

执行之前会把 代码编程类似下面的样子

  1. var myname = undefined // var 提升
  2. function showName(){xxx} // function 提升
  3. showName()
  4. console.log(myname)
  5. myname = 'xxx'

可以这么想,但实际上不是这么做,位置是不会改变的。编译阶段会被引擎放入内存。

js源码 — 编译 — 执行。

虽然都提升,但function优先

请看下面这个变态的题目:

  1. debugger;
  2. alert(a)
  3. a()
  4. var a=3
  5. function a(){alert(10)}
  6. function a(){alert(20)}
  7. alert(a)
  8. a=6
  9. a()
  10. // function a(){alert(20)} -- 20 -- 3 -- Error a is not a function
  11. // 会变成这样:
  12. // function 优先级大于 var
  13. // 后面的大于前面的
  14. function a(){console.log(20)}
  15. alert(a)
  16. a()
  17. a=3
  18. alert(a)
  19. a=6
  20. a()

调用栈 call stack

标准的es6写法:全局执行上下文 包含了

变量环境 + 词法环境 + outer + this

在es5中,(尤其是你不知道的js第一版上册) 包含了 VO,vo激活的过程,ao等

  1. var a=2
  2. function add(b,c){return b+c}
  3. function addAll(b,c){
  4. var d =10
  5. var res = add(b,c)
  6. return a+res+d
  7. }
  8. addAll(3,6) // 3+6+2+10=21

解析过程:

变量环境:

  • a=undefined
  • add = function(){} // 其实应该放入堆,堆的地址
  • addAll = function(){}

调用栈 stack 先进后出

一步一步走,不断压栈。

块级作用域

  • 为了避开变量提升,兼容var,引入了 let const
  • 引入块级作用域,就有了词法环境。

作用域
程序中定义变量的区域,也决定这生命周期。
也就是变量和函数的可访问范围和生命周期。

es5时候只有 全局作用域函数作用域
变量提升带来的问题

  • 容易被覆盖掉
  • 本该销毁的变量没有销毁
    1. function foo(){
    2. for(var i=0;i<3;i++){} // 提升
    3. console.log(i)
    4. }
    5. foo()
    分析下面的代码执行:
    image.png
    注意 var c 会提升,let会放入词法作用域

image.png
找a时候是这样找

来一个变态的题目,在es5中严格模式会报错。

  1. let a=2
  2. console.log(a)
  3. {
  4. console.log(a)
  5. function a(){log1}
  6. }
  7. log(a)

bind 箭头函数没有原型 yield 协程

作用域链和闭包

每个执行上下文的变量环境中,都有一个外部引用,指向外部的执行上下文,这个外部引用称为 outer ,es5时候交 scope chian

闭包

原理是啥,是作用域链

  1. debugger;
  2. function foo(){
  3. var myName = 'xx'
  4. let test1 = 1
  5. const test2 = 2
  6. var innerBar = {
  7. getName:function(){
  8. debugger; // 控制台 local -- closure -- global
  9. console.log(test1)
  10. return myName
  11. },
  12. setName:function(v){
  13. myName=v
  14. }
  15. }
  16. return innerBar
  17. }
  18. var bar =foo()
  19. bar.setName('x')
  20. bar.getName()

this

动态执行。
image.png
这是es3版本。

栈空间和堆空间

原始数据类型是存在 栈空间 ,引用类型是存在 堆空间 的。

垃圾回收

编译器和解释器

源代码 — 词法分析 语法分析 — ast + 执行上下文 — 字节码 — 机器码

JIT 即时编译

字节码 — 是否有热点hot? — 没有热点就点火,有热点就涡轮增压Tubofan

消息对列和事件循环

EventLoop 底层是一个循环,引入了队列。
image.png

消息队列,先进先出:

  • 输入事件 鼠标滚动 点击 移动
  • 微任务
  • 文件读写
  • ws
  • js定时器等
  • js执行 解析DOM 样式计算 布局计算 css动画等

因此宏任务之间不光是js,也有渲染页面等。

每次宏任务中间,执行微任务。

宏任务

  • 渲染事件 如解析DOM 计算布局 绘制
  • 用户交互
  • js脚本执行
  • 网络请求 文件读写

微任务
主函数执行结束之后 — 微任务 — 宏任务结束之前。

3 浏览器页面及安全知识要点

  • google性能优化

进一步细化。

DOM树

DOM树如何生成,利用 HTML解析器。

有了响应头之后,会判断 content-type 是啥,如果是 text/html 就简单了。

  • 如果是 html 文件
  • 请求创建 渲染进程
  • 网络进程和渲染进程建立共享数据的通道,一边放,一边读取 送给html解析器,解析为DOM

这里维护了一个 token栈,startTag压栈,endTag出栈,通过一个栈结构,维护了DOM树

js如何影响DOM

抽离。

CSS如何影响

抽离。

CSS动画比js动画高效

一般是60Hz

image.png
paint处理完提交,交给合成线程

优化页面

  • 加载阶段
    • 减少关键资源个数,比如内联、defer
    • 降低关键资源大小
    • 降低关键资源的RTT次数,round-trip-time 一个往返的网络时间
    • cdn
  • 交互阶段
    • 减少js执行时间,分割,使用sw
    • 避免强制同步布局,尽量不要修改DOM时候查询一些值
    • 合理使用css合成动画
    • 尽量频繁的垃圾回收,临时变量等

浏览器安全

同源策略

XSS

攻击方式:

  • 存储式攻击。用户输入的地方写入script标签
  • 反射性攻击。恶意链接
  • 劫持,wifi 运营商劫持。

解决办法:

  • 转义
  • 浏览器,限制非让么,上报
  • cookie http only

CSRF

第三方获取登录态。

  • cookie sameSite
  • 验证referer
  • csrf toekn

HTTPS

SSL/TLS 安全层。

不是很理解剩下的。

传密钥使用非对称加密,安全。传输数据使用对称加密,速度。

  • 浏览器端:对称加密套件列表 + 加密套件列表 + client-random
  • 服务器端:非对称加密套件+加密套件+service-random+公钥
  • 保存公钥,生成随机数pre-master,然后利用公钥对pre-master加密,发送加密后
  • 服务器拿出私钥,揭密pre-master数据