前端优化的一些了解

in Notes with 0 comment

从我接触web开发开始,就一直去了解和去尝试乃至去实现性能优化,一直都没有写过一篇文章好好梳理清楚这些,所以今天才有这一篇文章

首先性能优化是一个很大很大的话题,其中本篇文章要说的内容只是性能优化话题里的子话题 —— 前端性能优化。而前端性能优化又是一个很宽泛的概念

前端优化的最终目的都是提升用户体验,改善页面性能。违背这两点的都不算是前端优化。

本文将围绕什么是前端性能,怎么去了解和评价前端页面性能

前端性能

首先,从一条普通的公式开始···

$$ view = f(data) $$

view 是你看到的页面或执行某个页面动作,通过 f(data) 的函数得到

而前端性能可以理解为用户获取所需页面数据或执行某个页面动作的一个实时指标。如果用算法的时间复杂度概念去描述的话,f(data)的时间复杂度就是衡量页面性能的一个度。

再通过下面公式进一步理解

$$ views = n * view $$

一个完整的页面 views 是有许多固定数量的 view 来得到的,也即是说一个完整的页面是由许多个 f(data) 来共同决定的

再更进一步说

一个简单的view,对决定它的f(data)进行进一步分解的话,你会发现情况就变得更复杂了

总结下来,前端性能它有f(data)的深,也有 view 的广,几乎所有的指标也是围绕这两个基本点去做

而反映性能的指标一般都是用时间衡量,一般以用户希望获取数据的操作到用户实际获得数据的时间间隔来衡量

前端性能测试

获取和衡量一个页面的性能,主要可以通过以下几个方面:Performance Timing API 、Profile 工具、页面埋点计时、资源加载时序图分析等等。这里只做Performance Timing API的介绍。

Performance Timing API

什么是Performance Timing API ? 它是一个支持IE9以上版本以及webkit内核浏览器中用于记录页面加载和解析过程中关键时间点的机制,可以详细记录每个页面资源从开始加载到解析完成这一过程中具体操作发生的时间点,这样根据开始和结束时间戳就可以计算整个过程所花的时间

具体标准参考W3C,下图来自W3C

timing-overview.png

上图是 Performance Timing 资源加载和解析过程中记录各个关键点的示意图

从图中可以知道浏览器加载和解析一个HTML文件的详细过程先后经历 unload、redirect、App Cache、DNS、TCP、Request、Response、Processing、onload几个阶段。浏览器使用 performance.timing 来记录每个过程开始和结束的关键时间戳。这样我们就可以根据这个记录并通过简单的计算,即可得到页面中每个过程所消耗的时间

function performanceTest(){
  let timing = performance.timing,
      readyStart = timing.fetchStart - timing.navigationStart,
      redirectTime = timing.redirectEnd  - timing.redirectStart,
      appcacheTime = timing.domainLookupStart  - timing.fetchStart,
      unloadEventTime = timing.unloadEventEnd - timing.unloadEventStart,
      lookupDomainTime = timing.domainLookupEnd - timing.domainLookupStart,
      connectTime = timing.connectEnd - timing.connectStart,
      requestTime = timing.responseEnd - timing.requestStart,
      initDomTreeTime = timing.domInteractive - timing.responseEnd,
      domReadyTime = timing.domComplete - timing.domInteractive,
      loadTime = timing.loadEventEnd - timing.navigationStart;

  console.log('准备新页面时间耗时: ' + readyStart);
  console.log('redirect 重定向耗时: ' + redirectTime);
  console.log('Appcache 耗时: ' + appcacheTime);
  console.log('unload 前文档耗时: ' + unloadEventTime);
  console.log('DNS 查询耗时: ' + lookupDomainTime);
  console.log('TCP连接耗时: ' + connectTime);
  console.log('request请求耗时: ' + requestTime);
  console.log('请求完毕至DOM加载: ' + initDomTreeTime);
  console.log('解释dom树耗时: ' + domReadyTime);
  console.log('load事件耗时: ' + loadEventTime);
  console.log('从开始至load总耗时: ' + loadTime);
}

通过上面的时间戳计算,可以得到几个关键步骤所消耗的时间,对前端有意义的几个过程有:解析DOM树耗时,load事件耗时和整个过程耗时等

performance 还提供一些其他方面的功能,如下:

performance.memory //内存占用的具体数据
performance.now() //返回当前网页自 performance timing 到现在的时间,可以精确到微秒
performance.getEntries() //获取页面所有加载资源的 performance timing 情况
performance.navigation //提供用户行为信息,例如网络请求类型和重定向次数等等
performance.navigation.redirectCount //记录当前网页重定向跳转的次数

当然,还有很多要说要补充,留到下一篇再续~

内容不多,大概就这样~

Responses