Introduction to the experience optimization strategy of ice.js 3





 ic e.js 3 has been officially released, looking forward to more businesses to use, verify, and build a better user experience together.

ice.js  3 address: https://v3.ice.work/

This article will briefly introduce some experience optimization strategies that have been implemented and are in progress in ice.js 3 for discussion.


Chrome established a project called Aurora last year to explore mainstream frameworks and tools, such as next.js, nuxt, angular, webpack, etc., to explore how to combine frameworks and tools to help web developers build out better experience.


Although ice.js is not in this project, it adheres to this concept at the beginning of the design to realize the entire framework. Whether it is routing schemes, data loading schemes, or rendering schemes, they are all designed around the experience. This is because we are all more and more aware that the framework controls the entire application lifecycle, and is the most suitable for optimizing the process and improving the experience. A good experience should be a natural product of business development.


In contrast, at present, our web experience is still 开发者重参与 a model, which is often:
  1. Develop first and then govern. After completing business development and even going online, perform performance evaluation, analyze and diagnose optimization points, and implement corresponding optimization strategies
  2. The requirements for developers are high, and each developer needs to be proficient in analyzing various performance problems and mastering experience optimization solutions for various scenarios
  3. Unsustainable, easy to degrade with business iteration


How to change the status quo, with the help of framework design, generally improve the experience baseline of the business, without requiring everyone to become an expert in Web experience, this is exactly the problem that ice.js 3 is exploring and solving.


This article will briefly introduce some experience optimization strategies that have been implemented and are in progress in ice.js 3 for discussion.


loading strategy

▐It   is both an MPA and a SPA


ice.js 3 does not distinguish between MPA and SPA, but integrates and optimizes the two. This is because both traditional MPA and SPA have certain limitations:
  1. MPA application builds HTML and JS Bundle independently for each page, resources are not shared between pages, and shared resources are loaded and executed repeatedly when the page jumps.
  2. For SPA applications, all pages reuse a piece of HTML and entry JS, relying on the main Bundle for route matching before loading the corresponding page, the whole process is serial.

In ice.js 3 we improved on this:
  1. Each page will build its own HTML, and introduce the resources required by the current page in the HTML, thus avoiding the serial loading of resources. (build product class MPA)
  2. When jumping between pages, only the Bundle specific to the next page will be loaded, avoiding repeated loading of resources. (Resource loading logic class SPA)

The framework hopes to optimize the default resource loading logic in this way.


   Parallelized loading of blocks


In ice.js 3, a page can 布局组件 be 页面入口组件 nested by multiple and one , also known as 嵌套路由 . For such scenarios, ice.js applies the following optimizations to achieve a better performance experience on the page:
  1. The and of layout components 资源 and 数据请求 will be loaded in parallel to achieve the fastest resource loading speed.
  2. When jumping between routes, such as /sales/recommends jumping to /sales/favorites , the framework will only load differentiated components favorites.tsx for rendering, and will not re-render their common ones 布局组件 .

Using the optimization 嵌套路由 made , we can 嵌套路由 organize the relatively separated logic parts of the page in a way to obtain a better loading experience.


For example, the following common mobile marketing pages can split the content of the page:

  1. Abstract the top generic asSlider布局组件

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


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



  数据的并行化加载


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


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


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



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



  云端结合的预请求


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


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


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

渲染策略


  默认 HTML 不再空白


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


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


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



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

  开箱即用的 SSR


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


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



  页面内容的流式渲染


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

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


目前,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 端执行的组件,用于处理有交互的内容



浏览器侧,只需要加载 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 已经和正在建设的一些体验优化能力,可以简单小结为两个方向:
  1. 在加载策略上,优化了默认的页面资源加载策略,提供了区块和数据的并行化加载能力,同时还在探索如果结合云和端,建设更彻底的预请求方案。
  2. 在渲染策略上,提供了 SSG 能力以优化默认的 HTML 构建产物,在现有 SSR 能力的基础上,还将继续探索流式渲染、Server Components 等方案,进一步提升 SSR 应用的体验。


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

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


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





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

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



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 改进了什么

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 从原先服务中后台开发的基础上,也全面支持了无线端应用的开发。



框架将内置无线端开发的实践,比如 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.tsexport const miniappManifest = {  window: {    defaultTitle: 'miniapp test',  },};

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


  全新的运行时


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


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


  专注性能优化


  • 资源加载


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


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


  • 数据加载


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

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

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


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


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

  • 多种渲染模式


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

import { ClientOnly } from 'ice';
export function Home () { return ( <ClientOnly fallback={<div>loading...</div>}> {() => <span>page url is {window.location.href}</span>} </ClientOnly> );};


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



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


  稳步提升开发体验


  • 工程体验


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


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


  • 稳定的依赖


框架在原先的基础上进一步优化工程依赖,对相关依赖进行预编译,对比上一个版本(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.0 框架依旧有很多需要突破的地方,接下来将在开发者体验和用户体验持续进行打磨:

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

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

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


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


相关链接


  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/


团队介绍

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

¤  拓展阅读  ¤

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

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


本文分享自微信公众号 - 大淘宝技术(AlibabaMTT)。
如有侵权,请联系 [email protected] 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

{{o.name}}
{{m.name}}

Guess you like

Origin my.oschina.net/u/4662964/blog/5640499