阅读 5122

《前端会客厅》对话winter和尤雨溪,深度探寻Vue3设计思想(上)

前端会客厅第一期B站地址

前端会客厅是我和winter设计的一档技术节目,每期会邀请一个嘉宾,畅聊前端技术

上次B站尤大的直播讲解了很多Vue3新的设计,有幸前端会客厅第一期邀请到了尤大从另外一个角度聊聊vue3, 针对Vue3的新特性,我也准备了一些代码演示 相当于一个买家秀, 代码实操我最近会录制视频放B站,欢迎关注

toc

  • 体验vue3的三种姿势
  • Composition Api
  • Fragment Teleport suspense
  • 尺寸
  • 内部架构
  • 响应式系统独立
  • 自定义渲染器api

体验vue3的三种姿势

  1. vue-cli
  2. 官方的webpack-preview
  3. vite

详细步骤

# vue-cli
npm install -g @vue/cli
vue create 01-vue3-cli
cd 01-vue3-cli
vue add vue-next
npm run serve

# webpack
git clone https://github.com/vuejs/vue-next-webpack-preview.git 01-vue3-webpack
cd 01-vue3-webpack
npm install 
npm run dev

# vite

npm install -g create-vite-app
create-vite-app 01-vue3-vite
cd 01-vue3-vite
npm install
npm run dev

复制代码

Vite

面向现代浏览器的开发工具 告别开发环境冗长的等待 手写vite理解原理

大致的原理就是拦截import发出的http请求,返回浏览器的代码,也保留了import语法,让浏览器自己去处理依赖 script type module 支持import,让浏览器处理es6 import的活,好处就是当前页面引用多少,编译多少,项目越大优势越大

编译还是用了rollup, 不过生产环境其实也尽可能的利用es6的import,当你做懒加载分包的时候 ,如果浏览器不支持,动态的import是被polyfill的

热加载 基本都是100ms以内 相比于大项目webpack2S左右的体验,差距是很大的

尤大愿意往vite这类工具上投入精力,是个非常好的事情,大家苦webpack久矣

vie还给我一个启发,就是尤大起名的艺术,vue和vite都是法语 有逼格,以后我搞开源 Vue3如此牛皮,我决定我下一个开源项目就叫cuir.js

性能

  1. vue2初始化 所有的数据都要走defineProperty ,vue3用proxy 动态的决定返回什么 做了拦截,初始工作量减少 组件实例化的提升还是明显,首次mount 一会代码看看

vue2和vue3的update对比代码

vdom重写

动态静态模板 vue2一竿子到底 全部diff vue3在模板层做静态分析 生成聪明的渲染函数
静态提升,节点结构根据v-if和v-for切分出block,block内部节点结构石不变的,我们直接把动态节点维护在一个数组里即可

一个大模板 可能嵌套了十层,但是没有v-if或者v-for的话,整个模板只需要记录一个数组,包含动态节点,就是这样

vue2也有static标记优化,但是做的不极致,vue3设计了block的概念,update只和动态内容强相关,和静态内容解耦了,大部分项目静态节点比你想象的多,比如一些为了布局存在的div等, 这个以后会专门发个文章讲解

测试组件

官方说update是1.3~2倍, 测试的结果要更好一些 看来尤大比较保守

<template>
    <div>
    <h1>Vue2 {{ items.length }} Components</h1>
    <p>{{ action }} took {{time}}ms.</p>
    <button @click="shuffle">shuffle</button>
    <ul class="col-row" v-for="item in items" :key="item.id">
      <li class="col-md-1" >kkb</li> 
      <li class="col-md-1" >kkb</li> 
      <li class="col-md-1" >kkb</li> 
      <li class="col-md-1" >{{item.label}}</li> 
    </ul>
    </div>
</template>

<script>
import {shuffle} from 'lodash'
var total = 500
var items = []
for (var i = 0; i < total; i++) {
  items.push({
    id: i,
    label: String(Math.random()).slice(0, 5)
  })
}
let s = window.performance.now()

export default{
    data(){
        return {
        total: total,
        time: 0,
        action: 'Render',
        items: items,
        selected: null,
        actions:['删除','更新']
        }
    },
    mounted(){
        this.time = window.performance.now() - s
    },
  methods: {
    shuffle(){
      this.action = 'shuffle'
      this.items = shuffle(this.items)
      let s = window.performance.now()
      this.$nextTick(()=>{
        this.time = window.performance.now() - s
      })
    }
  }
}

</script>

复制代码

SSR

SSR相比于vue2有2~3倍的差距,会客厅当时说到这一点,尤大对ssr的新实现,还是非常得意的 vue3能静态字符串化的 全部静态字符串,只有一个buffer,vue2之前就算是字符串, 内部还是有虚拟节点的处理逻辑

用wrk压测qps,详细代码文章vue2和vue3的ssr 直接上结论 130 VS 288 ,也是2.x倍的差距,这个差距在组件复杂之后,变得越来越明显 ,大家可以考虑自己试一下500个component的压测

// vue2 12个进程,300个并发,压10秒
➜  ~ wrk -t12 -c400 -d10s http://localhost:9092/
Running 10s test @ http://localhost:9092/
  12 threads and 400 connections
^[[A  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     1.48s   442.21ms   1.80s    89.88%
    Req/Sec    24.62     20.56    88.00     59.73%
  1319 requests in 10.10s, 173.65MB read
  Socket errors: connect 157, read 183, write 0, timeout 74
Requests/sec:    130.58
Transfer/sec:     17.19MB
复制代码
// vue3 12个进程,300个并发,压10秒
➜  ~ wrk -t12 -c400 -d10s http://localhost:9093/
Running 10s test @ http://localhost:9093/
  12 threads and 400 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency   770.76ms  165.36ms   1.89s    89.11%
    Req/Sec    63.99     56.81   252.00     74.34%
  2912 requests in 10.10s, 411.12MB read
  Socket errors: connect 157, read 31, write 0, timeout 0
Requests/sec:    288.21
Transfer/sec:     40.69MB

复制代码

更新性能

静态动态三比一, 首屏渲染对比,update性能对比

包含了dom操作,如果去掉dom操作,性能对比更明显 可能要3倍以上

日常业务场景,静态组件会比你意识到的还要多一些,比如一些一些css布局使用的div

值得期待

详细代码

内部架构

分层清晰,monorepo

编译层+运行时优化

自定义渲染器api

由于mpvue这个框架的发布,想修改vue2的compiler和runtime,必须要完整的fork一个vue,再改,小右17年的微博,还说过以后要把这些全部拆开,20年的vue3实现了 这个也需要写点文章来说,先放图和代码

下集预告

  1. compostion api实战
  2. fragment 组件递归
  3. 响应式骚操作
  4. custom renderer自定义渲染器实战
  5. 用户答疑+八卦
    • reactivity和vuex的关系
    • class based api被干掉的心路历程
    • vue3设计的过程
    • 小右如何学习的

扩展

最近在写vue3全家桶的电子书,推荐一下

www.yuque.com/woniuppp/vu…

第二期嘉宾是周爱民老师,会深入聊js,欢迎关注,持续更新