23

berial RFC:异步渲染管线

 4 years ago
source link: https://zhuanlan.zhihu.com/p/288513354
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

大家好,我是 132,今天给大家带来一篇文章,是有关于 berial 新的 RFC 的,这个 RFC 非常重要,涉及到的东西可能会比较多,请容我一一道来

这个 RFC 对于 berial 来说非常重要,甚至说对于微前端框架来说都是颠覆的

起因

事情的起因是 多实例 问题,就是说,同一路由匹配到了多个实例,该怎么去控制

berial 现在的版本是抄的 single-spa,它的处理方式是串行异步队列

https:// github.com/berialjs/ber ial/blob/master/src/app.ts#L90

因为是串行的,必须一个完了再走下一个,虽然可以保证渲染结果,但不得不出现 jank 问题

Concurrent

我们不要串行的话,就只能走并发模式,也就是类似 react 的 concurrent mode

Concurrent 是一种调度思路,因为如果不使用调度而只是简单的异步并行渲染,那么就是 Promise.all 而已,Promise.all 就是只关注最终结果,而无法保证顺序

这样虽然解决了 jank 问题,但却出现了新的 tearing 问题

所以说白了,其实我们要做这样一件事:

每个沙箱内部有自己的管线,多个沙箱之间保持正确的顺序

树状结构 vs 扁平结构

我们要实现一个调度器,必须约束结构,berial、qiankun,single-spa 都属于扁平结构,这种结构简单而又灵活,一个路由下,可能匹配了未知数量的沙箱

这种结构是很难用来调度的,所以要换成树状结构,比如 vue-router 类似的 API:

const routes = {
    path: '/parent',
    tag: 'parent-entity',
    url: 'http://localhost: 3000',
    children: [{
        path: '/parent',
        tag: 'child-entity',
        url: 'http://localhost: 3000'
    }]
}

当然这种手写树的方式还是不够直观,我们可以抄袭 react-router

<sand-box> 
   <sand-box slot="a"> 
    <sand-box slot="b"></sand-box> 
    <sand-box slot="c"></sand-box> 
   </sand-box> 
  </sand-box>

然后比如我们现在的 path 是 `/a/c`

我们在沙箱初始化的时候就只生成 a 和 c 的 slot,参考 react 的 Switch 组件

很好,没有命令式的 API 了,但这还没完,因为借助了 web component 的渲染,所以重点在于怎么去调度

调度过程

重点来了,我将会详细介绍这个调度过程,它和 react 的 Fiber 调度思路是类似的

JzYjIvI.jpg!mobile

还记得上面这张图吗,就是说 react 的潜水模型,就是它每次遍历完子元素,都要回溯到父元素,从而不断潜水冒泡,最终所有元素渲染完

我们可以将这种图用于微前端,但是实现有些许不同,我们使用延迟加载的方式来实现它

const connectedCallback = (host) => {
        const ref = hostMap.get(host)
        let ancestor = host
        // 构造回溯树,和链表一样,每个孩子都能拿到父亲,
        // 每个父亲都有一个孩子的序列(react 是链表,我们这里用数组)
        while ((ancestor = ancestor.parentNode || ancestor.host)) {
          if (ancestor['berial-promises']) {
            ancestor['s-p'].push(new Promise((r) => (ref.onReadyResolve = r)))
            ref.ancestor = ancestor
            break
          }
        }
        const schedule = () => { //执行生命周期 }
        if (ancestor['berial-render-callback']) { // 父元素还没执行,子元素先挂起
          ancestor['berial-render-callback'].push(schedule)
        } else { // 确保父亲已经执行
          schedule()
        }
      }

主要的实现思路和 fiber 类似,如果父亲没有执行,那么我就先将自己挂起,等父亲加载了我再加载

我们通过这种潜水冒泡的机制,实现了一个 顺序正确的异步管线

完美!但这还没完,我们还可以做更多!

keep alive

想象一下,我们的路由变化,从 a/b 变化到了 a/b/c ,实际上只增加了一个 c 对吗

如果按照我们现在的,路由每次变化都要重新匹配一遍,a 和 b 的生命周期也会重复走一次,但是其实我们的实例是没有状态的,这就是个沙雕而已

所以我们可以直接做沙雕的缓存,从而实现 keep alive

刺不刺激~调度在手,应有尽有~

Defference from React Fiber

请注意,虽然思路是一样的,但是效果不一样,react 实现异步渲染的单位是元素,所以可以做到时间切片,也就是元素之间的打断行为

我们这个的单位是实例,只是为了做异步渲染管线而已,微前端做时间切片也没有意义

但是异步渲染管线,对于沙箱来说,不仅可以缓解 jank,而且更符合语义

有个好消息是,我预估了一下整个调度的代码量,它竟然比之前的串行队列的代码量更少!天啦噜~

berialjs/berial

最后放一下 berial 的地址,对微前端感兴趣的可以看看,虽然我马上就要重构了,但源码会越来越好看的!

信我!


Recommend

  • 74
    • www.solidot.org 7 years ago
    • Cache

    碳纳米管线从血流中产生电

    您好,您关注的内容已在最近一次服务器维护中进行了备份收藏。如您想阅读此内容,请发送邮件标题为:“申请查看历史备份内容”,正文为:要查看的文章链接,发送至[email protected],进行申请查看。

  • 43
    • 掘金 juejin.im 6 years ago
    • Cache

    [译]Metal 渲染管线教程

    译者注:本文是Raywenderlich上《Metal by Tutorials》免费章节的翻译,是原书第3章.原书第 3 章完成了一个显示立方体的 app,相比其他教程介绍了很多 GPU 硬件部分基础知识. 官网原文地址Metal Rendering Pip

  • 17
    • zhuanlan.zhihu.com 4 years ago
    • Cache

    berial:更精致的微前端框架

    halo,大家好,今天抽时间对 berial 进行了大重构,这次重构还是非常重要的,我准备重新写一篇文章来详细介绍 先前的文章不用看啦,微前端看这一篇就足够了 异步渲染管线 微前端的本质就...

  • 9
    • zhuanlan.zhihu.com 4 years ago
    • Cache

    berial 久违更新:沙箱逃逸

    berial 久违更新:沙箱逃逸伊撒尔前端玩票,高产玩具,fre,fard,berial,ep……halo...

  • 48

    Unity图形渲染Part4/4——通用渲染管线(URP)教程系列(持续更新)腾讯 U3D开发工程师有关在Unity中创建自定义可编程渲染管线的教程的集合。 使用Unity 2019及更高版本。...

  • 24

    【完结】Unity图形渲染Part3/4——可编程渲染管线(SRP)教程系列12...

  • 18
    • zhuanlan.zhihu.com 4 years ago
    • Cache

    游戏引擎中的渲染管线

    游戏引擎中的渲染管线计算机图形学话题下的优秀回答者渲染管线是做图形的同学最常听到的名词,它描述了游戏中的一帧渲染的流程顺序,有关渲染的所有环节可以说都被囊括其中。这篇...

  • 16

    【《Real-Time Rendering 3rd》 提炼总结】(十二) 渲染管线优化方法论:从瓶颈定位到优化策略游戏开发话题下的优秀回答者这是一篇很特殊的文章。它将会是这个系列文章主线的最后一...

  • 7
    • hx-w.github.io 2 years ago
    • Cache

    计算机图形学-实时渲染管线

    记录描述计算机图形学中 实时渲染管线 (Real-time Rendering Pipeline)的内容。 渲染流水线 整个流程都是在硬件(显卡)中实现的。 整理流程可以认为包括三大部分:几何图形处理(顶点和三角形变换),光栅化和Fragment处...

  • 3
    • cniter.github.io 2 years ago
    • Cache

    OpenGL坐标系统与渲染管线

    OpenGL坐标系统与渲染管线 - Shaun's SpaceProcessing math: 52%  图形学中最基础的东西就是坐标系统,三维的东西如何在二维中显示,这中间经历了数次坐标变换,同时坐标变换也贯穿了整个计算机图形渲染管线。

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK