# vue **Repository Path**: robot114514/vue ## Basic Information - **Project Name**: vue - **Description**: vue阶段练习代码 - **Primary Language**: Unknown - **License**: MulanPSL-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2023-05-11 - **Last Updated**: 2023-06-05 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # day 01 ## 1.线程与进程 ​ 1.一个程序必须要有一个进程,进程之间相互独立 ​ 2.一个进程必须要有一个线程(即进程需要有线程支撑以确保应用正在执行才会分配内存) ​ 3.浏览器一般来说主要有以下三个进程:浏览器进程,网络进程,渲染进程(渲染进程默认开启渲染主线程,用于执行代码,由于代码均在一个线程中执行即单线程,则就有了异步操作的解决方案与事件循环) ## 2.消息循环(message loop) ​ 1.在浏览器底层并不存在事件循环,而是存在消息循环,即将所有的任务进行一个排序,按照先来后到的顺序依次 执行,但是这时如果遇到延时器之类的等待会阻塞进程的执行,因此这时就有了异步操作. ​ 2.在执行时根据浏览器源码可以看到,在执行任务的时候会默认开启一个死循环(无限循环),它会检测消息队列中 所有的任务并依次取出第一个执行,其它事件添加的排队任务则会默认到末尾. ## 3.异步 ​ 1.针对需要等待的任务,则执行的操作,它会将该任务交予其它进程执行执行等待,当达到某一条件后,则由其它线 程将回调函数封装为任务重新排到消息循环后面依次执行(即由任务生成的子任务需要重新排队) ​ 题目:如何理解js的异步 ​ 答:js是一个单线程语言,主线程只有一个,用来执行所有的html,css,js,如果不采用异步操作,在针对某些需要 等待的操作的时候就会造成线程阻塞,导致后面无法执行又或者无法对用户的交互作出反应,因此就有了异步操 作,在针对计时器,网络,事件监听等操作,会将该任务交予其它线程完成,其它线程在完成后再将传递回来的回调 函数包装成任务放在消息队列的末尾等待被重新执行 ​ js为什么会阻碍渲染 ​ 渲染本身属于一个绘制任务,在执行js同步代码的时候,文本本质上已经发生了改变,但是按照消息队列的排队,在 执行完文本更改后继续执行后续的js代码,而渲染则是执行完修改文本后重新发起的任务,会默认等当前所有的 同步js执行完毕后再重新循环执行渲染任务 ## 4.消息队列的优先级 ​ 1.根据w3c的标准,同一个类型任务需在一个队列,不同任务可以分属不同的队列,在事件循环中,浏览器可以根据 情况从不同的队列中取出不同的任务(浏览器之间会有差异),但一般来说默认为(微队列-交互队列-延时队列)即 默认用户交互的优先级更高,规定浏览器必须有一个微队列,微队列任务优先其它任务执行 ​ 题目:简述js的事件循环 ​ 事件循环本质是浏览器底层中默认开启的一个死循环,它会默认从消息队列中取出第一个任务执行,而其它新的 任务则会默认添加到队列末尾,在执行队列的时候会不止有宏队列和微队列,根据w3c官方的解释,每个任务根据 其不同的类型可以在不同的队列,但同类型的任务必须在同一个队列,且浏览器必须有一个微队列且执行优先级 最高 ​ 题目:js中计时器能做到精确计时吗?为什么 ​ 1.计算机本身没有原子钟,本身无法精确计时 ​ 2.各个操作系统的计时函数本身就有偏差 ​ 3.根据w3c标准,在执行计时器的时候如果嵌套超过五层则会默认时间最少为四毫秒而不是0 ​ 4.由于为单线程执行,受事件循环的影响,计时函数只能在主线程空闲时运行导致计时存在偏差 # day02 ## 浏览器渲染流程 ​ 浏览器渲染分为两个进程,一个是渲染主进程和合成进程,在网络进程获取到html的字符串后,渲染主进程会对整个html字符串进行解析在解析的时候,浏览器会同时产生一个预解析线程,该线程会提前对外部css文件进行解析,这时如果渲染主进程解析到对应的例如link标签则会跳过,等待预解析线程解析完后将结果传递回主线程解析,然后分别生成初步的dom树和som(cssom 即css object model)树(包含浏览器默认样式,内部样式,外部样式与行内样式等等) ​ 在得到dom与som后,主线程会遍历dom树,然后根据som的样式表合集进行计算,包括层级,更改,覆盖继承等等.在这个阶段的dom元素的所有样式都会计算出一个具体的值(未设置则为默认,但一定会有具体的值). ​ 对样式计算完成后则会遍历dom树,生成对应的布局树. ​ 生成布局树后则会将整个页面根据浏览器的策略进行分层(对基本不变的为一层,经常变化的为一层),提高效率,使某些经常发生变化的元素变化时不会使整个页面发生变化 ​ 最后主线程会根据整个分层的信息生成绘制指令并转到合成线程,渲染主线程进入等待或者休眠等待后续代码的执行 ​ 合成线程会拿到主线程给定对应的每一层的绘制指令,这时它会同时启动多个分块线程,将整个页面分成对应的小块(为后面的光栅化准备) ​ 在执行完分块后,合成线程会将分块信息交予浏览器的GPU进程进行光栅化,GPU会优先处理靠近视口的区域,并将每一块的像素点的位置等信息生成位图 ​ 最后,合成线程会根据光栅化生成的位图生成指引信息(指令),同时会针对transform(旋转缩放)指令进行稍微改变,然后交予浏览器GPU进程,然后浏览器GPU会再调用GPU硬件显示出对应的颜色 ### 解析HTML ​ 预解析线程会处理类似link标签的资源,并单独解析加载,但是例如js即src引入的资源相当于文件内部资源,会阻断浏览器的执行(js操作可能会针对已经生成的dom树进行操作),因此在引入css文件时使用link标签提高效率 ### 布局 ​ 布局树与dom树仅仅为类似,html语言仅提供的语义化标签,标签只有含义而没有实际样式,所有标签本质都是一样的,只不过浏览器的默认样式表设置了对应的默认样式例(p/div设置了display:block),使之成为了块级元素,因此,在生成dom树后,主线程会对dom的标签节点进行解析,根据不同的标签,生成不同的盒子(行盒,块盒(匿名))来存放对应的元素,包括针对伪元素这种dom树不存在的节点,都需要生成对应的盒子来存放 ### 分层 ​ 分层即浏览器根据自身策略对页面进行分层操作,改操作无法直接进行操作,但是滚动,transform,opacity等属性都能影响到浏览器的分层结果(分层较为消耗内存,应根据实际情况适当分层),也可以强行使用will-change属性对对应的元素进行操作(能较大程度影响分层结果),分层的好处是分层的部分发生变化不会影响其它层级(即:假如一个div单独分层出来,这时对这个div进行dom操作包括增加删除节点等不会造成整个页面的回流提高效率) ### 合成线程 ​ 在主线程执行完生成绘制指令后会交予合成线程进行,这时主线程就可以对后续的js代码或者其它操作进行执行,因此某些对页面的更改例如滚动条则仅仅是合成线程的操作,这时即使执行主线卡死,合成线程并不会造成影响,依旧可以执行某些效果 ### 为什么说浏览器现在很安全 ​ 在读取html页面后,主线程会将指令交予合成线程,而合成线程会将对应指令交予浏览器的GPU进程执行,即使浏览器插件出现问题影响的也只是浏览器的GPU进程而不是硬件的GPU进程 ### 什么是reflow(回流) ​ 回流则是js对dom进行操作,这时浏览器会重新对dom树进行更改,并会重新执行布局,分块等一系列操作,将整个页面重新布局排版 ​ 浏览器优化 :在对dom树进行操作的时候,为了避免对布局的反复计算,这时会将所有的dom操作进行合并,产生异步,异步作为异步任务进行排队,但是如果这时获取对应的dom元素的信息(同步操作)则无法获取到最新的信息,因此,浏览器会在获取dom属性信息的时候会先强制执行回流操作以确保能获取到最新信息 ### 什么是repaint(重绘) ​ 重绘则是对某些样式进行更改,该操作不会影响到布局,因此不会触发重新布局,但是会在主线程的最后一部分重新生成绘制指令并重新执行合成线程的操作(回流影响的是dom树结构并依次执行后面的步骤,因此回流一定引起重绘) ### 为什么transform的效率高 ​ transform阶段影响的是合成线程阶段的最后的绘画阶段,合成线程会根据对应的transform指令执行不同的公式对现有的位图进行变化并进行绘制,不会占用主线程,因此效率高(即使主线程卡死,也不会影响transform执行变化)