react-vs-vue
React vs Vue 对比
React 和 Vue 是目前最流行的两个前端框架,它们各有特色和优势。
共同点:
- 都使用了虚拟DOM
- 都提供了数据改变 -> 重新渲染的响应式系统
- 两者都是异步更新DOM,React中使用
setState
时不会立刻更新数据,而是加入缓存队列中,批量更新数据之后再渲染DOM;Vue中可以直接修改数据,但此时并不会直接渲染DOM,同样要加入缓存队列,再渲染DOM。
不同点:
- Vue中,只有纳入响应式系统的属性的值改变了(新增属性,或者依赖没有被收集的属性不算纳入响应式系统中),才会重新渲染;而React只要通过
setState
操作了数据,就会重新渲染 - Vue中,只有数据(
state
和props
)改变时才会重新渲染;React中,对于非纯组件,如果父组件重新渲染,那么子资源也会重新渲染 - Vue组件通常需要提前规定好
props
,而react
不用;Vue当传递给组件一个非props
的值,会自动挂载给组件的根元素(对于多个元素需要使用$attr
),而React
并不会。
虚拟DOM
虚拟DOM(VNode),可以粗略地把它理解为一个用来表示真实DOM树的JS对象。
无论Vue还是React,虚拟DOM都是通过数据和渲染函数生成的,对于Vue来说渲染函数是通过模板编译而来的。
第一次生成VNode时,会根据VNode来生成页面,也就是所谓的挂载。
之后当数据改变时,就会重新根据数据和渲染函数生成一个新的VNode。之后使用Diff算法来找出先后两个VNode之间的差异,并自动地对真实DOM进行操作。
虚拟DOM的优劣
在框架前的时代,无论是用原生代码还是使用类似JQuery
的类库,我们都是在直接操作真实DOM。
框架后时代,我们只需要操作数据,框架就会帮我们来操作真实DOM
优点
-
保证性能的下限。
当我们使用虚拟DOM的时候,框架会帮我们完成DOM的操作,相当于是一个自动化的过程。
想一想,一个前端菜鸟随便对真实DOM进行操作,一不小心就会写出低性能的代码。而当我们使用虚拟DOM,类似把我们的需求告诉我们的框架底层,让其进行真实DOM的操作。
-
跨平台。
虚拟 DOM 本质上是 JavaScript 对象,而 DOM 与平台强相关,相比之下虚拟 DOM 可以进行更方便地跨平台操作,例如服务器渲染、weex 开发等等。
缺点
- 虚拟DOM的使用可以保证性能的下限,但也正是因为如此,它也无法做到极致的优化。毕竟,我们操作虚拟DOM的最终目的是操作真实DOM,那论性能的上限自然是无法与直接操作真实DOM相比。
单页/多页应用
不要吐槽为什么这一节放在vue/react区别下面...
单页应用
优点:
- 前后端分离
- 页面的切换流畅。
缺点:
- 首屏加载慢,容易出现首屏白屏的情况
- 对SEO不友好
多页应用
好处
- 首屏加载快
- 对SEO友好
坏处
- 页面的切换不流畅。
服务端渲染/SSR
笔者对SSR并没怎么接触,建议读者跳过该节的内容,目标只是稍微做一个笔记,并不代表严谨和正确。
单页应用的两大缺点,首屏加载和SEO不友好。对于前者,我们通常有类似路由懒加载,或者是骨架屏之类的解决方案;对于后者,谷歌的puppeteer似乎也是可以一定程度上解决的(只听闻过,未曾了解),puppeteer对我们SPA应用进行爬取,然后渲染出html,后端对请求进行判断,如果是爬虫请求,就将我们就走puppeteer渲染的服务器,如果是用户就直接走单页就好了。
服务端渲染也是用来解决单页应用的缺点的,当然,虽然可以一定程度上解决,开发的成本也会相应的提高。
目前我对服务端渲染了解的还不深,只能说大概的目标是通过在服务端渲染出HTML发送给浏览器,取代原本的:浏览器中执行JS代码生成完整的HTML。这样,爬虫就可以爬到完整的网页;不过服务端渲染也会提高服务器的开销。
通常的单页应用采取的是客户端渲染的方式。用户访问网站时通常只获取一个<div id='app'></div>
,之后在浏览器中执行JS代码,生成完整的网页。而搜索引擎爬虫爬到网页后并不会执行JS代码,因此无法爬到网页的文本。
服务端渲染大概的目标是在服务端渲染网页再发送给前端,不过在解决前端SEO的问题的同时,也会给服务器带来额外的开销。
同构:指的是同一份代码,既可以跑在前端,也可以跑在后端。
详细对比
学习曲线
Vue
- 学习曲线相对平缓
- 模板语法接近HTML,容易理解
- 渐进式框架,可以逐步引入
- 中文文档完善
React
- 学习曲线相对陡峭
- 需要掌握JSX语法
- 函数式编程思想
- 需要理解虚拟DOM概念
开发体验
Vue
<template>
<div>
<h1>{{ title }}</h1>
<button @click="increment">{{ count }}</button>
</div>
</template>
<script>
export default {
data() {
return {
title: 'Vue示例',
count: 0
}
},
methods: {
increment() {
this.count++
}
}
}
</script>
React
import React, { useState } from 'react'
function App() {
const [count, setCount] = useState(0)
const title = 'React示例'
const increment = () => {
setCount(count + 1)
}
return (
<div>
<h1>{title}</h1>
<button onClick={increment}>{count}</button>
</div>
)
}
生态系统
Vue生态
- Vue Router(官方路由)
- Vuex/Pinia(状态管理)
- Vue CLI/Vite(构建工具)
- Nuxt.js(SSR框架)
- Element UI、Ant Design Vue(UI库)
React生态
- React Router(路由)
- Redux、MobX、Zustand(状态管理)
- Create React App、Vite(构建工具)
- Next.js、Gatsby(SSR/SSG框架)
- Ant Design、Material-UI(UI库)
性能对比
Vue
- 响应式系统自动优化
- 模板编译时优化
- 更小的包体积
- 更好的内存使用
React
- 需要手动优化(memo、useMemo、useCallback)
- Fiber架构提供更好的调度
- 更大的生态系统
- 更多的性能分析工具
适用场景
选择Vue的情况
- 团队对学习成本敏感
- 需要快速开发原型
- 项目规模中小型
- 偏好模板语法
选择React的情况
- 团队有函数式编程经验
- 大型复杂应用
- 需要丰富的第三方库
- 移动端开发(React Native)
总结
两个框架都是优秀的选择,关键在于:
- 团队技术栈:团队更熟悉哪个
- 项目需求:项目的复杂度和规模
- 生态需求:是否需要特定的第三方库
- 长期维护:团队的长期技术规划