ice.js 3 的体验优化策略介绍

ice.js 3 的体验优化策略介绍_第1张图片

 ice.js 3 已经正式发布,期待更多的业务来使用、验证,一起建设更好的用户体验。

ice.js 3 地址:https://v3.ice.work/

本文将简单介绍 ice.js 3 中已经落地和正在进行的一些体验优化策略,以供探讨。

Chrome 在去年成立了一个名为 Aurora 的项目,深入主流的框架和工具,比如 next.js、nuxt、 angular、webpack 等,探索如何结合框架和工具,帮助 Web 开发者用更低的成本,构建出更好的体验。

ice.js 虽不在这个项目之中,却也是在设计之初就秉持着这种理念,来实现整个框架的。无论是路由方案、数据加载方案、渲染方案,都是围绕着体验而设计。这是因为,我们都越来越意识到,框架掌控着整个应用的生命周期,是最适合从流程上来做出优化、提升体验的。好的体验,应该成为业务开发时的一个顺其自然的产物。

反观目前,我们的 Web 体验则还是一种 开发者重参与的模式,这种方式往往是:

  1. 先开发后治理,在完成业务开发,甚至上线后,再进行性能的评估,分析诊断优化点,实施相应的优化策略

  2. 对开发者要求高,需要每个开发者都能熟练分析各种性能问题,掌握各类场景的体验优化方案

  3. 不可持续,容易随着业务迭代又发生退化

如何改变现状,借助于框架设计,普遍提升业务的体验基线,而不必要求人人成为 Web 体验的专家,这正是 ice.js 3 在探索解决的问题。

本文会简单介绍 ice.js 3 中已经落地和正在进行的一些体验优化策略,以供探讨。

ice.js 3 的体验优化策略介绍_第2张图片

加载策略

  既是 MPA 也是 SPA

ice.js 3 没有区分 MPA 和 SPA,而是对二者做了融合优化。这是因为传统的 MPA 和 SPA 都存在着一定的局限性:

  1. MPA 应用,为每一张页面都独立构建 HTML 和 JS Bundle,页面间资源不共享,页面跳转时,共用的资源被重复加载和执行。

  2. SPA 应用,所有页面复用一张 HTML 和 入口 JS,依赖于主 Bundle 进行路由匹配后,才加载对应的页面,整个过程是串行。

ice.js 3 的体验优化策略介绍_第3张图片

在 ice.js 3 中,我们对此做出了改进:

  1. 每张页面都会构建产生自己的 HTML ,并在 HTML 中引入了当前页面所需的资源,从而避免资源的串行加载。(构建产物类 MPA)

  2. 页面间跳转时,只会加载下一跳页面特有的 Bundle,避免了资源的重复加载。(资源加载逻辑类 SPA)

框架希望通过这种方式,来将默认的资源加载逻辑调到最优。

  区块的并行化加载

在 ice.js 3 中,一张页面,可以由多个 布局组件 和 一个 页面入口组件嵌套而成,也称为 嵌套路由。针对这类场景,ice.js 应用了以下优化,来让页面达成更好的性能体验:

  1. 布局组件和页面入口的 资源数据请求 会被并行加载,以达到最快的资源加载速度。

  2. 路由间跳转时,比如从 /sales/recommends 跳转到 /sales/favorites,框架只会加载差异化的组件 favorites.tsx 进行渲染,而不会重新渲染他们共用的 布局组件

利用框架对 嵌套路由 所做的优化,我们可以将页面中逻辑相对分离的部分,用 嵌套路由 的方式来组织,以获得更好的加载体验。

例如,下面这种常见的移动端营销页,可以对页面内容进行拆分:

  1. 将顶部通用的 Slider 抽象为 布局组件

  2. 将不同 tab 下对应的瀑布流,抽象为 路由组件

这样,Slider瀑布流 就可以做到并行加载,并且当切换 tab 时,新的 tab 内容将由框架触发按需加载和渲染。

ice.js 3 的体验优化策略介绍_第4张图片


  数据的并行化加载

在常规的 React 或 Rax 应用 中,数据请求一般都会在组件首次 useEffect 时发起。这种组织方式,数据依赖于业务 Bundle 的加载、解析、执行,会在页面完成首次渲染后才发起,请求的时机是非常滞后的。

在 ice.js 3 中,框架对页面数据加载的编码规范做出了约定,来最大限度的提前页面的数据加载时机。页面数据请求通过 dataLoader 声明后,会由框架(或容器)统一发起,和业务 Bundle 的加载解析是并行、不阻塞的。在手淘等 PHA 容器下,这种标准化的数据请求,还会被进一步提升为数据预请求,而无需额外的配置。

基于这种模式开发的 Web 应用,天然获得了更好的性能体验。

ice.js 3 的体验优化策略介绍_第5张图片

两种编码方式的请求时机对比如下:

ice.js 3 的体验优化策略介绍_第6张图片

  云端结合的预请求

数据的预请求,已经是体验优化的一种主流手段,它将页面的数据请求和资源请求并行化起来。

ice.js 3 的体验优化策略介绍_第7张图片

但其实结合云和端,页面的 资源加载数据加载过程,可以被更彻底的并行化为下面的形式:

ice.js 3 的体验优化策略介绍_第8张图片

实现更彻底的预请求的前提是:当容器获得一个页面的 URL 地址后,就能知道这个 URL 对应的 Assets、数据接口信息,然后直接发起这些资源的请求。目前,ice.js 正结合云(服务端)和 端(手淘容器)在尝试打通这条链路,以帮助业务获得更好的性能体验。

ice.js 3 的体验优化策略介绍_第9张图片

渲染策略

  默认 HTML 不再空白

常规的 CSR 应用,构建的 HTML 一般只包含一个容器节点,页面的初始状态是空白的,具体内容依赖 JS 的渲染。

ice.js 3 的体验优化策略介绍_第10张图片

然而,我们的页面内容,并不总是全部依赖于动态数据的,页面的基本框架结构常常都是静态的,这部分内容是完全可以在构建时就生成的。这样,页面的白屏时间将被大大缩短,用户体感会从【白屏->页面加载完成】转变为【静态页面->动态数据渲染完成】。

ice.js 3 的体验优化策略介绍_第11张图片

出于这个原因,ice.js 3 默认开启了 SSG,会在构建时,执行页面渲染逻辑,预先构建好页面中不依赖于数据的静态部分。

ice.js 3 的体验优化策略介绍_第12张图片

出于这个原因,ice.js 3 默认开启了 SSG,会在构建时,执行页面渲染逻辑,预先构建好页面中不依赖于数据的静态部分。

  开箱即用的 SSR

SSR 作为体验优化的杀手锏,已在商品详情、用户增长、淘菜菜等业务中普遍使用和验证,可以预估在未来还会有着更广泛的应用。因此,ice.js 3 是将 SSR 作为主要的渲染模式来保障的。

ice.js 3 的 SSR 设计,延续了 Rax 中结合 Midway FaaS 的一体化模式,业务可以在一个工程中完成页面逻辑和渲染服务的维护,以 Serverless 的形式发布 SSR 应用。同时框架还内置了环境变量模拟、错误降级等常用逻辑,来尽可能降低 SSR 应用的开发成本。

ice.js 3 的体验优化策略介绍_第13张图片

  页面内容的流式渲染

建设中

传统的 SSR 渲染是一个同步的过程,需要等到所有的数据请求都完成后,再一次性进行整张页面的渲染,然后把渲染完成的 HTML 字符串下发给浏览器。这种模式下,如果应用中某个依赖的数据接口耗时比较久,就有可能拖慢整张页面的渲染时间,反映到用户体感上就是页面的白屏时间过长。

因此,对页面的内容分批、流式的返回,会是一种用户体感更好的方案。比如,页面的某个区块响应耗时比较久,就可以先渲染 Loading 状态,等待 Server 端完成这个区块的渲染后,再下发这部分的内容。

ice.js 3 的体验优化策略介绍_第14张图片

目前,ice.js 和上下游团队,正在基于 React 18 提供的流式渲染能力,在业务中探索面向业务的解决方案。

  Zero-Bundle-Size  的探索

准备开工

Zero Bundle Size 是 React 在推 Server Components 时提出的一个概念,意思是在 Server 端完成渲染的组件,就不需要再向 Client 端下发 JS Bundle 了。目前社区流行的 Islands Architecture 也可以看做是类似的方案。

这是相对于现有的 SSR 应用而言的,我们知道,SSR 应用即使在 Server 端完成了整张页面的渲染,在 Client 端依然需要下发完整的 JS Bundle,重新执行一遍,来完成 Hydrate,从而让页面达到可交互状态。

而在 Server Components 方案中,页面被划分为两类组件:

  1. Server Component,只在 Server 端执行的组件,用于渲染静态内容

  2. Client Component,只在 Client 端执行的组件,用于处理有交互的内容

ice.js 3 的体验优化策略介绍_第15张图片

浏览器侧,只需要加载 Client Component 对应的 JS  Bundle 即可,可以预期的是页面的资源大小将会大大减小。以 React 官方的 Server Component Demo 为例,Client 端加载的 Bundle 大小从 498k 减少到了 178k。Client 端资源减少,带来的直接收益是,页面的可交互时间将被大大提升。

这将会是 ice.js 在下一阶段的一个主要探索方向,期待通过这种模式,能进一步的提升业务的用户体验。

 Server Components 地址:https://reactjs.org/blog/2020/12/21/data-fetching-with-react-server-components.html

 Islands Architecture 地址:https://www.patterns.dev/posts/islands-architecture/

 Server Component Demo 地址:https://github.com/reactjs/server-components-demo

ice.js 3 的体验优化策略介绍_第16张图片

小结

以上就是 ice.js 3 已经和正在建设的一些体验优化能力,可以简单小结为两个方向:

  1. 在加载策略上,优化了默认的页面资源加载策略,提供了区块和数据的并行化加载能力,同时还在探索如果结合云和端,建设更彻底的预请求方案。

  2. 在渲染策略上,提供了 SSG 能力以优化默认的 HTML 构建产物,在现有 SSR 能力的基础上,还将继续探索流式渲染、Server Components 等方案,进一步提升 SSR 应用的体验。

目前 ice.js 3 已经正式发布,期待更多的业务来使用、验证,一起建设更好的用户体验。

 ice.js 3 地址:https://v3.ice.work/

1232cdf49d08e03e1a00f3cd8cf14492.png

正文结束,以下内容为重复编辑,非常抱歉。

ice.js 3 的体验优化策略介绍_第17张图片

ice.js 框架在之前的版本中,主要服务于中后台 / PC 的项目研发,而随着无线端以及多端能力的拓展,ice.js 3 将成为一套面向大淘宝技术的终端应用框架。因此在 ice.js 3 的版本中除了「开发者体验」之外,还围绕「用户体验」探索了大量技术方案。

ice.js 3 地址:https://v3.ice.work/

ice.js 3 的体验优化策略介绍_第18张图片

ice.js 研发框架是什么

ice.js 研发框架是致力于简单、友好的应用研发框架,基于社区流行的 React 渲染,迄今已发布了两个大版本,并广泛服务于阿里内部和社区用户。截止 2022.11,框架在内部已服务近 9000 活跃项目,累计服务 5000+ 活跃用户。

相比于社区 Webpack、Vite 等工程构建工具和 Next.js、Remix 等应用框架,ice.js 会更加侧重在以下几个方面的建设和思考:

  1. 通过框架内置以及其插件化机制保证跨项目的一致性:对于中大型团队而言,跨团队跨项目的技术方案收敛和一致性能够更好地保证协同效率

  2. 开箱即用的框架能力,减少重复建设:除了基础工程能力的支持之外,框架会结合业务上的主流 SPA、微前端等应用模式,探究业务领域的实践,比如数据请求、状态管理、权限管理、KeepAlive 等

  3. 贴近业务实践,让复杂的技术方案更好地落地:对于 SSR、FaaS 一体化应用等业务解决方案,ice.js 能更好地降低接入成本,同时打通与其他基础建设之间的连接

ice.js 3 的体验优化策略介绍_第19张图片

ice.js 3 改进了什么

ice.js 框架在之前的版本中,主要服务于中后台 / PC 的项目研发,而随着无线端以及多端能力的拓展,ice.js 3 将成为一套面向大淘宝技术的终端应用框架。因此在 ice.js 3 的版本中除了「开发者体验」之外,还围绕「用户体验」探索了大量技术方案。在经历 150+ 个测试版本的迭代,以及部分内部项目的验证后,我们在 2022.11.21 正式发布 3.0 版本。这次的版本将带来以下重要特性:

  1. 多端研发:除了支持支持 PC / 无线的研发之外,还可以通过 ice.js 3 进行小程序的开发,并为多端研发提供解决方案

  2. 全新运行时:默认以 React 18 为基础 UI 框架,同时升级了路由系统默认以约定式方式进行配置,面向开发者提供更小的构建体积以及更加简单的运行时能力定制

  3. 专注性能优化:提供不同解决方案提升页面性能,包括全新的 SSR 设计、页面数据请求能力、资源预加载等

  4. 开发体验提升:引入 swc、esbuild 等原生前端工具链稳步提升构建性能,并且提供丰富的生态以便开始满足开发诉求

  多端研发

  • PC 和无线统一

在这个版本,ice.js 从原先服务中后台开发的基础上,也全面支持了无线端应用的开发。

ice.js 3 的体验优化策略介绍_第20张图片

框架将内置无线端开发的实践,比如 rpx 转 vw 将作为框架默认的能力提供。而对于原 Rax 体系下的源码资产,也可以通过兼容模式,无缝在 ice.js 3 框架下运行。

对于无线搭建体系,通过 rax-compat 的兼容,我们也能使业务的 Solution 中能够无缝支持绝大部分的 Rax 模块 运行在 ice.js 3 之上。

当然,兼容模式只是在成本上对历史源码资产的支持;之后,我们将完全站在 Web 标准 & React 栈基础上建设面向 Web 开发者的研发基线和基础设施。

  • 小程序研发

ice.js 3 的小程序研发将以运行时方案为基础,让用户可以以一码多端的方式高效的进行业务研发。在引入小程序插件之后即可开启:

import { defineConfig } from '@ice/app';
import miniapp from '@ice/plugin-miniapp';


export default defineConfig({
  plugins: [
    miniapp(),
  ],
});

对于小程序窗体 window 和 导航 tabBar 相关的配置,可以在 src/app.ts 中进行配置

// src/app.ts
export const miniappManifest = {
  window: {
    defaultTitle: 'miniapp test',
  },
};

目前 ice.js 3 已支持阿里(支付宝、淘宝、钉钉等)及微信、百度、字节跳动、快手等端。

  全新的运行时

框架默认以 react@18 和 react-router@6 为基础依赖,提供更加强大的运行时 API 和路由系统。


在 ice.js 3 中默认推荐以约定式的路由进行开发,框架将内置对加载和渲染上进行优化,帮助业务构建性能更好的应用,同时也为开发者提供了更加便捷的方式基于路由进行能力定制。

ice.js 3 的体验优化策略介绍_第21张图片

  专注性能优化

  • 资源加载

框架将对对应路由页面进行资源预加载,从原先只关心页面主 bundle 加载的场景转变为并行加载当前页面的资源。

ice.js 3 的体验优化策略介绍_第22张图片

并行加载的方式有利于更快的加载脚本,由于页面访问依赖前端构建的 HTML 内容,对于前后端一体化开发的应用可以无缝享受其带来的提升。而对于常规的前后端分离项目,我们也推荐通过构建产物中的 assets-manifest.json 来预加载当前页面依赖的资源,以获得更好的页面体验。

  • 数据加载

除了资源的并行加载之外,框架对页面数据加载的编码规范做出了约定,来提前页面的数据加载时机。


通过以下方式定义的页面数据将会不在依赖主 bundle 和页面资源的加载:

import { defineDataLoader, useData } from 'ice';


export default function Home() {
  // 通过 useData 消费页面级别定义的数据源
  const data = useData();
  return 
{data.title}
; } export const dataLoader = defineDataLoader( () => fetch('https://api.github.com/repos/alibaba/ice') );

ice.js 3 的体验优化策略介绍_第23张图片

同一个项目,两种不同写法,数据请求发起时机的差异对比如下(测试环境 Chrome slow 3G):

ice.js 3 的体验优化策略介绍_第24张图片

同时框架支持终端统一的数据预请求方案,从框架层面提供开发者统一的使用方法,降低开发者认知成本,抹平不同容器侧概念的差异,并在不同端内获得当前端最极致的体验。

  • 多种渲染模式

除常规的 CSR(Client Side Render) 之外,框架还支持 SSR(Server Side Render) / SSG(Static Site Generation)。框架也提供如 useMounted 和  的能力,方便应用完成差异化的渲染处理:

import { ClientOnly } from 'ice';


export function Home () {
  return (
    loading...
}> {() => page url is {window.location.href}} ); };

框架结合 Midway FaaS,进一步降低业务接入 SSR 应用的研发成本,除了基础的调试开发能力之外,也将在链路方案上给予支持:

ice.js 3 的体验优化策略介绍_第25张图片

后续我们也将为社区开发者打通阿里云、Vercel 等平台的部署流程,方便开发者能够低成本享受 SSR 带来的体验提升。

  稳步提升开发体验

  • 工程体验

开发者体验一直是框架重视的部分,3.0 的版本从多个维度去提升开发者的工程体验。除了默认应用 webpack 5 物理缓存之外,框架采用 swc 作为默认的编译工具来进一步提升编译时间:

ice.js 3 的体验优化策略介绍_第26张图片

SSR 后续将作为推荐开启的链路,因此 server 端构建的体验也是 3.0 版本优化的重点,server 端构建基于 esbuild,并引入预编译及 ES Modules 的执行方式,让开发体验进一步得到提升:

ice.js 3 的体验优化策略介绍_第27张图片

  • 稳定的依赖

框架在原先的基础上进一步优化工程依赖,对相关依赖进行预编译,对比上一个版本(ice.js 2)减少 300+ 个依赖,大小减少 90M+。

关键依赖会被预打包和锁定版本,确保使用的每个小版本均是稳定可用。

  • 配置提示

框架默认的工程配置从 build.json 变更为 ice.config.mts。开发者在获得完善的配置类型提示的同时,可以非常便捷地添加本地插件或者定制运行时能力。开发者不必再为配置出错以及不清楚 API 的导出而困扰。

import { defineConfig } from 'ice';


export default defineConfig(() => {
  plugins: [
    minify: false,
    {
      name: 'custom-plugins',
      setup({ onGetConfig }) {
        onGetConfig(() => {});
      },
    },
  ],
});

ice.js 3 的体验优化策略介绍_第28张图片

下一步

ice.js 3.0 框架依旧有很多需要突破的地方,接下来将在开发者体验和用户体验持续进行打磨:

  1. 探索 React Streaming 和 Server Components 在业务下的实践,提升页面的可交互体验

  2. 进一步推进终端统一的预请求模式,让页面性能再进一步

  3. 持续优化框架开发体验,以轻量方式应用原生前端工具链,给开发者带来极致的调试体验

同时我们也会进一步加强能力生态和周边的建设,如果对框架、工具、组件体系感兴趣的开发者,欢迎参与贡献。

4475835e8e6fdc448c064d17c9103527.png

相关链接

  1. 飞冰(ICE)站点:https://v3.ice.work/

  2. ice.js GitHub 仓库:https://github.com/alibaba/ice

  3. ICE PKG 组件开发站点:https://pkg.ice.work/

  4. ICE PKG Github 仓库:https://github.com/ice-lab/icepkg

  5. Midway:https://midwayjs.org/

  6. swc:https://swc.rs/

  7. esbuild: https://esbuild.github.io/

bc71a078a366fac5dc8ce55e8ca21878.png

团队介绍

大淘宝技术跨端技术部终端框架团队致力建设简单友好的终端应用框架,希望通过研发框架和研发工具提升开发者体验,并降低研发成本。除了研发框架之外,我们还提供了 NPM 包开发解决方案 ICE PKG 以及开发调试工具。
如果对于框架体系、工程构建、组件工程和调试工具等领域有兴趣,欢迎通过 [Github Issue](https://github.com/alibaba/ice/issues) 或者[邮箱](mailto:[email protected]) 联系我们一起探讨。

¤ 拓展阅读 ¤

3DXR技术 | 终端技术 | 音视频技术

服务端技术 | 技术质量 | 数据算法

你可能感兴趣的:(javascript,前端,开发语言,ecmascript,webpack)