X(Twitter) Zenn GitHub RSS 共有

フロントエンドに触れてみた

作成日時:2022-07-16
更新日時:2022-07-16

1. 概要

2. Reactを触ってみる

Create React Appというツールチェインで楽にSPA向けの環境構築が出来るらしいのでやってみる。
その他ツールチェインなど:https://ja.reactjs.org/docs/create-a-new-react-app.html

  1. https://nodejs.org/ja/ からnodejsをダウンロード/インストール。
  2. 下記コマンド実行(パスが通ってなければ通す)
    ※コマンドに関してはnpm / yarn / pnpm好きなのに置き換えて。
    上記3種に関して→ https://zenn.dev/hibikine/articles/27621a7f95e761
## Create React Appをインストール
npm i create-react-app

## プロジェクト作成 暫く待つ
npx create-react-app (プロジェクト名)

## 開発用にサーバー立ててアプリを起動する。
cd (プロジェクト名)
npm start
  1. 勝手にブラウザが開いてテンプレートのReactアプリが立ち上がるはず。

不満

create-react-appがなんか遅い。ビルド / HMR / サーバー開始とか諸々遅すぎる。
Reactを勉強する気が失せてしまう。

3. Viteに移行する

Viteというのが上記不満点を色々解決してくれるらしいので導入してみた。
https://ja.vitejs.dev/

## viteをインストール
npm i vite

## create-react-appみたいに環境構築してくれる奴をインストール
npm i create-vite

## プロジェクト作成
npx create-vite

## ↑対話形式で下記の項目を設定
## 1.プロジェクト名
## 2.フレームワーク(vanilla / vue / react / preact / lit / svelte)
## 3.TypeScriptか否かなど

## 開発用にサーバー立ててアプリを起動する。
## エラーが出るなら内容に従って修正
## 多分 @vitejs/plugin-reactが無いとか言われるのでインストールしておく
cd (プロジェクト名)
npm run dev

・ビルド / HMR / サーバー起動、全て爆速である。二度とcreate-react-appは使わん。
・React以外のフレームワークのテンプレも作ってくれるのはありがたい。(SolidJSはまだ無い)

HMR

Hot Module Replacement
ソースを保存したら勝手にブラウザに変更を適用してくれる機能。
今まで変更するたびにF5を押す事しか知らなかったので、最近は便利になったなあと思った。

4. ReactでSPAを作ってみた

爆速開発環境を手に入れたので、何か作ってみた。

最近の不満点↓
・各種技術サイト(Qiita / Zen / etc…)内のブクマとブラウザのブクマがごちゃごちゃになってきた
・上記ブクマを技術内容で検索出来ない。

→なのでReactの練習がてら、これを解消するツールをSPAで作成した。

技術記事管理ツール

感想

詰まった点とか

RewriteEngine on
RewriteCond %{REQUEST_URI} ^/foo$ 
RewriteRule ^ / [L]

5. 自分のサイトを改修してみる

勉強がてら自分の運営しているサイトを最新のフロントエンドっぽく改修してみることにした。

変更前のサイト仕様

上記を改修していく

6. SSG

※SSGなどに関しては:https://qiita.com/thesugar/items/47ec3d243d00ddd0b4ed

全ページをhtmlにする。

Hugo / Next.js / GatsbyなどのSSGを使おうと思ったが、面倒くさくなったのでPHPでhtml出力ツールを作成。

全ページhtmlになったので
サイトへのアクセス時にPHPもDBも起動しないのでセキュリティ〇。
SEOや表示速度的も向上したと思われる。

が、似たような内容のhtmlファイルが2,000個もサーバー上に存在することが個人的に気に食わない + ストレージ容量圧迫させたくない。(+ React使いたい)
ので、SSGは止めてReact SPAに改修する。

※仕事だったらSSG / ISR / DSGにする。

7. Reactのファイルサイズ大きすぎだろ

そんなこんなで自分のサイトをReactのSPAで作り直した。
が、Lighthouseのスコアが下がった。

原因はJSのファイルサイズが大きすぎてロードに時間が掛かり、表示が遅くなったため。
確認してみると確かに大きすぎる。(数字は失念)

BUNDLEPHOBIAというサイトでバンドルのサイズをチェック出来るらしいので見てみた。
https://bundlephobia.com/package/react-dom@18.2.0

react-domだけで42KB。jQueryよりデカい。
create-viteを使って他のフレームワークを試してみたがここまでデカくはない。

minifier変えたところでそんなに変わらないだろうし
参考:minifierベンチマーク https://github.com/privatenumber/minification-benchmarks
参考:Viteビルド設定 https://ja.vitejs.dev/config/build-options.html

ejectして外出しにするのもその後が面倒くさそう
参考:https://kisalabo.com/2020/04/16/react-2/

訳があってCDNも使えないしどうすればいい

8. SolidJS

SolidJSに移行した。https://www.solidjs.com/
最終的なファイルサイズも小さくなるしパフォーマンスも向上するし良いことづくめ

ViteにおけるSolidJSのテンプレートの作成方法は公式に記載されている
https://github.com/solidjs/templates

上記で作成したテンプレートのビルド設定等を7で作成したReactのプロジェクトに転記し、ソースをSolidJSの記法に修正した。

ほぼほぼReactとSolidJSの記法は同じなので
・useXXX → createXXX
・className → class
など、文字の一括置換で容易に修正できた。(多少動かなくなった箇所はあったけども)

詰まった点

ReactとSolidJSの違いは?

知らん。下記参照

9. DBデータを全部SPAに突っ込む(愚行1)

SolidJSへの移行が完了し、Lighthouseのスコアも上がった。
が、更なる速度向上をしてみたくなった。

現在のページ表示の流れを見てみる。(SPA)

  1. クライアント:サーバーに情報要求
  2. サーバー:DBから表示する表示情報取得
  3. サーバー:クライアントにJSONで表示情報返却
  4. クライアント:表示情報を画面に反映

これもうDBのデータを全部JSONにしてSPAに埋め込めば1~3の処理が消えるから速くなるよね。PHPもDBも不要になるからセキュリティ的にも〇のはず。

やってみた→Lighthouseのスコアが下がった。

ファイルサイズが爆増するから当たり前である。

なので下記の対応をした。

結果

Lighthouse満点達成

開発者ツールでスロットリングを低速3Gにしてもサクサク閲覧できるようになった。
DBもPHPも使用しなくなったのでセキュリティ〇。
速度も向上。

10. Rust_WebAssembly (愚行2)

もっとファイルサイズを小さくできないか?
→独自のバイナリフォーマットを作れば小さくできるのでは?

データ内におけるマンガの表示ページ数情報を例に考えてみる。

// JSONだと12Byte(= 96bit)
"page":"30",

// 独自バイナリフォーマットにする
// 冗長なので 1Byteを 1話分のページ数とする
00011110

// まだ冗長なのでページ情報を5bitで表現させる(31を超えることはないため)
11110

5 bit / 96 bit = 5.2%
さらにgzip圧縮もあるのでかなり小さくなった。

ちょうどWebAssembly(wasm) に興味を持っていたし、バイナリ読み込み処理をwasmで実装する。

WebAssembly

https://developer.mozilla.org/ja/docs/WebAssembly
上記サイト引用

WebAssemblyはウェブプラットフォームに大きな影響を与えます — 以前ではできなかったようなウェブ上で動作するクライアントアプリケーションのために、複数の言語で記述されたコードをウェブ上でネイティブに近いスピードで実行する方法を提供します。

大雑把に言うとブラウザ上でバイナリコード動かして爆速にする。
色々と使われている。

下記サイトを参考に実装してみた。(言語はRustを使用)
https://dev.classmethod.jp/articles/rust-webassembly-javascript/

wasmへのバイナリデータ埋め込みは自作したRust用のxxd -iコマンドみたいなツールを利用して埋め込む。

ビルドを行うとTypeScript用の型定義ファイルが出てくるので、TypeScript使ってるならそれを読み込む。

ビルドサイズが大きい場合は最適化オプションを設定する。
https://zenn.dev/dozo/articles/14b76b561f3b45

結果、ファイルサイズの縮小と若干の速度向上は出来たけれども、
下記の点が問題なのでおとなしくJSON埋め込みverに戻した。

愚行だった点

まだ試してないけどもZig使ってwasm書いたらどうなるんだろう。変わらんか
https://ziglang.org/ja/

※念のため記載するが、wasm上に見られたら困るようなデータを埋め込むな。JSと同じで基本全部参照可能
https://i-407.com/blog/m7/

11. まとめ

雑多に記載していったので特にまとめとかは無い。
各技術における個人的な感想とか考えを記載していく。

SolidJS

wasm

Rust

最近勉強しようかなと思っている言語

Wiki
公式

と、色々良さげっぽい

以上

(おまけ) 個人的に体感したwasmによるパフォーマンス向上事例

この間、OpenCV (https://opencv.org/) + Pythonで画像解析をするWEBアプリを作成したがサーバーが貧弱な為、異常に処理が遅い。

そこでOpenCV.js (wasmで動くOpenCV) を使ってクライアントで画像解析処理を行わせることにした。
OpenCV.js:https://docs.opencv.org/4.x/d5/d10/tutorial_js_root.html

結果として爆速で動くようになった。
それも当たり前で、画像のアップロード / ダウンロードの時間も消えて画像解析は貧弱サーバーではなくクライアントで行うのだから。

旧:画像アップロード(遅) → 画像解析(遅。複数リクエストが来たら死) → 解析/変換した画像返却(遅)
新:クライアント内で完結

重い処理をクライアントでやらせればサーバー負荷(またはLambda起動)が掛からんし、クラウド料金とかを安くできそう。

ただwasmファイル自体が重いので初回ロードに時間が掛かるのデメリットか。
(CDNとか使えばまあ若干改善できるし、2回目以降はキャッシュ使うから大した問題ではないか)