最近做首屏优化学到的一些知识点

相关名词解释

1.TTFB:
time for First Byte 首字节时间

2.FP:
First Paint 首次绘制

3.FCP:
First Contentful Paint 首次有内容的渲染

4.FMP:
First Meaningful Paint 首次有意义的绘制

5.TTI:
Time To interactive 可交互时间

6.Long tasks:
超过50ms的任务

7.SSR && CSR:
服务端渲染和客户端渲染

8.Isomorphic JS:
同构化

简单理解

  • FP: 仅有一个div根节点
  • FCP: 包含页面的基本框架,但没有数据内容
  • FMP: 包含页面所有元素及数据

先后顺序 如图

首屏渲染相关性能度量数据

FP、FCP、FMP、TTI可以用下面的图直观的表现出来

注意

  • FP: ”首次绘制“(First Paint)不包括默认背景绘制(例如浏览器默认的白色背景),但是包含非默认的背景绘制,与iframe。
  • FCP:”首次内容绘制“(First Contentful Paint)包含文本,图片(包含背景图),非白色canvas与SVG。
  • iframe:父级浏览上下文不应该知道子浏览上下文的绘制事件,反之亦然。这就意味着如果一个浏览上下文只包含一个iframe,那么将只有“首次绘制”,但没有“首次内容绘制”。

可以通过下面这行代码获得首屏渲染性能指标数据:

1
performance.getEntriesByType('paint')

通过这行代码可以得到一个列表。列表中包含一个或两个PerformancePaintTiming对象。这取决于“首次内容绘制”是否存在。如图2所示:

从图3可以看到PerformancePaintTiming对象包含四个属性,这四个属性的值为:

  • name: 如果是首次绘制则name为“first-paint”,如果是“首次内容绘制”则name为“first-contentful-paint”
  • entryType: “paint”
  • startTime: 绘制发生的时间,该时间是相对于time origin的
  • duration: 0

可以使用下面的代码注册一个绘制观察器:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 性能度量结果对象数组
const metrics = [];

if ('PerformanceLongTaskTiming' in window) {
const observer = new PerformanceObserver(list => {
for (const entry of list.getEntries()){
const metricName = entry.name;
const time = Math.round(entry.startTime + entry.duration);
metrics.push({
eventCategory: 'Performance Metrics',
eventAction: metricName,
eventValue: time,
nonInteraction: true,
})
}
})
observer.observe({ entryTypes: ['paint']});
}

几种常见web页面渲染方式对比

CSR客户端渲染

1.最近几年流行的SPA,web app都是CSR模式,页面只有一个空div
2.优点:
(1)不依赖数据
(2)FP时间最块;就是留了一个div挂载组件嘛
(3)客户端用户体验好
(4)内存数据共享
3.缺点
(1)SEO不友好
(2)FCP、FMP慢;要各种发请求嘛;

预渲染

使用puppeteer或者 rize.js 提前渲染一遍,另存起来;
这种方式太傻了,就不详细介绍了;
具体可以看他们的官方文档;

SSR和同构

1.服务端渲染,服务器把内容全都拼好直接输出
类似早些年的JSP,服务端用一套模板引擎
2.服务器和客户端使用一套代码就是同构
3.优点:
(1)SEO友好
(2)首屏性能高,FMP比CSR和预渲染都要快
4.缺点:
(1)客户端数据共享成本高
(2)模板维护成本高

总结如下图

最优的渲染方式

1.SSR和CSR共存的模式,发挥两者的优势
(1)刷新页面是SSR渲染,nodejs配合bigpipe
(2)站内点击是CSR,不用vue router、react router等等,直接用原生的a链接

补充知识点:Bigpipe

1.什么是bigpipe

  • 存在很久的一种技术
  • Facebook首创
  • 首屏快速加载的的异步加载页面方案
  • 前端性能优化的一个方向
  • 适合比较大型的,需要大量服务器运算的站点
  • 有效减少HTTP请求
  • 兼容多浏览器

2.能解决的问题

  • 下载阻塞
  • 服务器与浏览器算力浪费

3.与传统Ajax相比,优点

  • 减少HTTP请求数:多个模块更新合成一个请求
  • 请求数减少:多个chunk合成一个请求
  • 减少开发成本:前端无需多写JavaScript代码
  • 降低管理成本:模块更新由后端程序控制
  • URL优雅降级:页面链接使用真实地址
  • 代码一致性:页面加载不劢态刷新模块代码相同

一句话总结:分块加载技术

4.判断的标志
Response Headers中
Transfer-Encoding:chunked

5.koa-bigpipe
阿里巴巴狼叔写的koa包

最后,查阅资料中看到一个大佬说的话,
现在随便搜搜nodejs比较好的包,基本全都是两三年前的,侧面说明nodejs已经相对比较稳定了。而web端经过这几年野蛮生长,也逐渐能看出统一稳定的趋势。对我们来说实在是一件好事情!

参考文献:
2018你应该知道的web性能信息采集指南
科普Nodejs Bigpipe
HTTP协议中的Transfer-Encoding:chunked

同时欢迎关注我的个人微信公众号:

分享到:
Disqus 加载中...

如果长时间无法加载,请针对 disq.us | disquscdn.com | disqus.com 启用代理