金色小芝麻

vuePress-theme-reco 金色小芝麻    2021 - 2023
金色小芝麻 金色小芝麻

Choose mode

  • dark
  • auto
  • light
主页
分类
  • JavaScript
  • BUG复盘
  • SVG笔记
  • TypeScript
  • 个人总结
  • CSS笔记
  • 开发工具
  • 前端入门
  • Vue2.0
  • 性能优化
  • 架构学习
  • 每日一题
标签
时间轴
社交
  • 掘金 (opens new window)
author-avatar

金色小芝麻

83

文章

27

标签

主页
分类
  • JavaScript
  • BUG复盘
  • SVG笔记
  • TypeScript
  • 个人总结
  • CSS笔记
  • 开发工具
  • 前端入门
  • Vue2.0
  • 性能优化
  • 架构学习
  • 每日一题
标签
时间轴
社交
  • 掘金 (opens new window)
  • 前端入门

    • 博客搭建过程及相关配置
    • 数组中的16种常用方法
    • JS中的数据类型简析——基本数据类型值
    • JS中的数据类型object基础
    • JS中三种常见的判断
    • 数据类型之间的区别(堆内存Heap VS 栈内存Stack)
    • JS基础练习题及解析
    • 开关灯的小案例
    • JS中数据类型检测方法——typeof
    • 条件判断几个小练习
    • JS循环——for循环
    • 自定义属性实现选项卡小案例
    • 字符串中的12种常用方法
    • DOM操作的简单原理
    • JS实现隔行变色鼠标跟随小案例
    • JS中function的基础知识
    • JS中数组去重的三种方法
    • JS中时间格式化的三种方法
    • JS中URL参数处理的三种方法
    • JS小案例——获取随机验证码
    • DOM操作之——获取DOM标签的9种方式
    • DOM操作之——DOM节点类型及属性
    • DOM操作之——元素的增删改、样式修改、插入内容
    • JS中THIS相关问题梳理
    • JS中的变量提升机制
    • 在全局:私有上下文中:带VAR和不带VAR的区别
    • 作用域和作用域链查找机制
    • JS中堆栈内存的释放问题
    • JS中的闭包机制
    • ES3和ES6定义变量的区别
    • JS中的单例和工厂设计模式
    • JS中的面向对象OOP理论基础
    • 构造函数创建自定义类
    • JS中的原型和原型链
    • Math中常用的9种方法
    • 从一道阿里经典面试题剖析函数三种角色
    • 重写内置call
    • 重写一个内置new
    • 浏览器渲染页面的主体流程
    • 减少DOM的回流和重绘
    • JS中的多种继承方式
    • JS中数据类型检测四种方式的优缺点
    • JS中的正则表达式&&全面梳理
    • 非严格模式 🆚 严格模式的区别
    • 数组方法reduce、filter、flat
    • 获取数组中最大值/最小值的三种基础方法
    • 轮播图——渐隐渐显版
    • 深克隆 VS 浅克隆|深比较 VS 浅比较|回调函数
    • 轮播图——左右切换版
    • 事件及事件绑定、事件对象及事件传播
    • 从在地址栏输入网址到看到页面的过程&&AJAX基础
    • 想自学JS吗?想提升JS底层原理吗?76张脑图带你彻底搞懂原生JS
    • 面试手写API系列
    • 30张脑图带你从零开始学VUE
    • JS中的盒子模型
    • 初识JS-基础中的基础
    • 前端发展简史
    • JS中的三大类输出方式

浏览器渲染页面的主体流程

vuePress-theme-reco 金色小芝麻    2021 - 2023

浏览器渲染页面的主体流程

金色小芝麻 2020-06-11

当我们在浏览器输入网址后;浏览器都会做哪些事情才会让我们看见页面呢?

  • 首先在客户端浏览器输入网址:https://www.baidu.com
  • 客户端浏览器向服务器发送请求 HTTP REQUEST(省略很多细节步骤)
  • 服务器端存储着百度官网项目的原代码
  • 服务器收到请求后:服务器端把指定文中的代码返回给客户端 HTTP RESPONSE

# 一、进程/线程

一个进程中,会包含零到多个线程

# 1、进程 process

  • 电脑端安装很多的应用软件,每当运行一个应用程序,都相当于开辟了一个进程
  • 而对于浏览器来说,每新建一个页卡访问一个页面,都是新开辟一个进程

# 2、线程 thread

  • 每一个进程当中可能还会同时做多件事情,如果同时做多件事情,则会开辟多个线程

# 二、浏览器常用线程

浏览器是“多线程”的,但是JS渲染或者页面渲染是“单线程”的

  • GUI 渲染线程
    • 渲染和绘制页面
  • JS 引擎线程
    • 运行和渲染JS代码
  • 事件管控和触发线程
  • 定时器管控和触发线程
  • 异步 HTTP 请求线程
  • ......

# 三、同步/异步

# 1、同步编程

  • 单线程
  • 一次只能处理一件事情,当前这件事情处理完,才能继续处理下一件事情

# 2、异步编程

  • 同时可以进行好几件事情(一般是基于多线程并发完成的)
  • JS 中的异步编程,有自己一些特殊的处理方式
    • 队列 Queue
    • 事件循环 EventLoop

例题:

let n = 10;
setTimeout(() => {
    n++;
    console.log(n);
}, 0);
console.log(n);
for (let i = 0; i < 99999999; i++) {}
console.log(n);

按步解析:

  • 1、JS 是单线程的,所以在 “栈” 中,代码一定是按照顺序,自上而下依次执行的

  • 2、代码执行过程中如果遇到一个异步的操作代码:

    • 定时器(设置定时器的操作是同步的(立即设置),异步指的是间隔多久后执行指定的函数)
    • 事件绑定(监听)
    • AJAX的异步请求
    • PROMISE/ASYNC/AWAIT
    • ......
  • 事件对列 EventQueue

    • 3、当遇到定时器之后:浏览器默认开辟一个 事件队列 EventQueue
    • 4、JS 代码执行过程中遇到的异步操作,都先放置到事件队列中
      • 本题是把:(间隔浏览器最小反应事件内,执行对应的箭头函数),放到事件队列中
      • 浏览器会单独开辟一个定时器线程:监听事件队列中存储的各个定时器的到达时间
      • 只有 GUI 线程空闲下来,才会过来找
  • 5、此时 GUI 渲染线程继续向下执行代码:输出 10

  • 6、遇到循环:循环是同步的,代码中遇到死循环,会中断整个页面的循环或者中断代码的执行

  • 7、继续执行同步代码:输出10

  • 事件循环 EventLoop

    • 8、栈内存中的同步任务代码都执行完了:
      • 去事件队列中找到达时间的任务
      • 把找到的已经到达执行条件的任务,放入到栈中执行(每次只拿回来一个)
      • 还是 GUI 线程执行他
    • 9、等 GUI 执行完,“闲下来”,在去事件队列中找其他到达时间的任务......一直到事件队列被执行完为止

    这个循环查找的过程就是 EventLoop 事件循环

# 3、三种 CSS 样式的渲染区别

GUI 渲染页面时,当遇到其他请求时的两种处理方法:

  • 让 GUI 线程自己去拿:
    • 在CSS文件没有从服务器加载回来之前,下面的代码不会继续渲染
  • 在开辟一个线程,专门去服务器加载CSS文件:
    • 不用管CSS是否加载回来,GUI线程继续向下渲染

# -1).在渲染过程中遇到 <link> 引入式样式 : 异步操作

  • 浏览器会新开辟一个 HTTP 的请求线程,专门去服务器加载 CSS 样式内容
  • 此时 GUI 线程还可以继续向下渲染(不用管 CSS 是否回来)

# -2).如果遇到的是 @import 导入式样式 : 同步操作

  • 不会开辟新的线程去加载 CSS ,而是当前线程去加载
  • 这样只要 CSS 没有加载回来,下面的代码都不会继续渲染(阻碍页面渲染)

<link>和 @import 相比较: link 会提高页面渲染速度

# -3).内嵌式

上面虽然说link会提高页面渲染速度 ,但是当 CSS 代码较少的情况下,我们最好采用内嵌式(把CSS 和 HTML 写在一起),这样只要把 HTML 加载回来,CSS 也回来了

任何形式的HTTP请求都一定会有时间和性能的消耗

  • 前提是CSS代码少;
  • 代码多的情况下,如果还是和HTML放在一起,那么第一次请求HTML的速度都会变慢,也就得不偿失了;

# 四、浏览器渲染页面的步骤

# 1、生成 DOM 树

渲染了所有的 HTML 标签

  • 转换
    • 通过 HTTP 返还的首先是十六进制的编码字节数据
    • 拿到字节数据后,浏览器会通过内部的机制,把数据转换成我们能看到的代码
  • 令牌
    • 按照 W3C 规范(第五代版本的规范H5)的规则,转换成我们能看懂的标签
  • 词法分析
    • 通过转换后的标签,进行词法解析,生成DOM节点
  • DOM构建
    • 最后通过查找每个DOM节点之间的关系,生成DOM树

图片来源:图片摘自网络,如有侵权,联系删除

# 2、生成 CSSOM 树

请求回来 CSS 后,渲染完 CSS

同生成DOM树一样的过程生成CSSOM树

图片来源:图片摘自网络,如有侵权,联系删除

# 3、DOM 树 + CSSOM 树 => RENDER-TREE(渲染树)

图片来源:图片摘自网络,如有侵权,联系删除

# 4、 布局(Layout)或 重排/回流(reflow)

按照 RENDER-TREE 在设备的视口中进行结构和位置的相关计算=>布局(Layout)或 重排/回流(reflow)

# 5、绘制(painting)或 栅格化(rasterizing)

根据渲染树以及回流得到的几何信息,得到节点的绝对像素=>绘制(painting)或 栅格化(rasterizing)

# 思维导图

欢迎来到 金色小芝麻
看板娘