分析vite2.x/rollup分包原理,解决chunk碎片问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了分析vite2.x/rollup分包原理,解决chunk碎片问题相关的知识,希望对你有一定的参考价值。

参考技术A 年前开始负责新项目开发,是一个h5内嵌到企业微信。技术栈是 vite2.x + vue3.x 。随着业务的开展,版本迭代,页面越来越多,第三方依赖也越来越多,打出来的包也越来越大。针对这个问题,很容易就会想到分包这个解决方案。根据 vite 官方文档 提示,做了 vendor 分包之外,还对路由引用的组件做了异步加载处理,也会产生独立分包。这种配置在某个阶段是没问题的。

经过阅读源码,以及官方文档,分析了vite和rollup的分包策略,最后得出这个解决方案:

下面来看看当时是如何分析,以及一步一步来揭开默认分包策略的神秘面纱。

经过测试,在 vite 配置文件,通过 build.rollupOptions.output.manualChunks 配合手动分包策略之后,不会自动生成vendor包。想要知道更清晰 vite 在什么情况会分 vendor 包,什么时候不会分 vendor 包,需要打开源码看清楚。

小结:用户配置了手动分包,就会忽略 vite 提供的 vendor 分包逻辑。

那如果希望在手动分包的基础上还需要 vendor 分包,那么就需要把 vendor 分包的逻辑抄过去就可以了。

备注:

为什么会产生 chunk碎片 ?参考对 webpack 分包的理解,除了入口点(静态入口点、动态入口点)单独生成一个chunk之外,当一个模块被两个或以上的 chunk 引用,这个模块需要单独生成一个 chunk 。

下面从源码的角度看看 rollup 是如何生成这些 chunk碎片 的。

下面来看看 getChunkAssignments 做了什么。

小结:

下面看看通过 createChunks 是如何进行默认分包的

对于生成 chunk签名 ,举个具体点的例子, allEntryPoints 包括一个静态入口点 index.html ,两个动态入口点: Hello.vue 和 World.vue 。有一个模块 sdkUtils.js 的入口点为 Hello.vue (即被 Hello.vue 导入);有一个模块 api.js 的入口点为 Hello.vue 以及 World.vue ;有一个模块 log.js 依赖了 Hello.vue 、 World.vue 和 index.html 。

所以,这个例子中,会产生6个chunk,且 api.js 对应的 chunk 和 log.js 对应的 chunk 就是额外多出来的chunk。

小结:

以太坊 Optimistic Rollup 原理概览

什么是乐观 Rollup?

首先,什么是rollup?它是使以太坊更有效率的方法之一,通常被称为L2解决方案。有3种L2解决方案类型:状态通道、plasma和Rollup。我很快会有一篇关于 L2解决方案的分类 的文章,将详细介绍这个问题。下面是关于什么是Rollup,特别是乐观 Rollup的一个简短总结。

以太坊上有一个智能合约(称为RollupL1),它允许ETH的存款/提款。当你的钱存入RollupL1时,你可以认为它是在L2。L2的资金流动比L1的资金快得多,因为L2的交易更有效,更快。这一点是如何实现的呢?

还有一个在以太坊外的程序(称为RollupL2)。它可以更快地处理交易,因为它不需要通过以太坊缓慢而昂贵的共识机制。它可以处理一堆交易,将它们合并(把它们卷在一起,即 Rollup)成一个批,并将该批次提交给RollupL1

二层网络 Optimism 智能合约要点解析 | 登链社区 | 区块链技术社区解析Optimism在代码层面是如何工作的https://learnblockchain.cn/article/4368

从较高层级了解 Optimistic Rollups 如何工作的,以及解释为什么Optimism被构建为Optimistic Rollup。Optimism描述了一种依赖父区块链安全性的区块链设计。具体来说,Optimistic Rollup利用了父区块链的安全机制而不是自己使用某种机制。

块存储

Optimism的区块存储在以太坊的CanonicalTransactionChain (CTC)合约中,在合约中以追加列表的形式存在,该列表构成了Optimism的区块链。CanonicalTransactionChain保证已存在的区块列表不会被新的以太坊交易修改。但是,如果以太坊自身发生重组、过去的以太坊交易顺序被改变,则该承诺会被打破。Optimism主网被设置为能够抵抗多达50个以太坊区块的重组。如果以太坊经历了更大规模的重组,Optimism也将发生重组。

同时,以太坊系统的关键安全目标是不经历重大的区块重组,因此只要以太坊的共识机制安全Optimism就可以抵御大型的区块重组。通过这种关系特性,Optimism从以太坊中获得它的安全保证。

区块生成

Optimism的区块主要由一个参与方生成 sequencer,该角色帮助网络中提供下列服务:

  • 交易的实时确认和状态更新
  • 构建、执行L2区块
  • 提交用户交易到L1

sequencer没有交易池,因此交易按照被接收的顺序立即接受或者被拒绝。当用户发送交易至sequencer时,它会检查交易的有效性(手续费...)、然后将交易作为待处理区块应用到本地状态。待处理区块以批次形式周期性的提交到以太坊上进行最终确定。批次处理模式通过将固定成本分摊到批次的每个交易上,极大的降低了整体交易的手续费。sequencer使用了基础的压缩技术来最小化写到以太坊上的数据量。

sequencer在L2中有写有限的权利,因此它一旦决定新的pending 块之后,就可以为将被确认的状态提供强保证。即:它可以立即知道一个被L2接收的交易会产生什么样的结果,因此L2的状态可以可靠的快速更新,可以提供快速、及时的用户体验,如提供Defi市场的实时价格更新。

另外,用户也可以绕过sequencer通过发送以太坊交易将L2上的交易数据直接提交到CanonicalTransactionChain合约,这种操作费用很高,因为提交交易的费用完全由这个用户承担不能与其它交易均摊。但是这种方案提供了抗sequencer审查的好处,即使sequencer频繁的审查某个用户,他也可以在L2上发送交易。

当前,唯一的sequencer 仅由 OP Labs PBC组织运行,未来会将sequencer去中心化,可以参考协议RoadMap

用户可以用抗审查的方式执行提款操作,同时rollup必须允许参与方无需可得发送交易结果至以太坊。但是当前, OP Labs PBC 是唯一可以发布交易结果的实体,团队正在紧张工作已达成去中心化的使命。

区块执行

以太坊节点从它的P2P网络中下载区块,Optimism节点从CanonicalTransactionChain合约的仅追加列表中下载区块。

Optimism 节点由两个主要组件组成:以太坊数据索引器、Optimism客户端软件;

  • 以太坊数据索引器也叫做数据传输层 (DTL),从发布到CanonicalTransactionChain合约中的区块数据构建Optimism区块链;DTL搜索由CanonicalTransactionChain触发的事件(表示一个新的区块被发布),然后检查发出这些事件的交易、以标准的以太坊区块结构构建一个发布块。
  • Optimism客户端软件是几乎Geth的clone版,使用与以太坊相同的虚拟机、账户、状态结构、gas计费机制,这种架构称为EVM-等价,意味着大多数的以太坊工具都可以在Optimism上使用。Optimism客户端持续监控DTL新的索引块,下载并执行块内的交易;Optimism执行交易的流程与Ethereum一样:加载Optimism状态、基于该状态执行交易、记录状态变化后的结果。

在不同层之间桥接资产

Optimism设计为用户可以在Optimism和Ethereum上的合约之间发送任意消息;如在网络间转移资产。交互机制因消息发送方向不同而有区别。optimism在标准桥中使用该功能使用户可以将Ethereum上的资产存入Optimism,或者从Optimism提取资产到Ethereum。

Moving from Ethereum to Optimism

从Ethereum发送消息给Optimism,用户仅需在CanonicalTransactionChain合约中创建一个Optimism的新块,包含由生成区块地址生成的交易。

Moving from Optimism to Ethereum

Optimism的合约不能用类似的方式在Ethereum上生成交易,因此从Optimism发送数据回Ethereum比较复杂,必须对以太坊合约中包含的Optimism状态作出可证明陈述。

生成Optimism状态可证明的陈述 是要对Optimism's状态树根进行密码学承诺,每个区块后Optimism状态都会更新,所以每个区块密码学承诺也都会改变。因此状态的密码学承诺是周期性(大约一小时一两次)发布到Ethereum的智能合约上StateCommitmentChain

用户使用密码学承诺生成Optimism的Merkle证明,被Ethereum上的合约进行校验。Optimism维护了一个跨链交互合约L1CrossDomainMessenger,可以代表其它合约验证这些证明。

这些证明用来对存储在Optimism任意合约任意区块高度的数据做可验证声明,该功能可以用来从Optimism的合约向Ethereum的合约发送信息,预部署在Optimism 上的L2ToL1MessagePasser可以被其它合约用来在Optimism状态上存储消息,然后用户可以给Ethereum上的合约证明Optimism合约的某些行为,例如:通过展示存储在L2ToL1MessagePasser上的某些消息哈希表明发送过这些消息。

欺诈证明

在 Optimistic Rollup中,不带可验证证明的状态承诺被发送到Ethereum上,这些承诺在一段时间("challenge window")被视为待处理的,如果一个状态承诺通过了"challenge window”进入unchallenged,它被认为已确认。一旦承诺被视为已确认后,Ethereum上的合约就可以安全的接收基于该承诺的状态证明。

当一个状态承诺被挑战时,可以通过恶意证明流程使它无效。如果状态承诺被挑战成功,它会从StateCommitmentChain中删除,被另一个状态承诺替代。一个成功的挑战不会回滚Optimism,只会发布链的状态承诺,交易顺序和Optimism状态不会因为恶意证明挑战成功而修改。

As part of the OVM 2.0 upgrade, the Optimism fault proof mechanism had to be temporarily disabled. This means that users of the Optimism network currently need to trust the Sequencer node (run by Optimism PBC) to publish valid state roots to Ethereum.

optimistic-rollup.png

参考资料

  1. How Optimism Works | Optimism Docs
  2. Protocol specs | Optimism Docs
  3. https://etherscan.io/address/0xb0ddff09c4019e31960de11bd845e836078e8ebe#code 存储数据的合约

原文链接:https://community.optimism.io/docs/how-optimism-works/#optimistic-rollups-tl-dr

原文作者:optimism dev

Optimistic Rollup 原理概览 - 腾讯云开发者社区-腾讯云从较高层级了解 Optimistic Rollups 如何工作的,以及解释为什么Optimism被构建为Optimistic Rollup。Optimism描述...https://cloud.tencent.com/developer/article/2074918 

以上是关于分析vite2.x/rollup分包原理,解决chunk碎片问题的主要内容,如果未能解决你的问题,请参考以下文章

Optimism Rollup原理详解

以太坊 Optimistic Rollup 原理概览

以太坊 Optimistic Rollup 原理概览

Android热修复学习之旅——HotFix完全解析

vue3响应式原理

ZK-Rollups工作原理