浏览器八股

浏览器页面渲染过程

当点开一个网页时,浏览器会先接受到服务端的资源,然后经历下面几个步骤渲染页面

  • 首先解析HTML文档,构建起DOM树。在这个过程中,解析器遇到外链标签会把请求交给网络模块,浏览器网络层会并行加载脚本、样式表和图片,以此提高性能
  • 然后浏览器解析CSS,构建CSSOM树,这个树包含了所有CSS规则。
  • 将DOM树和CSSOM树结合起来,形成渲染树,渲染树包含了页面上每个元素的显示信息
  • 然后进行布局(回流),浏览器要计算出渲染树上每个元素的几何信息(位置大小等)
  • 再进行绘制(重绘),浏览器使用渲染树来绘制页面上的内容
  • 最后浏览器把所有页面的部分合成我们最终看到的像素
    性能优化:为了加快渲染速度,可以减少重绘和回流,延迟加载图片,使用CSS硬件加速等

进程和线程之间的区别

首先他们都是操作系统用来执行任务的基本单位,但有以下几点关键不同:

  • 进程是独立的运行环境,每个进程都有自己独立的内存空间。创建进程时,操作系统需要为其分配资源,所以进程的开销比较大,而线程共享进程的内存空间,所以开销较小
  • 进程之间相互独立,一个进程崩溃不会影响其他。而线程属于进程的一部分,同一进程下的线程可以共享数据,一个线程崩溃可能导致整个进程崩溃
  • 进程的上下文切换比线程慢,因为涉及整个内存空间的切换,而线程共享相同的内存空间,所以切换更快
  • 进程间通信(IPC)比较复杂,需要通过管道,信号,共享内存等方式。而线程间通信直接,因为共享内存空间
  • 进程是操作系统进行资源分配和调度的基本单位,而线程则由进程创建和调度
    线程更适合执行多个任务,而进程适合隔离运行的程序

JS是单线程还是多线程的

  • JavaScript运行在单线程的环境中,在浏览器或Node.js中,JS代码在一个线程上执行,也就是说一次只能执行一个操作。
  • 但是JS通过异步编程事件循环机制可以实现非阻塞的并发操作。虽然代码本身是按顺序执行的,但可以通过回调函数,Promises或async/await来处理异步任务,如网络请求或文件读写。
  • 此外,JS可以利用Web Workers[^1]来实现多线程。其可以允许你在后台线程上运行代码,这样可以执行一些复杂的计算任务而不阻塞主线程。
    [^1]: Web Worker 是浏览器给 JS 开的“后台线程”——多线程、不共享 DOM、纯消息通信;用来把重计算从主线程搬走,让页面保持 60 FPS
  • 所以虽然JS在主线程上是单线程的,但它有机制来处理并发,并且可以通过Web Workers实现多线程

浏览器渲染进程的线程有哪些

主进程管“外壳”,渲染进程管“网页”,GPU 管“合成”,网络进程管“下载”,扩展/工具进程跑“插件杂活”——多进程保稳定,站点隔离保安全
渲染进程有几个关键的线程:

  • 主线程(UI线程):1. 负责解析HTML,CSS,构建DOM数和CSSOM树,然后合并成渲染树。 2. 负责页面的布局(回流)和绘制(重绘)。3. 负责用户输入和页面交互
  • 工作线程(Worker线程):1. 执行JS脚本,避免阻塞主线程,提高页面的响应性。2. 可以是浏览器专门为复杂计算创建的线程,如Web Workers
  • 合成线程:1. 负责图层的合成,将不同的页面图层合并成最终的页面显示。2. 处理页面滚动,放大等操作
  • 网络线程:处理页面的网络请求,如HTTP请求的发送和接收
  • 定时器触发线程:负责定时器(如setTimeoutsetInterval)的计时和触发
  • 文件操作线程:异步处理文件的读写操作
    这些线程共同完成页面的加载,渲染和交互处理。主线程是渲染进程中最核心的线程,其他线程都是为减轻主线程的负担而存在。