- 输入URL到显示页面的过程
- DNS
- 缓存机制
- 强缓存
- 协商缓存
- 页面渲染过程
- 回流 (Reflow) && 重绘 (Repaint)
- 浏览器的进程和线程
- 事件循环机制
- 前端优化
- 图片懒加载
- 虚拟列表
- 滚动懒加载
①浏览器使用DNS域名解析URL,确定协议,IP地址和端口号。
②浏览器与服务器建⽴TCP连接,三次握手,(HTTPS额外增加TSL握手),并发送HTTP请求。
③服务器接受请求,返回响应报文。
④浏览器根据状态码判断是否需要重定向,根据Location头部进行重定向。
⑤当需要发起多次HTTP请求时,浏览器建立多个TCP连接,过多的HTTP请求进入TCP队列。
⑥浏览器对响应进行解码,缓存可缓存资源,解析HTML⽂档,下载静态资源(根据状态码304判断缓存是否需要更新)。
⑦构造渲染树,执⾏js脚本,渲染页面。
⑧浏览器接受服务器的响应,根据Connection头部判断是否关闭TCP连接,四次挥手,或保持TCP连接。
①DNS服务提供域名到IP地址的解析服务。
②浏览器进行域名解析时,依次查询浏览器DNS缓存,本地Host文件,操作系统缓存。
③如果以上缓存都没有,浏览器便会发起一个DNS的系统调用,向DNS服务器发起解析请求(UDP)。
④依次查询路由器缓存,ISP的DNS服务器缓存(注意DNS劫持),再发起递归请求,从顶级域名逐层查询获取主机IP地址。
①Ctrl+F5强制刷新页面,缓存机制均无效,不允许使用任何缓存。
②F5刷新页面,跳过强缓存机制,协商缓正常使用。
①使用强缓存策略时,如果缓存资源有效,则直接使用缓存资源,不必再向服务器发起请求。
②强缓存由服务器的响应头里Cache-Control和Expires两个字段决定。
①使用协商缓存策略时,客户端会先向服务器发送一个请求,如果资源没有发生修改,则服务端返回一个304状态,让浏览器使用本地的缓存副本。如果资源发生了修改,则返回修改后的资源。
②协商缓存服务器的响应头里Last-Modified和Etag两个字段决定。
①浏览器同时进行.html文件的解析下载和页面的渲染。
②浏览器逐行解析.html文件,构建以docume为根节点的DOM树,解析过程中遇到外部静态资源就发送请求下载。
③浏览器下载.css,.js等资源后,优先解析CSS样式,构建CSSOM树。CSSOM树的构建会阻塞JS引擎的执行。
④浏览器在CSSOM树构建完毕后才执行JS脚本,JS的运行会阻塞.html文件的解析。
⑤结合CSSOM树和DOM树,构造Render树。Render树是用于显示,不可见的元素不会在这棵树中出现。Render树中计算了每个可见元素的位置和大小,浏览器通过Render树对页面进行布局和绘制。
⑥当.html文件解析完毕后,浏览器继续加载标记为defer的脚,整个解析过程结束触发DOMContentLoaded事件,并在async的脚本执行完之后触发load事件。
①当DOM元素的尺寸,位置,显示等发生布局变化时,浏览器会重构页面,触发回流。
②当DOM元素的颜色,风格发生变化时,浏览器会重绘该元素。
③回流必定会发生重绘,重绘不一定发生回流,回流的成本比重绘要大。
④增删移改DOM,绘制动画,修改样式,调整浏览器窗口,改变页面默认字体等,浏览器会马上进行回流。
⑤display:none;会触发回流,而visibility:hidden;只会触发重绘,因为没有发生位置变化。
⑥浏览器会优化重排布局的操作,将修改放入队列中,一定时间后再触发回流,这是异步回流。但是当访问offsetLeft,scrollLeft等属性时,会强制触发回流。
进程: 进程是CPU进行资源分配的基本单位。
线程: 线程是CPU调度的最小单位,是建立在进程的基础上运行的单位,共享进程的内存空间。
①浏览器包含:浏览器进程、第三方插件进程、GPU进程、浏览器渲染进程(浏览器内核)。
| 浏览器渲染进程中的线程 | |
|---|---|
| GUI渲染线程 | 1. 负责渲染浏览器界面HTML元素,当界面需要 重绘(Repaint) 或由于某种操作引发 回流(Reflow) 时,该线程就会执行。 2. GUI线程运行时会阻塞JavaScript引擎线程 |
| JavaScript引擎线程 | 1. 该线程是单线程,当该线程执行时,GUI线程会被挂起,GUI更新会被保存在一个队列中等到引擎线程空闲时立即被执行。 |
| 定时触发器线程 | 1. JS引擎计数的会因阻塞导致计时不准确。 2. 该线程在计时完成后会被添加到任务队列队尾,等待JS引擎的处理。 |
| 事件触发线程 | 1. 当一个事件被触发时,该线程会把事件添加到任务队列队尾,等待JS引擎的处理。 2. 这些事件可以是当前执行的代码块如定时器回调、也可来自浏览器内核的其他线程如鼠标点击、AJAX异步请求等。 |
| 异步HTTP请求线程 | 1. XMLHttpRequest在连接后,浏览器新开一个线程请求,将检测到状态变更时,异步线程就产生状态变更事件添加到任务队列队尾,等待JS引擎的处理。 |
①JavaScript引擎线程主线程在执行时,用调用栈记录函数执行的环境位置。
②主线程执行时产生的异步操作,其他线程触发的回调事件函数,会按顺序存入任务队列。
③当主线程的调用栈为空时,会从任务队列中选择一个可执行的回调函数放入调用栈,形成事件循环机制。
④微任务队列: 每一个宏任务执行完毕后,执行微任务,包括:process.nextTick,Promise,Object.observe,MutationObserver,V8垃圾回收机制,fetch API。执行微任务时创建的微任务会放到本轮队列末尾继续执行。
⑤宏任务队列: 浏览器最开始先执行宏任务,执行完后再执行所有微任务。等所有微任务执行完后,再执行下一个宏任务,包括:script,setTimeout,setInterval, setImmediate,requestAnimationFrame,I/O,UI rendering。
⑥在每轮微任务完成之后,页面进行重新渲染,再取下一个宏任务处理。
前端优化
| 模块 | 内容 | 模块 | 内容 |
|---|---|---|---|
| HTTP | 1. 减少前端HTTP请求。 2. 浏览器缓存相同的JS、CSS、图片。 3. 页面GZIP压缩。 4. 减小Cookie的大小。 | HTML | 1. 减少 |
| CSS | 1. CSS引入标签放页面顶部。 2. 使用CSS Sprites(雪碧图)。 3. 尽量使用类名选择器。 4. 动画元素开启定位或浮动,脱离文档流 | JavaScript | 1. JS脚本放页面底部。 2. 修改样式时,可以先把DOM克隆或隐藏,离线修改,再展示。 3. 节流和防抖 4. 不要一条一条的修改DOM样式,而是修改className或者修改style.cssText |
| 其他 | 1. 图片懒加载、预加载、图片base64。 2. 组件按需加载。 3. 虚拟滚动列表 |
①图片的加载是由src引起的,使用HTML5的自定义属性data-src属性来储存真实图片的路径,将src储存为正在加载图片。在需要加载图片的时候,将data-src中的值赋值给src,这样就实现了图片的按需加载,即懒加载。
②懒加载图片的条件:元素顶部距离文档顶部的高度 < 浏览器滚动的过的距离 + 浏览器视口的高度。



