1.首先明确打开页面发生了什么?
浏览器渲染页面大致分为以下几个步骤
(1)DNS解析
(2)TCP连接
(3)HTTP请求
(4)HTTP返回
(5)渲染
如上图所示,首先需要通过DNS(域名解析系统)将URL解析为对应的IP地址,然后与对应IP地址确定的服务器建立TCP网络连接,随后向服务端抛出 HTTP请求,服务端处理完请求之后把目标数据放在HTTP响应里返回给客户端,拿到响应数据的浏览器就可以开始走渲染的流程。渲染完毕,页面呈现给用户,并时刻等待响应用户的操作。本文针对HTTP请求、HTTP响应到页面渲染进行分析,针对DNS解析和TCP连接不做分析。
2.导致加载过慢的原因有哪些?
静态资源CSS、JS等体积过大;
HTTP请求数量过多;
首页列中图片体积大、没有进行压缩;
未使用HTTP缓存;
网络波动造成速度不稳定。HTTP优化有两大方向:
(1)减少请求次数;
(2)减少单次请求所花费的时间。
3.解决方案
1.HTTP优化有两大方向:
(1)减少请求次数;
(2)减少单次请求所花费的时间。
这两个优化方向在前端开发过程中对应的就是资源的压缩与合并:
(1)我们通过构建工具(webpack)对静态资源进行压缩与合并;
(2)同时项目中的静态文件我们也通过Gzip的方式来压缩,比如减少图片质量,减少图片体积;
(3)使用HTTP缓存
2.浏览器渲染层面优化
上面介绍完HTTP方向的优化方案,接下来我们进行浏览器渲染层面优化。首先我们了解浏览器内核可以分成两部分:渲染引擎和JS引擎。其中渲染引擎包括了HTML解释器、CSS解释器、布局、网络、存储、图形、音视频、图片解码器等零部件,我们针对如下述列表中每一个零部件来进行优化,以便让我们的页面在渲染过程中更快。
(1)HTML解释器:将HTML文档经过词法分析输出DOM树;
(2)CSS解释器:解析CSS文档, 生成样式规则;
(3)图层布局计算模块:布局计算每个对象的精确位置和大小;
(4)视图绘制模块:进行具体节点的图像绘制,将像素渲染到屏幕上;
(5)JavaScript引擎:编译执行JavaScript代码。
我们看一下浏览器渲染的整个流程:
基于上面的列表和流程我们来进行渲染层的优化:
(1)在HTML的优化中我们尽量减少DOM结构,减少层级,使HTML结构尽量简化。
(2)在CSS优化中避免使用通配符,只对需要用到的元素进行选择,并通过继承实现的属性,避免重复匹配重复定义,少用标签选择器,多用类选择器替代。
(3)同时优化阻塞资源的加载顺序,将CSS尽早下载到客户端,以缩短首次渲染时间。使用async、defer的方式进行JS文件的加载以防止阻塞。
(4)并且在操作DOM的过程中减少回流与重绘,将需要修改的部分缓存起来,修改完成一次渲染。
(5)使用lazy-load懒加载,初屏时只加载首屏中需要的静态资源和图片,其他资源实现异步加载。
(6)在首页中使用节流防抖,将scroll 事件、键盘事件等通过对事件对应的回调函数进行包裹,以自由变量的形式缓存时间信息。最后用setTimeout来控制事件的触发频率,通过闭包的形式实现节流防抖,以减少请求或者操作DOM。