作者:韩小窝
本文会对web页面的全链路进行完整的讲解并针对每一步找到能做的性能优化点,本文的目标是极致的性能优化。
性能优化不单指优化一个页面的打开速度,在开发环境将一个项目的启动时间缩短使开发体验更好也属于性能优化,大文件上传时为其添加分片上传、断点续传也属于性能优化。在项目开发以及用户使用的过程中,能够让任何一个链路快一点,都可以被叫做性能优化。
本文会对web页面的全链路进行完整的讲解并针对每一步找到能做的性能优化点,本文的目标是极致的性能优化。
因为针对性能优化,能做的点会特别特别的多,覆盖着整个互联网的访问流程,因此此文章的内容会比较多且杂,笔者会尽量对内容进行分类讲解。
本文的大致流程为先讲理论知识,比如如何评价一个页面的性能好与不好、如果获取性能指标,如何使用各种性能相关工具,浏览器如何获取并渲染页面。笔者认为这些都是基础,只有了解了这些基础才能开始考虑如何去优化。
接下来我们会进入性能优化环节,在这个环节我会详细讲解在页面的整个流程中,哪些地方可以做哪些优化。
目录
1.用户输入
2.卸载原页面并重定向到新页面
3.处理ServiceWorker
4.网络请求
5.服务端响应
6.浏览器渲染详细流程
进程与线程
输入url到页面展示完整过程
浏览器处理每一帧的流程
ChromePerformance(性能)
ChromePerformance工具的使用
PerformanceAPI介绍
使用PerformanceAPI获取性能相关指标
Coverage(覆盖率)
Lighthouse
Network(网络)
网络请求中的Timing(时间)
网络请求的优先级
网页总资源信息
Network配置
网络优化策略
减少HTTP请求数
使用HTTP缓存
使用HTTP/2.0
避免重定向
使用dns-prefetch
使用域名分片
CDN
压缩
使用contenthash
合理使用preload、prefetch
浏览器渲染优化策略
关键渲染路径
强制同步布局问题
如何减少重排与重绘
静态文件优化策略
图片格式
图片优化
HTML优化
CSS优化
JS优化
字体优化
浏览器储存优化策略
Cookie
LocalStorage
SessionStorage
IndexDB
其他优化策略
使用PWA提高用户体验
浏览器渲染原理
我们需要知道浏览器是如何渲染一个页面的,我们才能知道如何对页面进行性能优化,所以这里我们对一些基础知识进行讲解
进程与线程
浏览器有多种进程,其中最主要的5种进程如下
浏览器进程负责界面展示、用户交互、子进程管理、提供存储等
渲染进程每个页面都有一个单独的渲染进程,用于渲染页面,包含webworker线程
网络进程主要处理网络资源加载(HTML、CSS、JS、IMAGE、AJAX等)
GPU进程3D绘制,提高性能
插件进程chrome插件,每个插件占用一个进程
输入url到页面展示完整过程
图1
1.用户输入
用户在浏览器进程输入并按下回车健后,浏览器判断用户输入的url是否为正确的url,如果不是,则使用默认的搜索引擎将该关键字拼接成url。
2.卸载原页面并重定向到新页面
然后浏览器会将现有页面卸载掉并重定向到用户新输入的url页面,也就是图中和流程。
此时浏览器会准备一个渲染进程用于渲染即将到来的页面,和一个网络进程用于发送网络请求。
3.处理ServiceWorker
如果当前页面注册了ServiceWorker那么它可以拦截当前网站所有的请求,进行判断是否需要向远程发送网络请求。也就是图中与步骤
如果不需要发送网络请求,则取本地文件。如果需要则进行下一步。
4.网络请求
OSI网络七层模型:物理层、数据链路层、网络层、传输层、会话层、表示层、应用层
在实际应用中物理层、数据链路层被统称为物理层,会话层、表示层、应用层被统称为应用层,所以实际使用时通常分为4个层级
也就是图中、、、、步骤
图2
浏览器会拿着url通过网络进程进行如下步骤
HTTP/0.9没有请求头和响应头,不区分传输的内容类型,因为当时只传输HTML。
HTTP/1.0提供了请求头和响应头,可以传输不同类型的内容数据。根据请求响应头的不同来处理不同的资源,HTTP1.0每次发完请求都会断开TCP连接。有新的请求时再次创建TCP连接。
HTTP/1.1默认开启了keep-alive,它能够让一个TCP连接中传输多个HTTP请求,也叫链路复用。但一个TCP连接同一时间只能发送一个HTTP请求,为了不阻塞多个请求,Chrome允许创建6个TCP连接,所以在HTTP/1.1中,最多能够同时发送6个网络请求
HTTP/2.0多路复用:hpack
HTTP/3.0使用UDP实现,在UDP上一层加入一层QUIC协议,解决了TCP协议中的队头阻塞问题。
根据url查询本地是否已经有强制缓存,如果有则判断缓存是否过期,如果没过期则直接返回缓存内容,也就是图1中步骤
如果没有强制缓存或者缓存已过期,则将该请求加入队列进行排队准备发送网络请求,也就是图2中,然后进入DNS解析阶段,也就是图1中以及图2中的,DNS根据域名解析出对应的IP地址。(DNS基于UDP)。
然后使用IP寻址找到对方,然后根据IP地址+端口号创建一个TCP连接(三次握手),也就是图1中以及图2中的创建完成后利用TCP连接来传输数据。(TCP会将数据拆分为多个数据包,进行有序传输,如果丢包会重发,TCP的特点是可靠、有序)
判断当前协议是否为