关于前端渲染方式以及性能
前端性能指标和计算方法
本文主要介绍关于前端渲染模式,包括客户端渲染、服务端渲染、静态渲染、预渲染、同构渲染,还有同构渲染的另一种方式、三方同构渲染。
以下是浏览器加载的性能指标,也是整个加载和渲染过程中会触发的关键事件:
- FP(First Paint):首次绘制时间,也就是白屏,这个指标用于记录页面第一次绘制像素的时间,从页面开始加载到浏览器中检测到渲染(任何渲染)时被触发(例如背景改变,样式应用等)【计算方式:白屏时间 = firstPaint - pageStartTime】;
- FCP(First Contentful Paint):首次内容绘制时间,也是首屏,这个指标用于记录页面首次绘制文本、图片、非空白 Canvas 或 SVG 的时间,从页面开始加载到页面内容的任何部分呈现在屏幕上的时间【计算方式:首屏时间 = firstContentTime - pageStarTime】。
- FMP(First Meaningful Paint):首次有意义的渲染帧,也是首次有效绘制,从页面加载开始,到大部分或者主要内容已经在首屏上渲染的时间点, 表示页面的“主要内容” 开始出现在屏幕上的时间点,这项指标因页面逻辑而异,因此上不存在任何规范(只是记录了加载体验的最开始。如果页面显示的是启动图片或者loading 动画,这个时刻对用用户而言没有意义);
- LCP(Largest Contentful Paint):最大内容绘制时间,用于记录视窗内最大的元素绘制的时间,该时间会随着页面渲染变化而变化,因为页面中的最大元素在渲染过程中可能会发生改变,另外该指标会在用户第一次交互后停止记录,指标代表的是视窗最大可见图片或者文本块的渲染时间 (可以帮助我们捕获更多的首次渲染之后的加载性能,但这各指标过于复杂,而且很难解释,也经常出错,没办法确定主要内容什么时候加载完)【
<img>
元素、<svg>
中的<imge>
元素、<video>
元素(如果定义了封面图,会影响LCP)、带url()背景图的元素、块级元素有文本节点或者内联文本子元素】。 - CLS(Cumulative Layout Shift):累计位移偏移,记录了页面上非预期的位移波动。计算方式为:位移影响的面积 * 位移距离。
- LT(Long Task):当一个任务执行时间超过50ms 时消耗到的任务(50ms 阈值是从RAIL模型总结出来的结论,这个是google研究用户感知得出的结论,类似永华的感知/耐心的阈值,超过这个阈值的任务,用户会感知到页面的卡顿);
- TTI(Time to Interactive):首次可交互时间。这个指标计算过程略微复杂,从页面开始到它的主要子资源加载到能够快速地响应用户输入的时间。(没有耗时长任务),它需要满足以下几个条件:
- 从 FCP 指标后开始计算;
- 持续 5 秒内无长任务(执行时间超过 50 ms)且无两个以上正在进行中的 GET 请求;
- 向后搜索静默窗口前的最后一个长任务,如果没有找到长任务,则在FCP上停止;
- TTI 是在安静窗口之前最后一个长任务的结束时间(如果没有找到长任务,则与FCP相同)。
- FID(First Input Delay):首次输入延迟时间,记录在 FCP 和 TTI 之间用户首次与页面交互时响应的延迟,从用户第一次与页面交互到浏览器实际能够开始处理事件的时间。(点击,输入,按键),(人为因素会干预TTI 的结果强调了第一印象,而第一印象对于塑造我们对网站质量和可靠性的整体印象至关重要,因此,改善网站的第一个用户交互将对提高整体的网络交互性产生最大的影响);
- TBT(Total Blocking Time):阻塞总时间,记录在 FCP 到 TTI 之间所有长任务的阻塞时间总和(FID需要依赖用户实际进行操作来计算,不方便开发者通过工具进行测量);
- DCL(DOMContentLoaded):DOM解析完毕,当HTML 文档被完全加载和解析完成之后,DOMContentLoaded 事件被触发,无需等待样式,图像和子框架的完成加载;
- Load(Onload Event):它代表页面中依赖的所有资源加载完的事件;
客户端渲染(CSR)
CSR(Client-Side Rendering),也就是客户端渲染(客户端执行 JS 代码,动态创建 DOM 结构)。
优点
前后端分离。前端专注于界面开发,后端专注于api开发,且前端有更多的选择性,可以使用vue,react框架开发,而不需要遵循后端特定的模板;
服务器压力变轻了,渲染工作在客户端进行,服务器直接返回不加工的html;
用户在后续访问操作体验好,(首屏渲染慢)可以将网站做成SPA,可以增量渲染。
缺点
- 不利于SEO,因为搜索引擎不执行JS相关操作,无法获取渲染后的最终html。
- 首屏渲染时间比较长,因为需要页面执行ajax获取数据来渲染页面,如果请求接口多,不利于首屏渲染。
服务端渲染(SSR)
SSR(Server-Side Rendering),服务端渲染(在服务端生成完整的 HTML 页面)。
优点
- 有利于SEO,由于页面在服务器生成,搜索引擎直接抓取到最终页面结果;
- 有利于首屏渲染,html所需要的数据都在服务器处理好,直接生成html,首屏渲染时间变短;
- 可以利用缓存,进一步提高响应速度。
缺点
- 占用服务器资源,渲染工作都在服务端渲染,大流量场景下会给服务器带来一定的压力(不需要考虑服务器运维成本可冲);
- 用户体验不好,每次跳转到新页面都需要在重新服务端渲染整个页面,不能只渲染可变区域。
解决方案:
静态渲染(SSG)
SSG(Static Site Generation)
优点
- 减轻服务器压力,可以把生成的静态资源(html)放到CDN上,合理利用缓存
- 有利于SEO,由于html已经提前生成好,不需要服务端和客户端去渲染
缺点
- 只适用于静态数据,对于经常改动的数据,需要每次重新生成页面。
- 用户体验不好,每次打开新页面都需要重新渲染整个页面,不能只渲染可变区域
预渲染(Prerendering)
优点:
- 包含SSR的所有优点,但请求时间优化可能没有SSR好
- 操作极其简单,成本极其低廉,只需要安装一个plugin即可
缺点:
- 预渲染不适合频繁变动的页面
- 设置路由越多,构建时间也就越长
解决方案:
- 安装prerender-spa-plugin
- 配置plugin
同构渲染(Isomorphic Rendering)
其实也就是同时支持CSR和SSR,是指在服务器端和客户端都可以执行的渲染方式,也就是同构渲染(isomorphic rendering)。它允许在服务器端和客户端使用相同的代码来生成和渲染应用程序的UI。在初始加载时,服务器会执行应用程序的渲染逻辑,并将生成的HTML内容发送到客户端。然后,客户端会接管应用程序,并使用相同的代码来重新渲染UI,以便处理后续的交互和更新。这种方式可以提供更好的首次加载性能,因为服务器可以生成完整的HTML内容,而客户端只需要处理后续的交互和更新。
服务端 要渲染 Vue 组件 意味着需要处理 *.vue
、*.css
、*.ts
等依赖模块,而这些是 node 本身就不能处理的内容,也不是 renderToString
能够处理的,因此需要借助 打包构建工具(如 webpack) 进行处理;
客户端 实际也需要一个独立的客户端构建版本,虽然最新版本的 Node.js 完全支持 ES2015 特性,但对于旧的浏览器仍然需要对代码进行转译、兼容处理;
基本思路,使用 webpack 同时打包客户端和服务端应用,其中服务端的包会被引入到服务端用来渲染 HTML,同时客户端的包会被送到浏览器用于 激活静态标记。
优点:
- 兼容了前端渲染的大部分优点(节省服务端资源、多终端适配渲染、局部刷新等),同时也具有服务端渲染首屏加载快,SEO支持好的特点
缺点:
- 增加了整个系统的复杂度和维护成本。
不论是在服务端渲染还是在客服端渲染,我们的基本思路就是通过 JavaScript 驱动将 模板 和数据组合成想要的 html 文档片段,然后挂载到 Html 文档中。
html = 模板 + 数据
两端主要的差异在于 获取数据的方式 、 运行的环境和挂载方式。同构渲染分为渐进式和部分
Rehydration(重新水合)
Rehydration是指在服务器端生成HTML内容,并将其发送到客户端,然后在客户端使用JavaScript重新激活(hydrate)这些HTML内容,使其成为一个可交互的应用程序。这种方法通常与单页面应用程序(Single-Page Applications,SPA)相关。在初始加载时,服务器会生成HTML内容,并将其发送到客户端,然后客户端使用JavaScript框架(如React、Vue或Angular)重新激活这些HTML内容,以便处理用户的交互和动态更新。这种方式可以提供更好的性能和用户体验,因为初始渲染在服务器上完成,客户端只需要处理交互和更新。
Trisomorphic Rendering(三方同构渲染)
解决方案:
- Vue SSR(服务器端渲染):
Vue SSR是一种使用Vue框架在服务器端生成HTML内容的技术。通过使用Vue的服务器端渲染功能,可以在服务器上执行Vue组件的渲染逻辑,并将生成的HTML内容发送到客户端。这种方式可以提供更好的首次加载性能和更好的搜索引擎优化(SEO)。 - Vue Hydration(Vue水合):
Vue Hydration是指在客户端使用JavaScript重新激活服务器端渲染生成的HTML内容,使其成为一个可交互的Vue应用程序。在初始加载时,服务器会生成包含Vue组件的HTML内容,并将其发送到客户端。然后,客户端会使用Vue框架重新激活这些HTML内容,以便处理后续的交互和动态更新。Vue提供了hydrate
方法来实现这个过程。 - 渲染框架:React 生态中的 Next.js、Vue 生态中的 Nuxt.js、Angular 生态中的 Angular Universal。
附录:
[页面加载性能之LCP - 知乎 (zhihu.com)]
[Web前端最新优化指标:FP、FCP、LCP、CLS、TTI、FID、TBT、FMP等 - guo&qi - 博客园 (cnblogs.com)](https://www.cnblogs.com/gg-qq/p/16178277.html#:~:text=Web前端最新优化指标:FP、FCP、LCP、CLS、TTI、FID、TBT、FMP等 FP(First Paint):首次绘制时间,这个指标用于记录页面第一次绘制像素的时间。 FCP(First Contentful,Paint):首次内容绘制时间,这个指标用于记录页面首次绘制文本、图片、非空白 Canvas 或 SVG 的时间。)
FP、FCP、FMP、LCP都是什么P? - 知乎 (zhihu.com)
图解 SSR 等 6 种前端渲染模式-腾讯云开发者社区-腾讯云 (tencent.com)