性能问题呈现给用户的感受往往就是简单而直接的:加载资源缓慢、运行过程卡顿或响应交互延迟等。而在前端工程师的眼中,从域名解析、TCP建立连接到HTTP的请求与响应,以及从资源请求、文件解析到关键渲染路径等,每一个环节都有可能因为设计不当、考虑不周、运行出错而产生性能不佳的体验。
我们以一道常见的前端面试题目:从浏览器地址栏输入URL后,到页面渲染出来,整个过程都发生了什么?来引入这个话题。
整个过程分为下面这几个阶段:
- 浏览器接收到URL,到网络请求线程的开启。
- 一个完整的HTTP请求并发出。
- 服务器接收到请求并转到具体的处理后台。
- 前后台之间的HTTP交互和涉及的缓存机制。
- 浏览器接收到数据包后的关键渲染路径。
- JS引擎的解析过程。
网络请求线程开启
浏览器接收到输入的URL到开启网络请求线程。这个阶段是在浏览器内部完成的。
首先对URL解析,URL的各部分含义如下表所示:
URL结构:Protocol://Host:Port/Path?Query#Fragment
| 标识 | 名称 | 备注 |
|---|---|---|
| Protocol | 协议头 | 说明浏览器如何处理要打开ide文件,如http,https,ftp等 |
| Host | 主机域名/IP地址 | 所访问资源在互联网上的地址,主机域名经过DNS解析成IP地址 |
| Port | 端口号 | 请求程序与响应程序之间连接的标识 |
| Path | 目录路径 | 请求目录或文件名 |
| Query | 查询参数 | 请求所传递的参数 |
| Fragment | 片段 | 次级资源信息,通常作为前端路由或锚点注意该资源不会被发送到后端 |
解析URL后,如果是http协议,则浏览器会新建一个网络请求线程去下载所需的资源,要明白这个过程需要先了解进程和线程之间的区别,以及目前主流的多进程结构。
进程与线程
简单来说,进程就是一个程序运行的实例,操作系统会为进程创建独立的内存,用来存放运行所需的代码和数据;而线程是进程的组成部分,每个进程至少有一个主线程及可能的若干子线程,这些线程由所属的进程进行启动和管理。由于多个线程可以共享操作系统为其所属的同一个进程所分配的资源,所以多线程的并行处理能有效提高程序的运行效率。
进程、线程和所执行任务之间的关系,如下图所示,从中可以总结4个特点

- 只要某个线程执行错误,将会导致整个进程崩溃。
- 进程与进程之间相互隔离。这保证了当一个进程挂起或崩溃的情况发生时,不会影响其他进程的正常运行,虽然每个进程只能访问系统分配给自己的资源,但可以通过IPC机制进行进程间通信。
- 线程之间共享所属进程的数据。
- 进程所占用的资源会在其关闭后由操作系统回收。即使进程中存在某个线程产生的内存泄露,当进程退出时,相关的内存资源也会被回收。
单进程浏览器
说到底浏览器只是一个运行在操作系统上的程序,那么它的运行单位就是进程,而早在2008年Google发布Chrome多进程浏览器之前,几乎所有浏览器都是单进程,它们将所有功能都运行在同一个进程中,其架构示意图如下所示:

单进程浏览器在以下方面有着较为明显的隐患。
- 流畅性:首先是页面内存泄露,浏览器内核通常非常复杂,单进程浏览器打开再关闭一个页面的操作,通常会有一些内存不能完全回收,这样随着使用时间延长,占用的内存会越来越多,从而引起浏览器运行变慢;其次由于很多模块运行在同一个线程中,如JS引擎、页面渲染以及插件等,那么执行某个循环任务的模块就会阻塞其他模块的任务执行,这样难免会有卡顿现象产生。
- 安全性:由于插件的存在,不免有些恶意脚本会利用浏览器漏洞获取系统级别权限。
- 稳定性:由于所有模块都运行在同一个进程中,对于稍复杂的js代码,如果页面渲染引擎崩溃,就会导致整个浏览器崩溃。
多进程浏览器

- 浏览器主进程:一个浏览器只有一个主线程,负责如菜单栏、标题栏等界面显示,文件访问,前进后退,以及子进程管理等。
- GPU进程:最初是为了实现3D的CSS效果引入的,后来就成了标配。
- 插件进程:主进程会为每个加入浏览器的插件开辟独立的子进程,由于进程间分配的运行资源相对独立,所以即便某个插件进行意外崩溃,也不至于对浏览器和页面造成影响。另外,插件进程采取了沙箱模式:不能获取系统权限。
- 渲染进程:也称浏览器内核,其默认会为每个标签窗口页开辟一个独立的进程,负责将html,css和
前端性能剖析:从URL输入到页面渲染的全过程

本文详细解析了从用户输入URL到页面渲染的前端性能过程,包括网络请求、多进程浏览器架构、HTTP协议、关键渲染路径、浏览器缓存等关键环节,强调了性能优化的重要性,特别是首屏加载和交互性能的影响。
最低0.47元/天 解锁文章
1376

被折叠的 条评论
为什么被折叠?



