面试官:你解决过哪些难题-预渲染/SSR/SPA/离线包/Snapshot

关注前端早早聊,跟进第三十届|前端早早聊大会 BFF 专场(GraphQL、统一网关、API 接入管理、超大规模集群,协议转换、安全切面、高并发、可视化编排、统一稳定性建设...)8-14 全天直播,9 位讲师,点击报名看直播👉 ):前端

海报 (1).png

前端早早聊大会,与掘金联合举办。加 codingdreamer 进大会技术群,赢在新的起跑线, 全部往期都有全程录播,上手年票一次性解锁所有web


本文是第十八届 - 前端早早聊性能优化专场,也是早早聊第 127 场,来自 阿里 飞猪-太吾 的分享。算法

自我介绍

你们好,我是来自飞猪的胡昊,花名是太吾。先不着急开始,由于我刚才在小助手的朋友圈中看到前几位导师分享的截图,同时看到你们的一些问题。有人说我这篇分享在掘金中有对应的文章,相信也有很多小伙伴可能看过那篇文章,我想说的是看到过那篇文章还要不要听我这边分享,我以为仍是要听的。小程序

文章主要的做用是一个传播,而一些干货确定仍是在 PPT 中,因此你们仍是不要放过前端早早聊 2020 年最后一次分享。前两位大佬都是比较偏硬核:IDE 和可视化。咱最后又回到了传统的 H5 上的一个性能优化,可能没有前两位那么硬核,可是但愿能够给你们带来一些启发。后端

这个 PPT 也是以前用于咱们集团内的一个分享,因此有点偷懒,其实大部份内容是差很少的,可是有一些对外仍是须要有一些具体的讲解。本次分享是《飞猪双 11 - 基于 Web 的性能优化》,双 11 我当时的一个职责是性能的 pm,因此对双 11 总体的 Web 性能优化仍是有必定的理解,但愿把这个理解带给你们。缓存

目录

C18-7 太吾-如何在双11大促中实现会场页面秒开.002.jpeg

整个会分为三个部分来说解。安全

  • 背景
  • 优化的方向。主要的优化手段就是右边你看到的这 6 个东西,具体内容后面具体讲解。
  • 总结和规划

背景

首先是背景。从 Weex 到 Web 是基于什么样的考虑?性能优化

技术栈演进

C18-7 太吾-如何在双11大促中实现会场页面秒开.004.jpeg

咱们飞猪从 2013 年第一个 H5 页面的落地一直到 2016 年总体切换成 Weex,不管是 Weex 仍是 Rax 总体都是以 Weex 渲染为主,在飞猪端和手淘端内。一直到 2020 年的 6 月,咱们又总体顺应集团的策略又切换回 H5,技术栈也做为了统一,总体使用了 Rax1.0 的一个技术栈。微信

以前可能有 Rax 的同窗来前端早早聊分享过。咱们怎样基于这样一个考虑从 Weex 切换到 H5,咱们对于Weex 性能的可信度仍是比 H5 要好的。但为何要从一个相对来讲好一点的 Weex 技术栈切换到 H5?主要是基于如下几点考虑:markdown

  • 第一,咱们认为 H5 的研发体验必定是最好的,而且在飞猪端内升级 UC 的 U4 内核和 WKWebview 以后,性能咱们认为和 Native 的差距是逐渐的缩小,因此咱们能够尝试去进行 H5 的渲染;
  • 第二,针对以前支付宝小程序的策略,对于小程序的开发场景愈来愈多,而小程序的开发动态性它是不足的,由于它传统的开发意义和 H5 的体系是比较割裂的,是须要开发两套代码。若是一个页面要分别投小程序和 H5 的话,须要双倍的开发成本,咱们是比较没法接受的,毕竟人力那么宝贵;
  • 第三,咱们仍是但愿去统一端技术的方案,但愿有一套代码能够多端投放,支持 H五、小程序,以及将来的 Flutter。其实已是如今的 Flutter;
  • 第四,Rax1.0 也是能够支持 Weex,为何没有编译成 Weex?由于 Weex 和小程序都有其须要开发兼容的地方,它都是一个对于传统 API 的子集以及一些单独的 API。因此咱们若是同时要适配 Weex 和小程序,对于开发来讲是灾难性的。底下有一个开发难度的简单对比,单纯的开发 H5是没有限制的,相信不少小伙伴很乐意去开发,可是小程序它是有必定的限制。若是同时开发 Weex 加小程序,两端的同时兼容,那将是没法接受的。而若是是 H5 加小程序,也只须要去单纯的适配一个小程序就能够完成。这样是相对能够接受的。

这是一个总体的背景。

面临的困难

C18-7 太吾-如何在双11大促中实现会场页面秒开.005.jpeg

在基于这个背景下,H5 性能确定是比 Weex 性能相对来讲要差一点。以前刚切换的 H5 以后,两次大促(618 大促和国庆),飞猪的会场性能 IOS 大概在 1.5 秒,安卓大概在 2 秒左右。相对比淘系 618 会场的性能 1.4 秒和 2.1 秒,相对来讲是差很少的。你们基本上都是把通用的优化手段都用尽了,须要进入一个深水区。对于飞猪双11 的目标是 IOS 1.2 秒,安卓 1.6 秒,总体是要提高大概 20% 这样一个水平。在通用手段已经用尽的状况下,还要提高 20%,这样也是一个很是大的挑战。

还有在飞猪这个场景下:

  • 飞猪会场的模块复杂。运营业务方都针对于旅游场景有不少的想法,好比头图这边必定是要有视频的,去吸引别人去玩。以及飞猪这边互动动画模块。还有飞猪榜单类型,也有一些榜单的聚合模块,这些模块都是比较复杂的。有些是前端耗时、有些算法耗时。
  • 接口 RT 比较高。而且服务端是没有办法优化的。相似榜单这种场景,它是多榜单聚合,有榜单的个性化,而且算法那边想要去加多种模型,去更加的拉高它的 RT,理论能够为点击率带来必定的提高,你也没办法反驳别人。因此你只能让它任由的把 RT 升高,而你毫无办法。
  • 旅行行业的一些特色特征。咱们的一些个性化或者是一些模块,都比较依赖于定位信息以及用户信息来给你们推相应的一些商品,定位信息和用户信息会更加的拖慢一个首屏的时间,因此这就是整个优化所面临的一些困难。

优化方向

针对这些困难,视野要从前端这边就是脱离开来,站在是多职能协同的一个方向,主要借助于客户端以及服务端的一些能力,来进行一个总体的优化。

优化思路

C18-7 太吾-如何在双11大促中实现会场页面秒开.007.jpeg

总体的一个优化思路,先说一个通用的优化思路:

  • 第一阶段白屏。整个好比说相似一个页面,它的打开的这样一个进度,从一开始的白屏,主要就是进行一个 Webview 初始化以及主文档下载,基础 JS 下载。前几位讲师基本上提到这些过程,前端优化手段确定是依赖于客户端的缓存,以及减小资源包的大小这些通用手段;
  • 第二阶段 Loading 状况。这边基本上就是发生数据请求的这样一个阶段,在这个阶段可使用的通用手段,就相似服务端优化,请求拆分,把一个页面的数据能够分解成首屏和非首屏这样一个思路。首屏渲染,尽可能少的 DOM,尽可能少的模块以及一些数据预加载。以前说的数据并行以及客户端那边并行发起数据请求方式。以前几位讲师也有提到这里就不细说了;
  • 最后阶段模块上屏。慢慢的有元素能够往屏上进行加载。这段时间它主要发生的就是模块 JS 加载以及模块渲染。这里的通用手段基本上也就是对于模块 JS 精简以及就是对于模块的缓存。这里提一点,咱们会场基本上是搭建的场景,搭建是一个什么概念?就是一个底部的页面的 Layout 上面能够把它想象成根据参数从服务端获取须要某个页面须要哪些模块,再异步的去拉那些模块下来,把数据灌入那些模块再进行展现,是这样一个思路。相似于你如今把你的一个通用型页面,把它拆分红不少个模块去进行渲染,渲染哪些模块是由服务端的数据来决定的,比较相似搭建这样的一个场景。

基于这些通用手段你们都想到了,你们都确定必定都会用完的,而用完以后的效果就好比以前提到的像 61八、国庆大促已是一个顶峰,而以后想再进行优化,就要脱离这些进行更进一步的优化。增进式手段就有如下这些:

  • 预渲染。这个是重点保障一个主会场的打开效果。具体的实现以后会提到;
  • SSR。前几个讲师也有提到,咱们如今在 C 端场景可能 SSR 提的就比较少了,用的比较少了。但如今又重提SSR 这是为何?也是为了提升秒开率。以前 Weex 的状况下,其实一直都是提秒开率的,可是切换到 H5 以后,可能确实没有 Weex 当时这么好,因此咱们须要借助一些 SSR 这样的东西去提高咱们的页面秒开率;
  • Snapshot。相似前几位讲师说的页面快照,把页面的一些数据或者是页面 HTML 直接储存下来。在真实数据到来以前,提早展现一个页面结构,能够大大提早用户的可视时间,让用户不这么焦急等待;
  • SPA。单页应用这样一个东西。把多个页面聚合,保障页面间的跳转顺滑,来提高用户的体感。

主要就是这 4 点来进行一个双 11 大促的场景的保障。

C18-7 太吾-如何在双11大促中实现会场页面秒开.008.jpeg

总体思路用渲染流程来看,块条对应上面的渲染流程能够精简的部分。能够看到从上到下 SSR、Snapshop 和预渲染效果会愈来愈好,可是它适用的场景确定也是愈来愈少的。这个以后具体会提到。相似一些客户端预加载、资源的离线缓存、数据的变形请求和模块的缓存,这都是一些通用的手段,是跟客户端集成已经用了好久了。

总体的主要思路,以前也说到的就是压力转移,把客户端的压力转化到服务端上去。一些缓存、依赖于客户端的能力、阶段的变形以及最后在对用户进行一些体感上的优化,给用户最优秀的体验。

预渲染

C18-7 太吾-如何在双11大促中实现会场页面秒开.009.jpeg

首先说一下预渲染。以前讲师也提到预加载,可能飞猪这边作的更激进一点,能够先看一下右边这个效果。左边开启预渲染以后,点击就相似主会场这样一个胶囊,跳转过去基本上秒开,没有任何渲染的过程那种感受。而右边未开启预渲染就会有白屏、Loading 以及模块的加载这样一个过程,很明显的一个对比。

什么是预渲染?客户端以“离屏”的方式来初始化好容器并 LoadUrl,在上屏以前就完成了页面的 Rasterization(光栅化)。即客户端直接把 URL 经过 Webview 在后台 Load 好,等咱们须要的时候,它直接把 Webview 进行一个上屏的操做就行了,因此作的是比较激进一点。可是为了是对于主会场这种重点保障,仍是在端侧这边作了这样一个能力,体验是比较好。

预渲染它有什么特色?

  • 无感直出。很明显的一个体验;
  • 端侧定制。这多是由于是跟端侧比较耦合,可能如今只有飞猪端内可使用这样一个能力;
  • 少许页面。目前是只给主会场用了,由于你想一想一个 APP 后台去一直启动这样一个 Webview,它确定比较耗内存,而且是可能会引发一些 crash 风险的。因此只能配少许的页面,多了确定是 crash 率可能会愈来愈高。

可是这样一个预渲染方案上了以后,FCP(首屏首次渲染时间)就从 1~2 秒,一直到了前端这边的 100 毫秒,在客户端那边的打点基本上在 50~60 毫秒,就能够完成一个页面的展现,至关之快。

方案设计

C18-7 太吾-如何在双11大促中实现会场页面秒开.010.jpeg

总体的一个方案的设计,咱们会有一个相似 Orange 这样一个动态下发的平台,去配置一些咱们想要预渲染的一个URL,它就会动态下发到一个用户的 APP 上,APP 获取到这些配置以后,就会在后台这边去加载这样一个 URL,而且解析页面,完成页面的光栅化以后,置入缓存池,咱们还会启动一个内存预警的监控,保障 APP 的运行稳定,若是有 crash 风险,咱们会自动释放缓存池中页面,咱们确定仍是保稳定性为主,设计了这样一个内存管控。

当用户真实的去访问 H5 页面的时候,咱们会检测用户 是否命中了预渲染的 URL 配置。咱们会有一个 URL域名,以及 URL query 的一些特殊化的参数,进行 key 的对比。若是命中了以后,就会经过 URL 做为 key,在缓存池中找到 Webview,直接进行一个上屏的操做,GPU 直接进行上屏的显示。由于用客户端在后台已经渲染好这个页面确定跟前端的一些逻辑不相符合,因此咱们须要在真实的上屏以后,客户端会派发一个 document 事件来通知 H5 页面渲染完成以后,前端监听这个事件以后,咱们会进行一些对于性能埋点的处理、页面埋点的处理以及最后那些动态投放的一些事件的处理,这些都是在前端须要进行兼容的地方。

作完这些以后,这一个页面的总体展现逻辑就完成了。在用户退出这个页面以后,咱们会清除对应的 Webview 缓存,而且在 300 毫秒后马上又在后台从新去启动这样一个新的 Webview 去加载这个页面,从新的去进行下一次的这样一个总体流程。

预渲染这样一个方案比预加载只加载一个 Webview 容器,不去请求真实的数据,可能会更加激进一点。可是效果也会相对来讲更好一点。

SSR

C18-7 太吾-如何在双11大促中实现会场页面秒开.011.jpeg

第二个方案就是 SSR。重启 SSR 是为了什么?通常如今在集团内基本上 SSR 它的定义,从本来的 Server-side-render 慢慢转移到 Serverless-side-render,顺应 Serverless 这样一个大潮,反正慢慢的发现 SSR 可用武之地。咱们这种不是传统意义上的 SSR,跟传统意义上 SSR 就是相似 PC 时代这种主文档,就直接返回HTML主文档的那种 SSR。

咱们不一样的点是看底下这样两个渲染流程的对比,上面就是传统的 CSR 的渲染流程,在借助客户端的文档缓存以及数据的预加载,以后就进行模块的 JS 和渲染模块。而咱们这边,经过这个图你们能够看到咱们的 SSR 是在接口中返回的 HTML,在接口返回 HTML 后,咱们去把 HTML 再异步 hydrate 到页面上去,咱们至关因而省掉了后面加载模块 JS 和渲染模块这样一个流程,由于把 HTML 放在接口中返回,因此接口多是会比日常会更慢一点。咱们认为把 HTML 直接塞到页面中去,大概会花 10 毫秒左右的时间。这样,总体在减掉后面模块JS 加载和渲染模块的时间,咱们这边大概会节省 700 毫秒~800 毫秒的时间,SSR 相对于 CSR 这样一个对比。

方案设计

C18-7 太吾-如何在双11大促中实现会场页面秒开.012.jpeg

整个渲染流程的改变,为何是基于这样一个考虑,而不是把在传统意义上在主文当中直接返回整个页面的结构,而是在接口返回的时候,返回这样一个 HTML 来再进行一个渲染。

这背后的思考主要是基于这样一个考虑:以前手淘那边也作了这样一个方案,他们当时作了同步 SSR 放在主文档中返回。他们当时就发现有同步 SSR 后,一个是白屏时间会变得长,由于它没法使用客户端的一些能力,例如离线包以及数据预加载这样两个客户端提供了很好的一个能力。咱们就跟进了异步 SSR方案,也就是放在接口中返回一个 HTML 这样一个方式。

它有几个优势:

  • 减小渲染前的模块 Load 的时间消耗。就是模块那边基本上数据返回回来以后,咱们就能够进行一个页面的展现,而不用等模块在进行一个拉取以及模块的渲染;
  • 渲染就放在了服务端上,能够规避高低端机容器的影响。在高端机上可能就是渲染以及模块拉取这种均可能影响还不大。但对于低端机来讲,对于一些模块的拉取和渲染,这是很是耗时的。而若是把渲染放在服务端上,就能够规避掉这样一个高低端机容器的影响;
  • 能够复用客户端的一个性能优化的能力。这样咱们可使用客户端提供的离线包以及数据预加载的这样一个能力,就不会浪费客户端的一些能力。

咱们基于改形成本最小化的这样一个原则:

  • 基于现有的搭建的链路,仅仅增长一个 SSR render 的链路;
  • 能够作到 CSR 到 SSR 的平滑的切换;
  • 仅须要判断 HTML 是否返回,就能够切换到不一样的链路去进行渲染,而且模块能够基本复用,这样就造成一个改形成本很是小的SSR 效果。

遇到的困难

C18-7 太吾-如何在双11大促中实现会场页面秒开.013.jpeg

  • 一个就是如何进行平滑的切换,就是 SSR 若是出现了问题怎么办?怎么降级回去?基于考虑,因此咱们只须要在前端这边判断接口有没有返回 HTML,就能够走到不一样的链路上去,这是一个比较直接就能够解决问题的方法;
  • 前端稳定性的一些考虑。由于 SSR 确定有不少模块,它可能就是用的一些变量,或者是用的一些异步,可能在服务端那边拿不到模块的具体的一个数据,这样返回的时候可能会出现相似报错或者相似一开始这个模块没有展现出来,以后在 Web 端在 Hydrate 的时候再展现出来,像一个页面闪动这样一个状况。这样对业务模块进行一个总体的就是升级,一个是在 SSR 层作一些变量的兜底,以及对模块进行一些相似占位这样的一个处理,保证页面初始化跟 hydrate 最小更新;
  • 对于沉浸式 titlebar 的一个支持。沉浸式 titltbar 确定是要依赖客户端的一些变量,就客户端的 navbar 的高度是沉浸式 titltbar 的一个必要的参数,而 SSR 确定是获取不到客户端参数的。因此咱们后来发如今 innerHTML 的时候,是有间隙能够获取到这样一个 titlebar 高度的,咱们在这个时候再经过 style 去动态设置这样一个高度就能够实现沉浸式 titlebar 的一个支持;
  • 最后一点,由于咱们如今搭建这边都是经过统一渲染页。不管是离线、数据预加载以及一些模块缓存都是有一个统一渲染页这样一个东西。而相似这样一个统一渲染页,它进行离线了以后,它里面的就是 SSR 的配置,就会固定在那里,就没法针对于单页面,就是至关于你全部的页面要开 SSR 就全开 SSR。咱们有些页面确定不必定适配好了,或者是基于流量的考虑,不可能全部页面都开 SSR 的。因此咱们得再加一层拦截去肯定 是走SSR 链路仍是普通的 CSR 链路。咱们就去进行一个域名的拦截,经过判断后面的 query 来判断它是否在白名单中。在白名单中就走 SSR 链路,不然就走 CSR 链路。

完成这些考虑以后,咱们就成功地上了 SSR 方案,也获得了不错的效果,基本上是从以前的 1~2 秒用了 SSR 以后基本上平均耗时能够降到 1 秒如下。

Snapshot

C18-7 太吾-如何在双11大促中实现会场页面秒开.014.jpeg

页面快照。先看右边的效果,开启了 Snapshot 以后,就没有 Loading 的环节,直接点开页面,页面就直接进行一个相似直出的效果。Snapshot 实际上的效果确定是比 SSR 要好的,可是咱们有了 Snapshot 为何还要 SSR?

  • 首先咱们在营销页面这样一个场景下,回访率是比较低的。一个页面用户第二次去打开这个页面的几率仅为10%~30%。因此 Snapshot 它缓存那些数据,它的命中率也就只有 10%~30% 这样一个运动率;
  • 其次就是 Snapshot 适合的是一种非千人千面的场景。有些东西相似前几位讲师也有说到,就是一个商品的时效性的问题,因此有些场景就不适合用 Snapshot。

针对这个页面快照,咱们这边是设计了两种方案。一种方案是接口缓存,一种方案是传统意义上的 HTML 缓存。为何会有这两种方案的并存?

一种会场天天都会变阵,其实你看双11或者双12,你去逛会场,天天模块的顺序以及模块的数据展现逻辑,运营天天都会去进行修改的。因此天天都会变的状况下,若是是采用了 HTML 缓存,就不可避免的带来一些闪动的问题。例如你昨天访问了这个页面,今天再访问这个页面,它可能中间有几个模块没有了,或者有几个商品,它的坑位从 4 个变成了 6 个,这样你进去以后,它整个页面都会啪啪啪乱闪一气,而且就这种闪动过程,它其实会可能会带来不少毛病,一些不可预知的问题。例如就是模块可能会重复的渲染,而且有些模块它可能就会错位这样一个特别玄学的一些问题。

因此咱们又设计了第二个接口缓存的一个方式,接口缓存配合上模块缓存,基本上也能够作到性能和直接 HTML 缓存这样性能保持基本一致。由于接口缓存配合模块缓存数据相对来讲固定,就避免了闪动,而且咱们为什么有并存这样一个东西,咱们会发现 HTML 缓存也并不是毫无用武之地,就相似右边这种场景,所有会场这种场景,他在整个大促期间基本上是不会变更的。因此就采用 HTML 缓存带来更高更快的一个加载效率,是可使用 HTML 缓存。

方案设计

C18-7 太吾-如何在双11大促中实现会场页面秒开.015.jpeg

整个的方案设计以下:

  • **HTML 缓存。**它的优势就是展示的速度快,操做简单,而且它的劣势就是在模块不肯定的环状况下,页面可能会闪,可是它适用场景就相似所有会场这种。HTML 缓存就相似你们能够理解成你在全部的页面展现完成以后,你去存一个首屏的一个 DOM 到缓存中去,等下次你进入这个页面,你首先去缓存中取这样一个 HTML,先把它给塞到屏幕上去,先给它作上屏的操做。等真实的数据回来以后,在对这样一个界面进行一个 hydrate 操做;
  • **接口缓存。**为何接口缓存跟页面快照有关系。由于刚才说到搭建这样一个场景,有哪些模块其实都是接口去进行返回的,数据也是接口返回的。因此咱们只要把接口缓存下来,咱们就知道这个页面它有哪些模块,而且那些模块的数据是什么,只要把这个接口缓存下来,咱们就能够经过这个接口直接把页面进行一个展现。它的优势就是页面的展现很稳定,可是劣势就是相较于 HTML 缓存,它的展现会相对来讲较慢一点,而且接口缓存它把整个页面的一个JS,就是整个接口都给缓存下来,相较于缓存 HTML,它缓存的占用空间会很大,但它适用的场景就更多了。咱们的一些主要的会场,例如超级宝贝、榜单会场以及特点会场,这些都是使用了这样一个接口缓存的页面快照方式。

再提两点,一些设计上的思路:

  1. 第一个就是 HTML 缓存中,相似咱们有一些时效性的那些商品坑位,咱们不想进行一个 HTML 的保存,DOM 的保存,咱们就能够自定义一些 class name。去给那些模块设置上,到保存的时候,咱们会识别这些 class name,去把它进行一个剔除,或者是只保存父节点这样一个方式,来进行一个时效性的问题解决。还有你们能够基于这样一个 class name 的设计,咱们能够设计一些相似横滑列表,咱们只保存前几项,或者是相似头图 banner,咱们只保存第一项就行了。这样一个减小 HTML 缓存的大小以及效率设计;
  2. 第二个缓存总控。若是缓存无限制的去塞,那确定是不行的。咱们确定是要设计一个缓存的总控来控制缓存的数量。咱们用 LRU (算法)慢慢的去剔除掉使用的最少以及最远进行访问的一些缓存的数据,把新的给缓存进来,总体控制一个最大数,咱们当时应该是当时应该是有缓存最多 8 个。超过 8 个以后就会进行一些剔除的一些判断,这样就保证一个缓存的稳定性。

SPA

C18-7 太吾-如何在双11大促中实现会场页面秒开.016.jpeg

最后一点就是 SPA。咱们慢慢的在页面中的一些优化,给用户的体验也很好了。可是页面间的一个切换的体验还不是很好。由于以前其实你看到底下是有 Tabbar。可是它实际上是多个页面,你若是像以前那种方式去切换底部的 Tab,其实它整个是一个页面的跳转,是 replace 方式,整个页面都会进行一个刷新,这样体验是很是很差的。

在双 11 的时候,咱们对它进行了一个改进。底部 bar 是总体一个包框,咱们经过点击底部 bar 切换的时候,咱们仅须要去获取数据。仍是刚才提到那个点,咱们的页面是经过数据进行获取到模块,经过模块拼装组成的。因此咱们只须要知道模块有哪些,咱们就能够把页面组成起来。因此咱们切换 tab 的时候,咱们只须要去获取数据,去获取到模块,把页面的 DOM 替换一下,咱们就能够完成到页面的这样一个切换,而不用整个的 replace。

为何基于 SPA 实现,仍是刚才说到那个点。

  • 搭建页面已经造成比较成熟的体系,就是咱们的页面框架,它是共用一套 solution/core-render 的,它不会关联页面,就是业务的模块,它背后的 Layout 它全部的页面都是一个,只是上面的模块不一样,你因此看到的页面不一样,其他的后面的 Layout 永远都是同样的;
  • 第二点每一个页面业务模块它都是经过数据获取的,这两个都是必要条件才能够进行这样一个 SPA 的切换。它经过数据获取模块,咱们只须要进行一个 DOM 的切换,就能够进行一个页面间的一个跳转,跳转回去的时候,咱们只须要缓存模块,就能够造成无感的切换效果。

优化演进

image.png

咱们初版设计开启了 SPA 以后,咱们就获取那个模块的数据,替换当前 tab 对应的模块,进行页面的更新。可是咱们发现这样有一个问题:若是总体去不停的去替换模块,仍是比较卡顿的。相对于直接传统意义上咱们心目中那种单页应用仍是有一点鸿沟,因此咱们就对它进行了升级。

咱们只缓存首屏的 DOM,减小数据获取的过程。而且在高端机上咱们会请求首个 tab 数据渲染完成以后,咱们会去预加载其余几个 tab 的数据。这样下次切换过去的时候就没有数据获取过程,咱们能够直接取用它。就至关于把多页面之间的数据同时都拿到以后,咱们切 tab 就能够造成丝滑般的切换效果。咱们只须要隐藏其余 Tab 容器内 DOM。把该展现的那些 DOM 给 display 出来就行了。

资源&数据预缓存

C18-7 太吾-如何在双11大促中实现会场页面秒开.018.jpeg

最后再提两个小点,以前讲师他们也说到。基本上每一个优化都要借助客户端离线能力,离线包和数据的并行请求,我看基本上是 H5 这边是每次都会用到的。

可是就说一点小的设计,咱们对于会场页面是设计了一个 **URL + package **方式,咱们会在信鸽,就是咱们一个后台去输入须要进行离线的页面,在会场这种场景下。咱们信鸽就会在后台跑一个 puppetter,把页面的资源给获取到,而且再经过一些滚屏的操做,把一些懒加载的资源也给获取到。就把整个资源打成一个资源包,最后经过一个hash的方式,在去真实页面访问的时候,进行匹配。

第二点,数据并行请求的这样一个部分,咱们设计了相对于正常的 Memory 命中Miss 不命中这样一个状态下,咱们还设计了一个 Ongoing 这样一个状态。咱们认为只要客户端发起请求,那必定是比前端真实发起请求要快的要提早的,由于实际它确定是要提早的,因此咱们就会等待就是客户端真实的请求返回以后,咱们再会拿客户端的那样一个数据,而不是从新发起一次请求。

总结和规划

整个这边就不那么细说了,反正最终达成了咱们当时这样一个目标,基于咱们以前说到的不管是通用手段也好,仍是一些增进手段也好。通用手段可能也是提供了很大的一个帮助,增进手段在它的基础上有个更高的一个提高。反正最终是达成这样一个目标,而且有了这些东西以后,咱们会有一些将来可期的这样一种感受。

总结

C18-7 太吾-如何在双11大促中实现会场页面秒开.020.jpeg

性能优化,慢慢的就会发现它从前端的这样一个职能慢慢的上升到多职能协同的这样一种方式。慢慢你若是去优化,你确定就慢慢不能站在前端的这样一个视角,慢慢的就会依赖于就相似前面说的 NSR 还有服务端这种 SSR 以及咱们如今还有那种 ESR 就是 CDN 边缘计算这样去的一些就是东西,就慢慢你会发现性能优化慢慢是超脱了前端这样一个单纯的职能这样一个方面,你要站在多智能协同方式进行性能优化的尝试。

规划

规划就不那么细说提几点:

  • SSR 同步的方案。咱们以前刚才说异步在接口中返回 HTML 的方式,异步的方案。同步的方案就是主文档的那种方式,异步的方案在端内效果是确定很好的,由于它直接离线包以后,经过数据的 prefetch 并行请求以后直接拿到 HTML,直接渲染到屏幕上去,这样确定是效果很好的。可是在端外,咱们会有不少,好比相似支付宝、手淘这种场景它就用不了端内的一些离线包和 prefetch 这种方式,因此咱们仍是须要进行一些直接主文档返回的方式;
  • 页面的 Abtest;
  • 客户端那边,要考量接入一下 NativeTab 这样切换多 Tab 的方式;
  • 唤端状况下的一些性能优化,这么多新的优化点,确定须要统一的状态管理。

这样等等一系列的内功提高,以及咱们飞猪这边目标是前端的两秒达标率要达到 90%。因此单纯的单业务,咱们端内的单业务固然就须要去拓展到多业务。咱们就想法是有一个优化手段及如今在集团内咱们是有跨端性能小组是有白皮书这样一个方式,去记录一些优化手段,慢慢去 push 各个业务,进行落地,而且去收集各个业务的一些好的优化的手段,来进行沉淀反哺,慢慢去把总体的性能给提升起来。

C18-7 太吾-如何在双11大促中实现会场页面秒开.021.jpeg

推荐一本书

C18-7 太吾-如何在双11大促中实现会场页面秒开.022.jpeg

最后惯例推荐一本书,这边推荐的就是《金字塔原理》,它是讲一个相似写 PPT 或者是思考表达和解决方式的这样一种逻辑。写 PPT、写文章之类的这样一种逻辑,是一套就是逻辑清晰、重点突出、井井有条,简单易懂的思考表达方式和规范动做。这本书我以为是挺好的。看了以后对于作 PPT 或者是写文章,都是由很多的帮助的。你们有兴趣的能够去看一下。

团队宣传

最后惯例中的惯例,确定是须要招人的。咱们团队关因而飞猪的用户前端和数字化经营团队,咱们的业务是关于旅游的一切咱们均可以去尝试。咱们团队的基础事项。以前有咱们团队的南路,也来分享过 Web Flutter 这样一个方案,咱们团队的有 Flutter,那么以及在咱们如今 SSR 也是咱们团队基于 Serverless 这样一个大潮去作的。还有一些中后台的微前端,以及一体化的开发以及端线互动,以及智能搭建这样一个东西,咱们团队技术思想都是包括的。 因此基本上各个方面你们都有包括,因此你们有兴趣就等你了,就能够经过邮箱,P六、P7 多多益善。

你们也能够关注一下咱们飞猪技术的公众号,Fliggy F2E 以及掘金,有些以前看到我这篇文章有在掘金上发,也是被咱们飞猪前端这边专栏去收藏。若是对跨端这边性能这边有想法的,也能够加我微信了解一下。


关注前端早早聊,跟进学习更多 BFF/GraphQL,请关注第三十届|前端早早聊大会 BFF 专场 - 玩转先后端接口(GraphQL、统一网关、API 接入、API 管理、协议转换、统一安全切面、高并发处理、可视化编排、统一稳定性建设...)8-14 全天直播,9 位讲师,报名上车看直播👉 ):

相关文章
相关标签/搜索