前言

自JavaScript诞生以来,前端技术发展非常迅速。移动端白屏优化是前端界面体验的一个重要优化方向,Web 前端诞生了 SSR 、CSR、预渲染等技术。在美团支付的前端技术体系里,通过预渲染提升网页首帧优化,从而优化了白屏问题,提升用户体验,并形成了最佳实践。

在前端渲染领域,主要有以下几种方式可供选择:

CSR 预渲染 SSR 同构
优点 不依赖数据FP 时间最快客户端用户体验好内存数据共享 不依赖数据FCP 时间比 CSR 快客户端用户体验好内存数据共享 SEO 友好首屏性能高,FMP 比 CSR 和预渲染快 SEO 友好首屏性能高,FMP 比 CSR 和预渲染快客户端用户体验好内存数据共享客户端与服务端代码公用,开发效率高
缺点 SEO 不友好FCP 、FMP 慢 SEO 不友好FMP 慢 客户端数据共享成本高模板维护成本高 Node 容易形成性能瓶颈

通过对比,同构方案集合 CSR 与 SSR 的优点,可以适用于大部分业务场景。但由于在同构的系统架构中,连接前后端的 Node 中间层处于核心链路,系统可用性的瓶颈就依赖于 Node ,一旦作为短板的 Node 挂了,整个服务都不可用。

结合到我们团队负责的支付业务场景里,由于支付业务追求极致的系统稳定性,服务不可用直接影响到客诉和资损,因此我们采用浏览器端渲染的架构。在保证系统稳定性的前提下,还需要保障用户体验,所以采用了预渲染的方式。

那么究竟什么是预渲染呢?什么是 FCP/FMP 呢?我们先从最常见的 CSR 开始说起。

以 Vue 举例,常见的 CSR 形式如下:

一切看似很美好。然而,作为以用户体验为首要目标的我们发现了一个体验问题:首屏白屏问题

为什么会首屏白屏

浏览器渲染包含 HTML 解析、DOM 树构建、CSSOM 构建、JavaScript 解析、布局、绘制等等,大致如下图所示:

要搞清楚为什么会有白屏,就需要利用这个理论基础来对实际项目进行具体分析。通过 DevTools 进行分析:

  • 等待 HTML 文档返回,此时处于白屏状态。
  • 对 HTML 文档解析完成后进行首屏渲染,因为项目中对 id="app加了灰色的背景色,因此呈现出灰屏。
  • 进行文件加载、JS 解析等过程,导致界面长时间出于灰屏中。
  • 当 Vue 实例触发了 mounted 后,界面显示出大体框架。
  • 调用 API 获取到时机业务数据后才能展示出最终的页面内容。

由此得出结论,因为要等待文件加载、CSSOM 构建、JS 解析等过程,而这些过程比较耗时,导致用户会长时间出于不可交互的首屏灰白屏状态,从而给用户一种网页很“慢”的感觉。那么一个网页太“慢”,会造成什么影响呢?

“慢”的影响

Global Web Performance Matters for ecommerce的报告中指出:

  • 57%的用户更在乎网页在3秒内是否完成加载。
  • 52%的在线用户认为网页打开速度影响到他们对网站的忠实度。
  • 每慢1秒造成页面 PV 降低11%,用户满意度也随之降低降低16%。
  • 近半数移动用户因为在10秒内仍未打开页面从而放弃。

我们团队主要负责美团支付相关的业务,如果网站太慢会影响用户的支付体验,会造成客诉或资损。既然网站太“慢”会造成如此重要的影响,那要如何优化呢?

优化思路

在User-centric Performance Metrics一文中,共提到了4个页面渲染的关键指标:

基于这个理论基础,再回过头来看看之前项目的实际表现:

可见在 FP 的灰白屏界面停留了很长时间,用户不清楚网站是否有在正常加载,用户体验很差。

试想:如果我们可以将 FCP 或 FMP 完整的 HTML 文档提前到 FP 时机预渲染,用户看到页面框架,能感受到页面正在加载而不是冷冰冰的灰白屏,那么用户更愿意等待页面加载完成,从而降低了流失率。并且这种改观在弱网环境下更明显。

通过对比 FP、FCP、FMP 这三个时期 DOM 的差异,发现区别在于:



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

仍然以 Vue 为例, 在其生命周期中,mounted 对应的是 FCP,updated 对应的是 FMP。那么具体应该使用哪个生命周期的 HTML 结构呢?

mounted (FCP) updated (FMP)
缺点 只是视觉体验将 FCP 提前,实际的 TTI 时间变化不大 构建时需要获取数据,编译速度慢构建时与运行时的数据存在差异性有复杂交互的页面,仍需等待,实际的 TTI 时间变化不大
优点 不受数据影响,编译速度快 首屏体验好对于纯展示类型的页面,FP 与 TTI 时间近乎一致

通过以上的对比,最终选择在 mounted 时触发构建时预渲染。由于我们采用的是 CSR 的架构,没有 Node 作为中间层,因此要实现 DOM 内容的预渲染,就需要在项目构建编译时完成对原始模板的更新替换。

至此,我们明确了构建时预渲染的大体方案。

构建时预渲染方案

构建时预渲染流程:

配置读取

由于 SPA 可以由多个路由构成,需要根据业务场景决定哪些路由需要用到预渲染。因此这里的配置文件主要是用于告知编译器需要进行预渲染的路由。

在我们的系统架构里,脚手架是基于 Webpack 自研的,在此基础上可以自定义自动化构建任务和配置。

触发构建

项目中主要是使用 TypeScript,利用 TS 的装饰器,我们封装了统一的预渲染构建的钩子方法,从而只用一行代码即可完成构建时预渲染的触发。

装饰器:

使用:

构建编译

从流程图上,需要在发布机上启动模拟的浏览器环境,并通过预渲染的事件钩子获取当前的页面内容,生成最终的 HTML 文件。

由于我们在预渲染上的尝试比较早,当时还没有 Headless Chrome 、 Puppeteer、Prerender SPA Plugin等,因此在选型上使用的是 phantomjs-prebuilt(Prerender SPA Plugin 早期版本也是基于 phantomjs-prebuilt 实现的)。

通过 phantom 提供的 API 可获得当前 HTML,示例如下:

为了提高构建效率,并行对配置的多个页面或路由进行预渲染构建,保证在 5S 内即可完成构建,流程图如下:

方案优化

理想很丰满,现实很骨感。在实际投产中,构建时预渲染方案遇到了一个问题。

我们梳理一下简化后的项目上线过程:

开发 -> 编译 -> 上线

假设本次修改了静态文件中的一个 JS 文件,这个文件会通过 CDN 方式在 HTML 里引用,那么最终在 HTML 文档中的引用方式是 <script src="http://cdn.com/index.js"></script>。然而由于项目还没有上线,所以其实通过完整 URL 的方式是获取不到这个文件的;而预渲染的构建又是在上线动作之前,所以问题就产生了:

构建时预渲染无法正常获取文件,导致编译报错

怎么办?

请求劫持

因为在做预渲染时,我们使用启动了一个模拟的浏览器环境,根据 phantom 提供的 API,可以对发出的请求加以劫持,将获取 CDN 文件的请求劫持到本地,从而在根本上解决了这个问题。示例代码如下:

构建时预渲染研发流程及效果

最终,构建时预渲染研发流程如下:

开发阶段:

  • 通过 TypeScript 的装饰器单行引入预渲染构建触发的方法。
  • 发布前修改编译构建的配置文件。

发布阶段:

  • 先进行常规的项目构建。
  • 若有预渲染相关配置,则触发预渲染构建。
  • 通过预渲染得到最终的文件,并完成发布上线动作。

完整的用户请求路径如下:

通过构建时预渲染在项目中的使用,FCP 的时间相比之前减少了 75%。

作者简介

寒阳,美团资深研发工程师,多年前端研发经历,负责美团支付钱包团队和美团支付前端基础技术。

招聘信息

我们美团金融服务平台大前端研发组在高速成长中,我们欢迎更多优秀的 Web 前端研发工程师加入,感兴趣的朋友可以将简历发送到邮箱:shanghanyang@meituan.com。

前端黑科技:美团网页首帧优化实践相关推荐

  1. 黑科技!美团网页首帧优化实践

    点击上方"开发者技术前线",选择"星标" 每天 14.00 在看 | 真爱 本文转载自:美团技术团队 | 责编:可可 导读 美团支付前端团队支持着美团钱包及支付 ...

  2. 构建时预渲染:网页首帧优化实践

    前言 自JavaScript诞生以来,前端技术发展非常迅速.移动端白屏优化是前端界面体验的一个重要优化方向,Web 前端诞生了 SSR .CSR.预渲染等技术.在美团支付的前端技术体系里,通过预渲染提 ...

  3. 优酷播放黑科技 | 自由视角技术体验优化实践

    作者:邓小龙(白展) "本文为<优酷播放黑科技>系列文章第一篇<自由视角技术体验优化实践>,之后我们会陆续上线<基于WebRTC实现的直播"云多视角& ...

  4. JS奇淫技巧:挑战前端黑科技,数值的七种写法,能全看懂的一定是高手

    JS奇淫技巧:数值的七种写法 JS奇淫技巧:挑战前端黑科技,数值的七种写法,能全看懂的一定是高手 你知道吗?在JS编程中,数值可以有很多种写法. 第一种写法: 一般情况而言,数值就是数值. 比如: v ...

  5. 时间都去哪了-移动Web首屏优化实践

    时间都去哪了-移动Web首屏优化实践 首屏时间 可用性的前提,后面用户是否使用你app很重要的因素之一: 我们PC上访问其实现在的带宽已经很好了,百兆光宽带,但是在移动端就不一样了,很多用户还是使用的 ...

  6. 前端制作科技感网页登录界面

    注:如需背景图请联系作者(QQ:3416252112) 效果图: 源码: <!DOCTYPE html> <html> <head><meta http-eq ...

  7. 海康威视智能机器人泊车_黑科技!杭州首个自动泊车的机器人停车库今年内投用...

    去商场购物找不到停车位,是个麻烦事:shopping完忘了车停哪里,这尴尬又怎么解决?随着自动泊车技术与机器人技术的快速发展,智能停车库正日益普及.日前,记者了解到,杭州首个机器人停车库预计在今年内开 ...

  8. linux nodejs 采集器,前端工程师通过nodejs链接linux,并上传代码进行半自动化更新,省去ssh+ftp的链接工具-前端黑科技-SegmentFault思否...

    这几天,有一个临时项目,每次发布,都要我本地手动zip,上传fpt,然后shell unzip. 搞得头大,不胜其烦. 我是个懒人,这明显不是我的风格. 干脆nodejs写一个自动链接服务器,并上传文 ...

  9. 【Android高级工程师系统学习视频】百度APP-Android-H5首屏优化实践

    百度App自2016年上半年尝试Feed流业务形态,至2017年下半年,历经10个版本的迭代,基本完成了产品形态的初步探索.在整个Feed流形态的闭环中,新闻详情页(文中称为落地页)作为重要的组成部分 ...

最新文章

  1. iptables总结
  2. 乡村振兴谋定齐鲁道路-农业大健康·李昌平:放权改革创新
  3. linux上设置git高亮
  4. python+OpenCV图像处理(九)图像金字塔
  5. html5游戏制作入门系列教程(七)
  6. android110 jni01
  7. 基于MSBuild的xnb资源预生成机制
  8. MySQL 主键入门到精通
  9. 导入资料的预览与修改
  10. 2019版PHP自动发卡平台源码
  11. oracle更改字段大小语句,sql语句修改字段长度(实例)
  12. Python量化数据获取:总资产同比增长率与净资产同比增长率
  13. Python进阶之Scrapy抓取阳光政务平台
  14. html5饼图的制作方法,excel2010复合饼图制作方法
  15. 人脸表情识别相关研究
  16. 使用GitHub搭建个人博客
  17. WIN10家庭版局域网连接设置(含设置账号密码)
  18. 计算机管理磁盘管理,windows7双磁盘管理图文教程
  19. Windows10 调整屏幕颜色,设置暖色屏幕的办法
  20. 这些手机隐藏功能你知道吗?

热门文章

  1. 数字 IC 设计、FPGA 设计秋招笔试题目、答案、解析(6)2022 紫光展锐数字芯片提前批笔试
  2. try-catch用法和含义
  3. 让电视拥有高清影视,先搞清楚HDMI和VGA的误区
  4. PAT 1104 天长地久 (20 分) C语言
  5. 6-4 二叉树 - 12. 分枝结点数分数 10
  6. python调用通达信函数_Python读取通达信本地数据
  7. CSS3实现缺角矩形
  8. 如何使用notepad++查看和替换回车换行符
  9. 到底如何选择阿里云服务器?
  10. 大学什么时候考合适计算机二级证