完全に独断と偏見だけどReact vs Vue してみた

## 比較内容

大まかに以下の点で比較検討をしました。私個人はVueよりもReactに慣れているので、偏った意見かもしれないけど参考になれば。

|  |React  |Vue  |
|---|:---:|:---:|
|手軽さ  | △ |◎  |
|開発効率  | ○ | ○ |
|TypeScriptとの相性  |◎  |△  |
|GraphQLとの相性  |○  |△  |
|パフォーマンス面  |○  |△  |
|採用・育成面  |△  |◎  |

## 手軽さ
|  |React  |Vue  |
|---|:---|:---|
|ロジック  | ◎ <br>Hooksを使うことできる |○ <br>TSを使う場合はClassのメソッドとして定義 |
|マークアップ  | ○<br>JSX記法<br>本来は慣れが必要 | ◎<br>ほぼ普通のマークアップ |
|スタイリング  |△<br>いくつかの手法があるが基本的にはCSSModulesかCSS-in-JSを使う。どちらにしてもスコープドセレクタにするには一手間必要  |◎<br>デフォルトでスコープドセレクタを使うことができる。また、従来のCSS（SCSS）で書くことができる  |
|エコシステム  |△<br>create-react-app<br>TSで作成などはできるがオプションは豊富ではない。また必要なプラグインなどは自分で入れる必要がある。|◎<br>vue-cli<br>オプションが豊富。コマンドラインで指示に従いながら選択すれば開発環境ができている。|

### Vueの圧勝

こと手軽さにおいてはVueの方が圧倒的と言っていいです。
また、モダンフロントエンドのComponent志向では必須と言えるスコープドセレクタもデフォルトなので `vue-cli` で用意されたもので基本的な開発ができることもプラスです。

ただ、ロジック部分はReactの方が優秀。Hooksにより再利用性・拡張性の高いロジックをComponentで使用可能かつ、SteteをComponentに閉じ込めることができます。


## 開発効率
|  |React  |Vue  |
|---|:---|:---|
|VSCodeとの相性  | ○<br>特に気になる部分もなく使える |△<br>`vuter` を使うのだが、補完がいまいち  |
|ビュー作成  | △<br>Vueに比べるとコード量が多くなりがち。また、前述のようにスタイリングに一手間必要。 | ◎<br>HTML,CSSができればできてしまう。 |
|ロジック部分  |◎<br>基本が関数型プログラミングなので前述のHooksで拡張性・汎用性のあるロジックを書く  |○<br>TypeScriptでClassを書くのと同じ。私の所感ではあるがプロジェクトで使う場合に同じようなメソッドが増えてしまうのではと思っている。ベストプラクティスが知りたい。|
|UIライブラリ  |豊富にある  |豊富にある  |

### VueのVSCode補完について

個人的に気になる点として

- 使っていないメソッドが明示的ではない
- Componentからジャンプできない（import文からは可能）

vueファイルはオリジナルファイル形式のためどうしてもエディターのサポートが遅れてしまうことが起因しているのかも


### 実際のコードで比較

Mutaionを使ってCSVファイルアップロードをするケースをそれぞれ書いてみました。実際にプロダクトで使えるレベルではないですが書き味はわかるかと。

※アップロードもダウンロードもコード的にはそこまで差がないので今回は省略

Reactのコード

```react

const UploadComponent: React.FunctionComponent<{}> = () => {
  const uploadFile = useUploadMutation()
  const inputEl = React.useRef(null)
  const onUpload = React.useCallback(
    e => {
      const [file] = e.target.files
      if (file) {
        uploadFile({
          variables: { file }
        },
        update: (_, { data }) => {
          if (data.uploadFile.success) {
            // 成功時
          }
        })
      }
    },
    [uploadImage]
  )
  return (
    <>
    <input ref={inputEl} id="file" type="file" onChange={onUpload} />
      <Button htmlFor="file">
        アップロード
      </Button>
    </>
  )
}
```

Vueのコード

```vue

<template>
  <div>
    <input id="file" type="file" v-on:change="onUpload" />
      <Button htmlFor="file">
        アップロード
      </Button>
  </div>
</template>

<script lang="ts">
import { Component, Prop, Vue, Emit } from "vue-property-decorator";

@Component
export default class UploadComponent extends Vue {
  public onUpload(e) {
    const [file] = e.target.files
    this.$apollo
      .mutate({
        mutation: UPLOAD_MUTATION,
        variables: {
          file
        }
      })
      .then(result => {
        // 成功時の処理
      })
      .catch(error => {
        alert(error);
      });
  }
}
</script>

```

若干Vueの方が冗長な感がありますね。ReactのHooksは書きやすい上に使いやすくロジックを書くにあたりReactの方が一歩進んでいます。
後述しますが、Vue3ではHooksのような機能も入るようなので、今後フロントエンドの主流になるはずです。


### 開発効率については甲乙つけがたい

開発効率についてはそこまでの差はないように思います。慣れの問題も大いにあるので。ただ、VSCodeの相性についてはReactの方が良いのでどちらも同じ熟練度であるのであればReactの方が効率は良さそう。




## TypeScriptとの相性

|  |React  |Vue  |
|---|:---|:---|
|厳密さ  | ◎<br>言うことなし。TSとの相性抜群 |△<br>TSサポートされているが、微妙なとこがちらほら。  |
|堅牢性  | ◎<br>言うことなし。TSとの相性抜群 | △<br>型定義が間違っていてもコンパイルが通ってしまう（エラーは表示される。）※私の設定がだめな可能性もある |

### Reactの圧勝

TypeScriptとの相性・親和性においてはReactの方が優っていると判断しました。

### VueのTSサポートについて

TSのサポートは微妙。Vueは手軽さとアバウトさが売りなのでしょうがないのかも。

- 型付けがやりにくい（子Componentの場合いちいちデコレータを書かなくてはいけない）
- 型定義が間違っていてもコンパイルが通ってしまう(スキーマ !== 型定義 の場合でもとりあえずコンパイルは通ってしまう？？)
- 子コンポーネントにpropsを渡す際に必須であれば `required: true` と定義するが、これは型定義で解決するべきことのはず。 


## GraphQLとの相性

どちらもスキーマとqueryとmutationを定義すれば型定義ファイルを生成することができます。

[GraphQL Code Generator · Generate code from your GraphQL schema with a single function call](https://graphql-code-generator.com/)


### Reactが優勢

実際にコードを書くとなるとそこまでの差はないですが、Vue自体がTSとの相性があまりよくないのでスキーマ + TSの恩恵があまり受けられないことが理由です。

またReactの場合はgeteratorのサポートが進んでいて、型定義だけではなくhooksまで生成してくれます。詳しくは以前私が書いた記事があるので参考までに。
[GraphQLでスキーマ駆動開発導入したら開発効率がアップするぞ！！ - Qiita](https://qiita.com/102Design/items/b95e2cbda18b48f32004#clientsrcgenactionsts)

## パフォーマンス面
|  |React  |Vue  |
|---|:---|:---|
|フレームレートの比較  | 19.7FPS | 9.4FPS |
|メモリ使用量  |55MB  |172MB  |
|ライブラリの容量  |122kb |94.9kb  |
|ライブラリの起動時間  |197ミリ秒  |263ミリ秒  |

仮想DOMの追加・更新・削除と仮想DOMから実DOMへの反映を検証サイトがあるのでご覧ください。明らかにVueが重いのがわかります。

- [React](https://ics-creative.github.io/160916_performance_js_framework/react-svg/build/index.html)
- [vue](https://ics-creative.github.io/160916_performance_js_framework/vue-svg/dist/index.html)

下記サイトで詳しく検証をしています。

[Vue・React・Angularのパフォーマンス比較検証 - ICS MEDIA](https://ics.media/entry/190731/)


### Reactの方が優勢

検証サイトでも書かれているように

```
- Reactが性能面で総合的に有利
- Vueは大量にコンポーネントを配置するような場面においては不利
```

以上の点からReactの方がパフォーマンスの面でマッチしています。

## 採用面・育成面
アジア圏では圧倒的にVueが多い。なので、採用面ではVueの方が有利です。

さらに私の勝手な分析だと

webデザイナーからフロントエンドエンジニアを目指す方 > vueの方が馴染みやすい
Haskellなど関数型プログラミングをしていた > reactの方が馴染みやすい

なので、デザイン面も見てもらいつつフロントエンドの開発もお願いするケースはVueの方が若干有利。


## Vueを使うべきケース

以上のことから本案件ではReactが好ましいと判断しています。が、Vueを使うケースももちろんあります。

### 手軽さ・いい意味でのアバウトさ

Vueの良さは `手軽さ・いい意味でのアバウトさ` に尽きるので、以下の場合においてハマるはず。

- アプリの一部分をSPA
- webコーダーが開発
- デザイナーとの協同が必須

アプリケーションの開発に慣れていないコーダーが開発をしたり、デザイナーがCSSを書くなど協同が必要な場合は文句なしにVueの方が良いです。ReactはCSSの記述にある程度スキルが必要なため純粋なデザイナーさんには対応するのに学習コストがかかります。

また、例えば記事の一覧だけなど部分的にSPAにするなどの場合はVueの方が開発コストが少なくできます。

さらにパフォーマンス & TSサポートが未熟なので管理画面でVueを使う場合にはある程度限定される印象です。

- ダッシュボードがない
- スキーマ駆動ではない


## とはいえVue3が公式リリースされれば・・・

### Composition API
Vue.3.0で導入されるコンポーネントを書くための新しいAPI。React Hookから影響を受けていて、以下の2点が大きく変わるようです。

1. TypeScriptの全面的サポート
2. ロジックの関心をベースにコードを構造化できるようになる

1によりかなりTypeSriptでの開発がスムーズかつ効率よくなるのではと期待されています。

2では
現状のOptions-based APIは
「このコンポーネントはdataを2つ持っていて、methodを3つ持っていて...」という書き方になり、コードが断片的になってしまいます。あるロジックを変更しようとした時、コンポーネントファイル中に散らばる関係各所に影響が出る可能性が高くなってしまいます。特に、コンポーネントが複雑になるほど変更しづらくなってしまう。

Composition APIでは、「このコンポーネントがしようとしていることは、X, YとZということです。」
という書き方ができるようになり、ロジックが何をしたいのかということをベースにコードを書けるようになるとのこと。

公式のRFCでは下の画像のようなイメージと説明されています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47844/3007f3b8-bdd4-d184-3a9c-880ccea55a93.png)




### 公式リリースについて

公式リリースはまだみたい `vue 3 will be available by the end of Q2.`
https://github.com/vue3/vue3-News

プラグインを使ってVue3の書き方をすることはできるようですが、プロダクトに入れるのは現状厳しいと判断。

## 所感

ReactとVueどちらも触ったことあるけど、ここまで深堀して検討比較したことないのでかなり勉強になった。

パフォーマンス面での差が結果として決め手になってしまったけど、そこを知れたのは大きい。とはいえVue3が公式リリースされたら結果が変わる可能性があります。Vue3に期待したい。