移动互联网时代,用户对于网页的打开速度要求越来越高。首屏作为直面用户的第一屏,其重要性不言而喻。优化用户体验更是我们前端开发非常需要 focus 的东西之一。
一个快速响应的网站可以更好地留住用户,试想一下如果你打开一个网站,过了几十秒网站仍然没有加载完成,你是否还会有耐心去等待?
那这样的话该怎么去提升我们网站的打开速度呢?首先我们要知道打开网站的过程中究竟是什么地方比较耗时,才能更好地去优化,这一节我们主要分析加载网页的过程,也就是前端经典面试题——从输入URL到页面渲染经历了什么。
问题根源
从输入URL到页面渲染经历了什么?这个问题在前端面试中已经被问“烂了”,可能还有部分小伙伴不熟悉这个问题,我们今天就来回顾一下这个问题
- 输入网址
- DNS查询
- 建立TCP连接
- 浏览器向服务器发送HTTP请求
- 服务器处理请求
- 关闭TCP连接
- 浏览器解析资源
- 页面渲染
一个网页加载的过程大致就是这些,其中需要我们前端工作者去优化的部分已经加粗标注了,下面我们来说详细或一下这几个过程
DNS查询
这个过程其实就是根据域名查询主机地址的过程,主机的标识地址都是通过IP地址来区分的,但是这个IP对于常人来说很难记忆,于是就有了域名这个东西,一般来说域名都是跟网站内容相关的方便记忆的英文单词或者单词组合,但是我们要访问主机还是通过IP来访问,这个过程浏览器会自动帮助我们完成。
这个查询的过程大致如下:
- 首先浏览器解析输入的域名,先查找本地硬盘的host文件,看有没有和这个域名对应的ip,如果有,就直接使用这个ip。
- 如果没有,浏览器会发出一个DNS请求到本地DNS(域名分布系统)服务器.本地DNS服务器一般都是你的网络接入服务器商提供,比如中国电信,中国移动。
- 请求到达DNS服务器后,DNS服务器首先会查询他的缓存记录,如果有对应的ip地址,则返回,如果没有,本地DNS服务器向DNS根服务器发送查询请求。
- 根服务器不会记录具体的域名和ip的对应关系,而是返回域服务器的地址.本地服务器会继续向域服务器发起请求。
- 域服务器并没有记录域名和ip的对应关系,而是返回你的域名的解析服务器的地址.
- 本地DNS服务器继续向域名解析服务器发出请求,这时会收到域名对应的ip,本地DNS服务器将ip返回给浏览器,并将ip存入缓存,方便下次访问,加快访问速度。
其实这个过程的有话不需要我们自己动手,浏览器或者运行商已经通过缓存手段帮助我们完成了优化
HTTP请求
现在大多的网络请求都基于HTTP协议完成,他是一个基于TCP的应用层协议。
在 HTTP 请求阶段,最大的瓶颈点来源于请求阻塞。所谓请求阻塞,就是浏览器为保证访问速度,会默认对同一域下的资源保持一定的连接数,请求过多就会进行阻塞,一般是 6 个。所以减少HTTP请求或者使用**内容分发网络(CDN)**是优化方向。
其次,HTTP资源传输也需要消耗时间,时长和资源大小成正比,缩小资源体积也是一个优化方向。
再就是将不重要的且短时间不会改动的静态资源缓存下来也是一个方向
解析&渲染
最后一步发生在浏览器,浏览器将从服务器获取到的HTML、CSS、JS等文件进行解析然后渲染页面。
首先会并行解析HTML文档和CSS样式,分别生成产物DOM和CSSOM,然后将二者融合生成渲染树,最后绘制渲染树生成页面,这个过程中不会有JS脚本参与,只要有HTML和CSS就可以完成,但是遇到script
标签就会被阻塞,因为JS可以改变HTML和CSS,因此非必要情况下不要在过程中添加script
脚本,可以将script
标签放到文档内容的最后或者使用 defer 和 async,告诉浏览器在等待脚本下载期间不阻止解析过程。
页面渲染完成之后的界面布局如果发生了改变就会触发回流和重绘,回流的代价要高于重绘,当然这两个都不是善茬,尽量不要去招惹他们