页面加载过程详解和优化策略
前言
通过HTML5 Performanc相关的API,我们可以对页面进行性能分析。
下面会就几个比较重要的过程进行分析,给出耗时计算方法,并针对性的给出一些优化建议。
// 下文中的timing均表示performance.timing let timing = window.performance.timing;
DNS解析
域名系统(英文:Domain Name System,缩写:DNS)是互联网的一项服务。它作为将域名和IP地址相互映射的一个分布式数据库,能够使人更方便地访问互联网。
简单来说就是将一个域名映射到其对应的服务器IP地址,后续的请求均发送到该服务器。
DNS查询的基本过程如下:
- 查找浏览器缓存
浏览器会缓存DNS查询结果,不同的浏览器缓存时间会有所不同。如果浏览器存在缓存,那么DNS查询就到此为止。 - 查找系统缓存
浏览器缓存中没有需要的数据时,就会往上找到操作系统缓存。我们也可以手动配置host文件,这样浏览器会优先使用我们的配置。 - 查找路由器缓存
系统缓存中也没有需要的数据时,就会找到路由器。 - 查找运营商DNS缓存
之后会向运营的服务器(网络配置中的DNS服务器地址)请求DNS数据。 - 递归搜索
如果运营商服务器内也没有需要的数据时,就会开始消耗最大的递归搜索。
举个栗子m.taobao.com:
- 首先向根域名服务器请求顶级域com的IP地址;
- 获取返回值后,向顶级域com的服务器请求一级域名taobao的IP地址;
- 获取返回值后,向一级域名taobao的服务器请求二级域名m的IP地址;
- 获取返回值后,完成查找,返回m.taobao.com的IP地址;
根据网络的不同,这一块的耗时可能高达十几秒。
耗时计算:
let dns = timing.domainLookupEnd - timing.domainLookupStart;
明白工作原理后我们就可以针对域名解析这块做出一些优化,下面是一些优化建议:
- 考虑到域名解析是有时间消耗的,而且有可能消耗还不小,所以我们可以减少页面中使用到的域名数量,从而减少解析次数;
- 另外一个方法是进行DNS预解析,提前解析好的域名地址会被缓存在浏览器中,对其他页面也能起到加速的作用;
- HttpDNS,减少时延的同时还能防劫持;
建立连接
耗时计算:
let tcp = timing.connectEnd - timing.connectStart;
优化点如下:
- 避免重定向,这个不解释;
- 适当的合并请求,同上,减少握手次数;
- 长链接keep-alive,同上,减少握手次数;
发送请求
从发送请求到开始响应的过程。
耗时计算:
let req = timing.responseStart - timing.requestStart;
优化点如下:
- 避免重定向,还是不解释;
- 减少请求数据量,检查是否存在冗余的cookie;
- 使用CDN,缩短传输链路;
接收数据
从响应开始到数据传输完成的过程。
耗时计算:
let res = timing.responseEnd - timing.responseStart;
优化点如下:
- 减小html代码体积,包括去冗余以及代码压缩;
- 传输过程开启Gzip,进一步压缩传输数据量;
- 使用CDN,缩短传输链路;
解析DOM树
耗时计算:
let dom = timing.domInteractive - timing.domLoading;
优化点如下:
- 简化DOM结构,删除多余节点,避免深层嵌套;
- 同步的js会阻塞解析过程,考虑对js进行分段加载,延迟加载;
网页加载完成
下载并执行拥有defer属性的脚本。
耗时计算:
let dom = timing.domInteractive - timing.domLoading;
这一块的优化点主要集中在js代码层次的优化。然鹅,js的优化值得写本书来好好念叨念叨,so,这里就不展开了,主要给几个点吧:
- 减少需要加载的文件数,合并代码;
- 减小变量调用链路,多次访问到的对象成员保存成局部变量;
- 缓存函数运行结果;
- 算法优化,减少迭代次数,以及迭代的工作量;
- 缩短函数调用链;
DOM加载完成
DOM和CSSOM解析完成,并组合成为渲染树之后开始加载并执行defer
的脚本。
defer
的脚本执行完成就触发了DOMContentLoad
事件,同时进行的还有图片,css等,这些资源文件加载完成后才是domComplete
。
domComplete
之后就立刻触发load事件。
耗时计算
let domComplete = timing.domComplete - timing.domContentLoadedEventEnd;
这一块的优化主要集中在资源层次的优化,这也是一个比较大的项目,一样,挑几个点说一下:
- 使用css,iconfont,svg代替图片
- 根据屏幕分辨率进行适配
- 使用合适的图片格式,兼容的情况下,webp是个不错的选择
- 小图片使用data url代替
- 资源prefetch
- lazyload
此外,DOMContentLoaded事件耗时
和DOMLoad事件耗时
,主要就是执行js代码,优化建议参考网页加载完成
。
以上~