1. 浏览器简介
最近读了一些关于前端性能方面的书,做了下总结,如有错误望各位大牛指出
浏览器组成
1. 浏览器主要组成部分包括:
- 浏览器引擎:负责窗口管理,Tab进程管理
- 渲染引擎:负责DOM解析,页面渲染等
- js引擎: js解释器,如chrome和nodejs采用的V8引擎
浏览器的进程和线程
1. 进程和线程
- 进程是CPU分配内存的最小单位
- 线程是CPU调度的最小单位
2. 浏览器的多进程的架构
现在浏览器都采用多进程架构,每次打开一个Tab页面,浏览器就会启动一个进程(注意: 现在浏览器有自己的优化机制,在打开多个tab后,chrome可能进行进程合并) 主要的进程包括三个
-
Browser进程(负责协调,主控)只有一个
- 负责界面显示,与用户交互,如前进,倒退
- 负责页面管理,如页面的创建和销毁
- 网络资源管理,下载等。
-
渲染进程(Renderer进程,内部是多线程)默认下每个Tab都有一个渲染进程,相互不影响。
- GUI渲染线程: 负责选择渲染浏览器界面,当页面需要重绘或由于操作引起的回流,次线程执行
- JavaScript引擎线程: 主要负责js脚本解析,执行等
- 时间触发线程: 用来控制浏览器的事件循环,当事件触发的时候,该线程会把事件添加到待处理队列的队尾,等待javascript引擎处理
- 定时器触发线程:setTimeOut和setInterval所在线程,w3c在HTML标准中规定,要求setTimeOut低于4ms。
- HTTP线程:在XMLHttpRequest连接后浏览器开起的线程
注意:GUI渲染线程和JS引擎线程是互斥的,如果js引擎执行,GUI线程会被挂起。
-
GPU进程:最多只有一个,用于3D绘制等。
3. 解析过程
- 当浏览器获取文档后,渲染引擎开始解析DOM,将文档转换成DOM树
- 解析外部CSS以及style元素中的样式,生CSSOM树。
- DOM树和CSSOM树组成渲染树,进行渲染
- 如果在渲染过程中,遇到JS脚本的执行和下载,会停止渲染,进行JS脚本的下载和JS脚本的执行。
4. 时间线
- 创建Domcument对象,解析HTML,将元素对象和文本内容添加到文档中。 此时的document.readyState='loading'
- 遇到link外部css的时候,异步加载css,继续解析html
- 遇到script标签,同步加载js,阻塞html解析,下载完成后立即执行,如果有多个js标签,按顺序加载执行
- 如果遇到async和defer的script标签,创建异步线程进行加载,继续解析html,如果死async加载完成后马上执行,如果是defer则在DomContentLoaded前执行(注意:defer一般会按照显示顺序执行,async不一定按显示顺序执行,先下载完先执行)
- 文档解析完成,document.readyState='interative'
- 此时执行带有defer的js,按顺序执行
- DOMContentLoaded触发,程序从脚本执行转换为事件驱动
- 当所有的script加载完成且成功执行,document.readyState='completed',触发onload事件
- 异步执行ui,开始交互。
web性能优化
网络请求优化
1. 经典性能优化
-
减少NDS查找
每次主机名解析都需要一次网络往返,从而增加请求延迟时间,同时还会阻塞后去请求。DNS查找流程:浏览器DNS缓存,本机DNS缓存,路由器DNS缓存,本地DNS服务器。浏览器在请求一个URL时,大概会分为阻挡,域名解析,建立连接,发送请求,等待响应,接受数据,断开连接
阻挡: 不同浏览器对单域名并发请求有一定的限制。如果浏览器对一个域名请求超过限制就会阻挡等待。所有可以把url请求分散处理。
域名解析:DNS与解析
<meta http-equiv="x-dns-prefetch-control" content="on">
<link rel="dns-prefetch" href="//domain.com">
-
减少HTTP重定向
HTTP重定向及其费时的,尤其在不同域名下的重定向,这里既有额外的DNS查询以及TCP握手,还有其他延迟
-
重用TCP连接
尽可能的重用TCP连接,以消除TCP握手时间以及慢启动延迟
-
使用CDN(内容分发网络)
把数据放到离用户更近的地理位置上,减少每次TCP连接的网络延迟。这一条即适合动态资源有适合静态资源。
-
在客户端缓存资源
应该缓存资源,从而避免每次每次请求都发生相同的内容
-
传输压缩过的内容
传输压缩过得内容,把要传输的字节压缩到最少
-
消除不必要的请求开销
减少请求的HTTP部首的数据(比如cookie),节省的时间想当于几次往返的延迟到时间
-
并行处理请求和响应
-
针对协议版本进行优化
HTTP 1.x 支持有限的的并行机制,要求打包资源,跨域分散资源,等等。相对而言HTTP2.0只要建立一个连接,就能实现最优性能,同时无需针对HTTP1.x的那些优化方法
1.1 客户端缓存资源
只要有可能,就要对资源只能一个明确的缓存时间,这样客户就可以直接使用本地的缓存资源,而不必发送HTTP请求(catch-control)。类似的指定验证机制,可以告诉浏览器资源是是否更新,如果没有更新则不必返回(eTag)。应该注意的是,两个应该同时指定。
- catch-control 首部用于指定缓存时间
- Last-modified/ 首部提供验证机制
1.2 压缩传输
HTML,js,css等文件经过GZIP压缩平均可以减少60%~80%。
1.3 消除不必要的气请求字节
主要的cookie过大的问题,一般浏览器将cookie的大小限制在4KB,但是所有的请求都会带上cookie,所以说这也是不小的开销。在HTTP1.x中,cookie在内的所有HTTP头都是在未压缩状态下传输,在2.0中这些元素是可以压缩。所以一般今天服务的域名和网站的域名是不相同。
1.4 并行处理请求
- 使用持久化连接,从HTTP1.0 升级到HTTP1.1
- 利用多个HTTP1.1 进行并行下载(在相同域名下,并行的数目根据浏览器不同,有不同的限制,一般是4~8个)
- 考虑升级HTTP2.0来提升性能
1.5 关于HTTP1.x的优化
- 采用域名区分,因为每个来源限制的并发数是有限制。采用不同的域名,可以提高并发的数目
- 打包资源,减少HTTP请求,拼接和精灵图有助于降低协议开销
- 嵌入小资源,直接在文档中嵌入小的资源,从而减少请求的数目