Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >浏览器要原生实现React的并发更新了?

浏览器要原生实现React的并发更新了?

作者头像
公众号@魔术师卡颂
发布于 2023-08-30 02:48:27
发布于 2023-08-30 02:48:27
35000
代码可运行
举报
文章被收录于专栏:魔术师卡颂魔术师卡颂
运行总次数:0
代码可运行

要说React有什么其他框架没有的、独一无二的特性,那一定是「并发更新」。围绕并发更新,存在两个很有意思的现象:

  • 很多开发者听说过他
  • 很少开发者直接使用过他

这两个现象看似矛盾,其实很好解释 —— React18之后的新特性,主要是面向上层框架的(主要是Next.js)。

换句话说,这些新特性(比如并发更新)主要是供框架集成,而不是开发者直接使用。

比如,并发更新的两个核心API —— useTransitionuseDeferredValue,都是针对「视图切换」的场景。

而在前端交互中,最主要的「视图切换」场景就是路由切换」,所以包含路由功能的前端框架就会集成这两个API

而现在,一个试验性浏览器API —— View Transitions API将原生实现「视图切换」功能。

他到底有什么用?如果其他框架使用它,是不是能获得React同样的并发更新能力?

什么是视图切换?

不管是View Transitions API,还是ReactuseTransition,都是为了提高「视图切换」场景下的用户体验。

什么是「视图切换」?以view-transitions Demo[1]举例。这是个简单的相册Demo,点击左边图片缩略图,右边会显示大图:

整个过程简单来说包括3个步骤:

  1. 点击缩略图
  2. 请求大图数据
  3. 大图请求成功后,显示大图

从步骤1到3的过程就是个典型的「视图切换」。整个过程有很多可以优化体验的地方,比如:

  1. 从旧图到新图的渐变过渡效果
  2. 点击缩略图发起图片请求后,大图区域可以先显示旧图(而不是立刻显示loading效果),待新图请求成功后再过渡到新图

这里解释下第二点,对于切换类的交互,相比于「当视图切换时立刻显示loading效果,待新视图加载完成后过渡到新视图」「当视图切换时先显示旧视图,待新视图加载完成后过渡到视图」在延迟不高的情况下体验会更好。

除了上述这些「体验优化的点」,视图切换的实现还有很多细节需要考虑,比如:

  • 如何处理新旧视图切换时的过渡效果?
  • 如何处理新视图加载时的loading效果?
  • 当正在请求新视图数据时(此时视图处在旧视图中),用户又对旧视图产生交互怎么办?
  • 视图切换时如何处理页面滚动位置、光标聚焦(focus)位置?
  • 对于使用屏幕阅读器的盲人,视图切换时阅读器会朗读什么?

除此之外,不同场景下的「视图切换」实现细节也不同。比如,如何在切换页面时优化视图切换效果?

SPA(单页应用)出现之前,网站通常是由多个页面组成。比如下面网站的每个Tab栏,对应一个独立网页,其中:

  • bramus Tab对应 https://http203-playlist.netlify.app/with-bramus/
  • cassie Tab对应https://http203-playlist.netlify.app/with-cassie/

Tab之间切换,浏览器会:

  • 卸载之前的页面
  • 请求新页面数据
  • 加载新页面

「页面卸载」「页面加载」之间的白屏间隙会造成屏幕闪烁。

要优化这种场景下优化视图切换效果,当前唯一做法是利用history API接管路由操作,将网页变成一个SPA

既然「视图切换」是如此常见的需求,且有这么多需要考虑的因素,那浏览器为什么不原生实现呢?

于是,View Transitions API应运而生。

当前View Transitions API不支持跨页面的视图切换,但未来会支持

View Transitions的使用

View Transitions API[2]的使用很简单,只需要用document.startViewTransition包裹视图切换后的回调函数即可。

对于上述相册示例,回调函数的逻辑是「将img标签src属性更新为新图片地址」

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const transition = document.startViewTransition(() => {
  galleryImg.src = /* 新图片地址 */;
});

剩下所有跟过渡相关的实现,都由Transitions API解决。

View Transitions实现原理

在视图切换时,存在2个概念:

  • 切换前的旧视图
  • 切换后的新视图

当使用View Transitions后,会依次做:

  1. 对页面进行截图,作为旧视图
  2. 执行传递给document.startViewTransition的回调
  3. DOM更新后,对更新后的页面进行截图,作为新视图
  4. 构造一棵代表过渡效果的伪元素树,挂载在根元素(html元素)下,结构类似如下:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
::view-transition
└─ ::view-transition-group(root)
   └─ ::view-transition-image-pair(root)
      ├─ ::view-transition-old(root)
      └─ ::view-transition-new(root)

其中:

  • 旧视图保存在::view-transition-old(root)
  • 新视图保存在::view-transition-new(root)

对于上述相册示例,挂载的伪元素树结构如下:

之所以要挂载一棵伪元素树,主要是因为两个原因:

  1. 开发者可以对微元素应用CSS规则

比如,上述两个「保存了新/旧视图的截图」的伪元素,类似于img标签,开发者可以对他们应用CSS动画,当新/旧视图切换时,实现自定义的过渡效果。

  1. 方便对整个页面中不同「视图切换」分组

比如,在上述相册示例中,视图切换的元素包括两部分:

  • 新/旧视图之间的切换(下图红框部分)
  • 新/旧图片名称的切换(下图绿框部分)

相册对应的HTML结构如下:

  • img标签对应视图部分(下图红框部分)
  • figcaption标签对应图片名称部分(下图绿框部分)

当我们为figcaption元素设置不同的view-transition-name

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
figcaption {
  view-transition-name: figure-caption;
}

会得到一棵新的伪元素树,其中「视图部分」「图片名称部分」伪元素是分离开的:

通过给页面中不同HTML元素定义不同的view-transition-name属性,就能独立控制这个元素是视图切换时的过渡效果。

与 React 的区别

浏览器原生的View Transitions APIReact中的useTransition相比,谁更强大呢?

毫无疑问,前者更强大。

这是因为,对于View Transitions API,通过操作伪元素树,开发者可以自定义过渡效果(就像对img元素使用CSS过渡动画一样简单)。即使不使用CSS Transition,使用JS Transition也完全没问题。

document.startViewTransition方法会返回一个transition对象实例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const transition = document.startViewTransition(() => {
  galleryImg.src = /* 新图片地址 */;
});

该实例包含了一系列视图切换生命周期对应的promise,比如:

  • ViewTransition.ready:伪元素树构造完成,准备开始过渡时
  • ViewTransition.finished:过渡效果完成后,此时新视图已经可以响应用户交互

而在React中,使用useTransition后,与其说完成的是「视图切换」,不如说完成的是:

  1. 首先,完成状态的切换
  2. React内部再将状态变化映射到视图变化

本质来说,操作视图的是React,而不是开发者。所以,开发者很难控制过渡效果。

动效库Framer的作者认为,由于开发者很难控制并发更新的完整生命周期,所以很难在并发更新时表达animation效果:

简单来说就是,开发者很难为并发更新定制过渡效果(用CSSJS)。

总结

可以认为,View Transitions API是比useTransition抽象程度更高、开发者可控性更高的APIuseTransition能实现的,他可以。useTransition不能实现的,他也可以。

要说缺点,View Transitions APIWeb平台独有的,而useTransition依赖React核心的并发更新能力,是跨端的。

当前,View Transitions API的兼容性并不好:

但是,一旦他变成可以大规模使用的API,那么其他前端框架只要接入他,就能轻松获得比React耗费大量精力实现的useTransition(以及底层的并发更新特性)更强大的视图切换能力。

参考资料

[1]

view-transitions Demo: https://mdn.github.io/dom-examples/view-transitions/#

[2]

View Transitions API: https://developer.mozilla.org/en-US/docs/Web/API/View_Transitions_API

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2023-08-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 魔术师卡颂 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Patterns.dev 用设计模式打造最佳用户体验,提高应用的可扩展性和性能
各位码友们,大家好!今天给大家介绍一个非常棒的学习设计模式的网站 - Patterns.dev。
埃兰德欧神
2024/07/15
2510
Patterns.dev 用设计模式打造最佳用户体验,提高应用的可扩展性和性能
Next.js 实战 (三):优雅的实现暗黑主题模式
在 Next.js 中要实现暗黑模式,需要用到一个库:next-themes,它可以帮助我们很轻易地实现暗黑模式切换。
白雾茫茫丶
2024/12/10
3530
Next.js 实战 (三):优雅的实现暗黑主题模式
Nuxt3 实战 (六):Footer 底部布局
3、 这里我们顺便给 AppColorMode 组件加个切换过渡动画,让网站丰富一点:
白雾茫茫丶
2024/05/22
2340
Nuxt3 实战 (六):Footer 底部布局
WWDC24 - iOS18 下的 WebKit 有哪些更新?
作为 Web 开发者我们最关注的当然就是 WebKit 的更新了,新版本的 WebKit 总计共带来了 48 项新的 Web 平台功能,以及 18 项弃用功能和 174 项错误修复。
ConardLi
2024/07/01
5580
WWDC24 - iOS18 下的 WebKit 有哪些更新?
Safari 18.0 WebKit 新特性介绍
干扰控制功能允许你在浏览网页时隐藏干扰项,例如登录横幅、Cookie 偏好弹窗、新闻通讯注册覆盖层等。该功能适用于 iOS 18、iPadOS 18 和 macOS Sequoia 上的 Safari。
ACK
2024/09/26
1.1K0
Safari 18.0 WebKit 新特性介绍
「React18新特性」深入浅出用户体验大师—transition
在 React 18 中,引进了一个新的 API —— startTransition 还有二个新的 hooks —— useTransition 和 useDeferredValue,本质上它们离不开一个概念 transition 。
用户6835371
2021/11/10
2K0
CSS 实用新特性:交互、组件、效率的革新
本文将盘点与解析 CSS 的实用新特性,结合技术原理、应用场景和开发实践。从重塑交互体验,到强化组件功能,再到全面优化开发流程,这些新特性不仅显著提升了开发者的工作效率,还为用户带来了更加流畅、互动性更强的网页体验。
球球的前端奶茶屋
2025/04/09
8970
CSS 实用新特性:交互、组件、效率的革新
使用JavaScript与CSS创建"移动高亮"导航栏
在本教程中,Blake Lundquist向我们展示了两种仅使用原生JavaScript和CSS创建"移动高亮"导航模式的技巧。第一种技术使用getBoundingClientRect方法在点击时显式动画导航栏项之间的边框。第二种方法使用新的View Transition API实现相同功能。
qife122
2025/08/19
2130
聊一聊CSS的过去与未来,加深对CSS的理解
它涉及设定规则,让浏览器自动处理。你可以改变边距、字体和大小,但这只是浅尝辄止,你懂的吗?
前端达人
2023/08/31
7910
聊一聊CSS的过去与未来,加深对CSS的理解
不再支持 IE,React 新特性详细解读
近日,React 18 已经正式发布了,带来了许多令人兴奋的新特性。在这个版本中,React 通过其改进的渲染系统带来了并发能力,并在此基础上构建了转换或自动批处理等性能增强特性。本文将介绍这些特性的机制,以及它们对 React 开发人员有哪些帮助。
深度学习与Python
2022/06/13
2.3K0
【Vuejs】1720- 详细聊一聊 Vue3 动态组件
动态组件[1]是 Vue3 中非常重要的一个组件类型,它可以让我们在不同的场景下灵活地渲染不同的组件。
pingan8787
2023/09/01
1.3K0
【Vuejs】1720- 详细聊一聊 Vue3 动态组件
useTransition:开启React并发模式
React 18 之前,更新内容渲染的方式是通过一个单一的且不可中断的同步事务进行处理。同步渲染意味着,一旦开始渲染就无法中断,直到用户可以在屏幕上看到渲染结果。
奋飛
2024/05/25
6190
useTransition:开启React并发模式
用几行原生JS就可以实现丝滑的元素过渡效果!
做过体验优化的朋友应该都清楚,如果用原生的 CSS 或者 JS 动画去实现,想要实现出类似的效果,不会特别简单,而且也要考虑性能问题。
ConardLi
2021/12/02
2.3K0
用几行原生JS就可以实现丝滑的元素过渡效果!
用案例的方式解释 React 18 新特性——并发渲染、自动批处理等
React 18 于 2022 年 3 月发布。这个版本侧重于性能改进和渲染引擎的更新。同时,React 18 为并发渲染奠定了基础,未来的 React 功能将在此基础上构建。
前端修罗场
2023/10/07
1.5K0
用案例的方式解释 React 18 新特性——并发渲染、自动批处理等
React 18不再依赖Concurrent Mode开启并发更新了
大家好,我卡颂。 相信很多关注React进展的朋友都了解Concurrent Mode,他是「渐进升级」策略的产物。
公众号@魔术师卡颂
2021/11/23
1.3K0
React 18不再依赖Concurrent Mode开启并发更新了
详解React的Transition工作原理原理
Transition 是 react18 引入的新概念,用来区分紧急和非紧急的更新。
夏天的味道123
2022/10/18
9670
React18 带来了什么
经历了v17的平缓过渡,React 3月29日正式发布了React v18版本。这个版本带来了一些十分重要的能力。但大家伙不必担心学不动,这个版本无破坏性更新,hooks 还在。以下是核心功能更新。
jadeCarver
2022/08/06
8770
在追寻极致体验的康庄大道上,React 玩出了花
前者是 loading(或 skeleton)带来的好处,而后者得益于 Concurrent Mode 下的间歇调度
ayqy贾杰
2019/12/01
1.7K0
2023 年前端大事记
哈喽各位《code 秘密花园》的订阅者们,一年一度的年更系列又来了。关注我的老粉都知道,每到年末我会对前端生态在这一年的重大变化做一次总结,之前的总结:
ConardLi
2023/12/28
7540
2023 年前端大事记
React 18 如何提升应用性能
最近,无意中看到一篇关于React 18的文章,翻看之后,发现很多东西都是React官网没有细讲的,并且发现有些点也是在实际开发中可以实践和应用的.
前端柒八九
2023/09/10
7440
React 18 如何提升应用性能
相关推荐
Patterns.dev 用设计模式打造最佳用户体验,提高应用的可扩展性和性能
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验