Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

运行时/编译时前端框架都有哪些优缺点? #62

Open
BetaSu opened this issue Apr 15, 2022 · 2 comments
Open

运行时/编译时前端框架都有哪些优缺点? #62

BetaSu opened this issue Apr 15, 2022 · 2 comments
Labels
JS l1:JS 相关 React l3:React 相关 Vue l3:Vue 相关问题 前端框架 l2:前端框架相关 场景 具体业务场景下的问题 悬赏15元 最佳答题者可以获得 15 元

Comments

@BetaSu
Copy link
Owner

BetaSu commented Apr 15, 2022

发生问题的场景

主流的前端框架从实现原理讲,一般分为:

  • 纯运行时(比如React
  • 运行时 + 编译时(比如Vue
  • 纯编译时(比如Svelte

你能从以下角度回答该问题么?

需要解决的问题

  1. 列举对应的框架,分别解释什么是运行时、编译时、运行时 + 编译时?
  2. 它们有哪些优缺点?

最佳答案评选标准

  1. 答案遵循以上顺序作答

最佳答案

悬赏中,欢迎作答...

答题同学须知

  • 答题规范:请在一次评论中完成作答,后续修改也请编辑该评论,而不是追加新的评论

  • 评选标准:最佳答案由围观同学的 👍 和卡颂共同决定

  • 评选时间:一般是问题发布24小时后评选,如果问题发布当天回答数较少,问题悬赏金额可能增加,同时悬赏时间也会增加

围观同学须知

  • 对于你满意的答案,请不要吝惜你的 👍,这是评选最佳答案的依据

  • 非答题的评论会被删除,问题相关讨论请在赏金猎人群中进行

@BetaSu BetaSu added JS l1:JS 相关 React l3:React 相关 Vue l3:Vue 相关问题 悬赏10元 最佳答题者可以获得 10 元 场景 具体业务场景下的问题 前端框架 l2:前端框架相关 labels Apr 15, 2022
@a145789
Copy link

a145789 commented Apr 15, 2022

运行时

纯运行时框架比较好理解,举一个例子 JQuery .虽然 JQuery 并不能称之为框架,但我们可以看到 JQuery 的一些特点,不需要在 html 上做一些例如 v-show v-bind 的标记,也不需要稀奇古怪的写法,也不需要什么特定的环境,引入一个 script 文件即可,只是一个单纯的 js库 ,优化了 jsDom 之间的交互。同样的,在 React 身上我们也可看到许多共通点,React 在 js 层面上也没有许多稀奇古怪的写法,以 一切皆在 js 之下 为基准,也许这也是 React 自称一个 视图库,而不把自己当成一个框架的原因。当然这一切都在不考虑 Jsx 的情况下,React 的运行时体现在与视图的交互比如 虚拟 dom fiber 等。不使用 Jsx 手写 render 函数 虽然效果一样,但是尤为的繁琐,所以是在前端工程化的今天出现了编译。既然项目最后需要经过层层转译 tree-shake UglifyJS.minify 打包生成,那我为什么不加一层转译让开发者的体验更好,Reactrender 函数 变为 Jsx语法糖 的形式出现,让诸多开发者的开发体验极大提升,React 还是一个纯运行时的库,Jsx 语法本质上依然还是 render 函数 ,你写怎样的 Jsx 就会编译为怎样的 render 函数,同样的只要你想,你也可以无压力把 render 函数 反编译为 Jsx 这二者只不过在开发阶段展现给你的形式不一样,这样就可以引申出下一个 编译-运行时 框架 Vue

编译-运行时

为什么称 Vue 为 编译-运行时 框架?因为 Vue 既可以当作一个纯运行时的视图库,同时又与编译分隔不开。如果你可以像使用 React 一样使用 Vue,你会发现 Vue 就是自动挡版本的 React ,你需要 setState 我只需要 state.value = ‘’ 直接触发视图更新,Vue 也使用了 render 函数,甚至你可以在 Vue 中使用 Jsx ,此时 Vue 可以保证 一切皆在 js 之下 ,你把 Vue 当作一个单纯的 MVVM 的视图库就可以。那 Vue 的不可分隔的编译体现在哪?就是我们所熟知的 template ,为什么因为模板 Vue 被归类为 编译-运行时 框架,而 React 也有 Jsx 却仍然是 纯运行时框架。我们可以看两段代码。

// template
<div>
    <h1 v-if="true" />
    <h2 v-else />
</div>
// 编译后的render 函数 伪代码
// h('div', { children: true ? h('h1') : h('h2') })


<div>
    { true ? <h1 /> : <h2 /> }
</div>

// h('div', { children: true ? h('h1') : h('h2') })

可以看到其实二者的 render 函数其实可以保持一致,但是 jsx 只是将转换 Html 元素为 render 函数,而模板则将 if else 逻辑一同转换出来,再举一个例子

<div>{s ?? <h1 />}</div>

jsx 可以很轻松的转换为 h('div', { children: s ?? h('h1') }),如果在 vue 模板中就无法这样写,只能

<div>
  <h1 v-if="s != null" />
</div>

// 转换出来的代码为 h('div', { children: s != null && h('h1') })

可以看到在使用模板的时候有许多限制,这也是为什么很多 React 开发者会说写 jsx 就像在写 js ,因为写 jsx 就是在写 js。看到这里好似模板编译一无是处?那接下来就是编译发力的阶段。

既然我使用编译了,那就贯彻到底。虽然模板在 js 层面有很多限制,但是也得到了更多的能力,比如 Vue3 带来的性能改进,静态内容提升。还是上面的例子,对于 render 函数而言,jsx 只能原封不动的编译

<div>{true ? <h1 /> : <h2 />}</div>

//   h('div', { children: true ? h('h1') : h('h2') })

这样想要重新生成虚拟 Dom 就需要层层调用 h 函数,但是模板可以可以做一些性能优化

;<div>
  <h1 v-if="true" />
  <h2 v-else />
</div>

const h1 = h('h1')
const h2 = h('h2')

//   h('div', { children: true ? h1 : h2 })

这样再次生成 虚拟 Dom 的时候就节省两个函数执行的开销,还可以体现编译好处的就是 Vue 的指令,比如 v-show 这个指令,你可以想想在 React 中想要实现这个功能绝对没有直接写个 v-show 方便。此外你可以自定义指令,假设有个需求需要将权限控制细分到按钮,在 Vue 中你可以写一个 v-permission 指令,只需要加到 <button v-permission> 就可以,如果在 React 中可就要废一番脑细胞了。

Vue 使用编译的好处不仅体现在模板中,我们都知道 Vue 使用了单文件 .vue 的形式,这样也可以对 scriptcss 做优化,例如想要实现 css 隔离,只需要加一个简单的 scoped 就可以了,而 React 催生一大堆 css 方案,生态丰富是好事,但有时候想解决痛点只有一个就好了。在 Vue3 引入了 Composition Api ,Composition Api 在 js 下总有许多不舒服的地方,比如繁杂的 return 返回,ref 一个变量需要写繁琐的 .value,而这些 Vue 也正在通过编译的方式解决 script-setup

纯编译

对于纯编译框架 Svelte 了解的不多,只知道不需要虚拟 dom,通过编译对每个 Html 元素添加增删改方法,可以极细粒度的控制元素变更,轻运行时,性能很好。

总结

,主要对比了 ReactVue 之间有关 运行时-编译时 之间的不同。其实你会发现虽然 Jsx 只是算做 React 生态的一部分,但也绕不开编译,只不过这个编译对 Js 能力几乎无影响。Vue 不使用模板也可以当作纯运行时的一个框架,但使用模板编译去拓展了很多能力。使用编译的初衷都是缘因对 Html-Js-Css 的不爽。render 函数 很烦,那我就创造一个 Jsx,需要返回一大堆无用的东西,那我就开发 script-setup

利弊

二者之间的利弊其实挺明显的,纯运行时框架最大的利就是不会与 Js 有差异化,Js 能用的我都能用,尤其体现在生态方面,比如接入 Typescript 基本不需要什么 hack 方式。弊也很明显,能力只能局限在 Js 中,当性能出现瓶颈的时候,只能通过 Js 运行时的方式去解决,比如 fiber 并发模式。其实 Jsx 真的无法做编译时优化么?肯定是可以的,但是做了,也就不是一个纯粹的视图库了。

编译的利就是拓展了很多能力,觉得 Web 语法不爽,甚至可以搞一套自己喜欢的语法,只要最后编译为 Html-Js-Css 就可以了,但是弊就是要自己抹平与 Js 之间的差异,Vuetemplate 模板对 Typescript 支持也是老生常谈的问题,比如出现的新语法 ?? ?. 这些想要在模板中使用都需要框架开发者主动去支持,如果没有人力及时支持怎么办?只能放弃使用或者自己发挥主观能动性。

@BetaSu BetaSu added 悬赏15元 最佳答题者可以获得 15 元 and removed 悬赏10元 最佳答题者可以获得 10 元 labels Apr 19, 2022
@Garker
Copy link

Garker commented May 9, 2022

Svelte这种纯编译的框架,因为在运行前直接编译生成HTML代码而不是像react和vue这样生成vdom转换为HTML,因为少了在运行时候的转换所以减少了一些性能上的开销,但直接编译为HTML也给Svelte这种纯编译的框架带来了最大的弊端,不灵活只能局限在浏览器以及支持HTML格式的软件中使用reactvue生成的是vdom,大家都知道vdom就是描述元素状态的对象(例如:一个div的大小尺寸等),而vdom在不同环境中表现的形式不一样,正因为vdom的存在使得reactvue可以生成桌面端,移动端(react native)的应用。

简单总结:纯编译框架在做到性能优化的同时失去了灵活性,react就是纯粹的运行时框架,vue则是中庸之道在各个框架吸取精华

前端小白 用过的框架也只有react 所以说的很片面 肯定也有错的地方,欢迎指正

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
JS l1:JS 相关 React l3:React 相关 Vue l3:Vue 相关问题 前端框架 l2:前端框架相关 场景 具体业务场景下的问题 悬赏15元 最佳答题者可以获得 15 元
Projects
None yet
Development

No branches or pull requests

3 participants