SPAで技術ネタをまとめるサイトを作ってみた

#関連リンク
###　ソースコード
　　　[https://github.com/mofon001/TreeTypeInfomationService](https://github.com/mofon001/TreeTypeInfomationService)
###　実運用サイト
　　　[https://croud.jp/](https://croud.jp/)

※2019/07/06追記
　現在、バックエンドをPHPからNode.jsに置き換え、
　全てTypeScriptで作り直したものを以下のサイトで公開しています。
　　[https://ttis.croud.jp/](https://ttis.croud.jp/)


#動作画面
![IITS1.gif](https://qiita-image-store.s3.amazonaws.com/0/267629/c54e6def-2982-7dba-e8b5-19ca70c4ff21.gif)
![IITS2.gif](https://qiita-image-store.s3.amazonaws.com/0/267629/83e1c7a5-fbd3-8374-3d76-430643cf7394.gif)


#SPAとツリー型システム
###　Single Page Application(SPA)でのシステム構築

　Web上に様々な記事を掲載するにあたって、使いやすいシステムが欲しい。しかしWordPressのようなシステムは私には性に合わなかった。理由としては編集ページした内容を確認するのに、いちいちページが切り替わるからだ。私の心には、猫の額ほどのゆとりすら存在しない。もしかしたらノミの心臓よりもゆとりの領域は狭いのかもしれない。

　そんな私にとって自分として使いにくい物を無理に使うよりも、無いものは作ろうという日曜大工的な発想になるのである。作る上で必須なのはページ切り替えを行わないWebアプリケーション、つまりSPAでのシステム構築が必要となる。

###　ツリー型

　技術系の情報を掲載するシステムを作るにあたっての必須条件、項目をツリー型で表示することである。目的地までページ上のリンクをひたすらクリックしていくシステムは避けたいのだ。パンくずリストがあったとしても、方向音痴の私では、富士の樹海に迷い込んだかのような状況になるのが目に見えているからだ。整頓されたツリー構造、これが私が必要とするGPSなのだ。


#開発環境

###　テスト環境
**Google Compute Engine (GCE) + CentOS7**
　もはやローカルでちまちまテストなどしない
　テスト専用のVPSを使い、本サイトと同じ構成で開発を行う

###　開発言語
**PHP 7.2**
　今更PHPと思うかもしれない
　私もそう思う
　ぶっちゃけアプリケーションサーバは何でも良い
　SPAのシステムを作るに当たって、その存在は重要ではないからだ
　以前似たようなシステムを作ったときはC++で書いたり、Javaで書いたりした
　だからRubyだろうがPythonだろうが、DBに接続する能力を持っていれば何でもかまわない
　ただしJavaは言語仕様的にJsonと相性が悪いので、あまりお勧めできない

**PostgreSQL 10.5**
　むやみにPostgreSQLのバージョンが高いのはそれほど意味を持たない
　入れたのはただそこにあったからだ
　DBもデータさえ格納できればSQLiteでもかまわない
　というか、PostgreSQLに接続する認証情報はSQLiteで管理している
　これは初期設定でPHPのソースを直接いじる自体を避けるためだ

**JavaScript**
　Webアプリケーションを作るなら・・・避けて通れないこともない存在
　しかしSPAのシステムを組む上では必須となる
　PHPのコードを打っている時間よりも、JavaScriptをゴリゴリ書いている時間の方が長いのだ

###　開発環境
**VisualStudioCode**
　頻繁にバージョンアップを繰り返し、日増しに機能が増えていく恐ろしい子だ
　Web開発においては、完全に本家の存在を脅かしている
　Sambaを使用し、VPS上のファイルを直接編集する形で開発を行っているためデプロイの手間はゼロだ
　sshのポートフォワードと組み合わせれば、サーバ上でもxdebugがそのまま使用できる

#いざ開発
###　とにかくJavaScript
　SPAでの開発ではJavaScriptを扱えない人間は門前払いである
　一応JavaScript用のフレームワークは各所に存在するが、私の考え方とは設計思想が根本的に異なるため、結局全部自分で書いた

　私が必要としているのはブラウザで動く仮想ウインドウシステムであって、出力体裁を整えてくれたり、ビューの切り替えを一定の手順で縛る物ではない
　各種コンポーネントをウインドウという単位で生成し、位置やサイズが可変のフレームウインドウとして表示したり、領域を分けるためのセパレート上に張り付いて、サイズを自動計算してくれる、そんな物が必要なのだ。
　そして仮想ウインドウという単位にまとめることによって、機能ごとにソースを分割することが出来る。ツリー表示、メインコンテンツの表示、編集画面、設定画面など、明確に分離して開発するのとが可能なのだ。

###　御用聞き、PHPの役割
　SPAにおいてMVCでいうところのモデルの大部分がJavaScript側に露出することになる。ほとんどの状態制御はJavaScriptが担当することになる。逆にサーバ側であるPHPが担当するのは、権限を判定し適切なデータの入出力のみ行えば良いのである。今、クライアントの画面に何が表示されているかなど、全く知る必要はないのだ。だからPHPの有名どころのフレームワークは一切合切役に立たない。使うだけ邪魔にしかならないのである。

###　Ajax
　ほとんどの処理がJavaScriptで行われはするけれど、データはサーバに取りに行かなければならない。そこで使われるのはAjaxだ。ただしAjaxを生のまま使うのはお勧めできない。jqueryでも使えば良いのかというと、そういう話ではない。

　JavaScriptとPHPで情報をやりとりする際に、高レベルプロトコルを一つ用意する。コマンドとデータのやりとりに規約を設けるのだ。そうすることによって、連携させる部分を書く負担を減らすことができる。また、一定時間内に発生した処理要求をキューイングする機構を設ければ、複数通信が発生していたところを一つにまとめることが出来るのだ。今回はそういう機能も搭載してみた。

#ライブラリの蓄積
　JavaScriptによるウインドウシステム
　JavaScriptとPHPを連携させる高レベルAjaxアダプタ
　JavaScriptとPHPのセッション・ユーザ管理

　などなどが増えてきたので、新しいシステムを組む場合もかなり時短が出来るはずだ

#出来上がった物の機能

###　ツリー構造編集機能
　ツリービュー上で兄弟や子コンテンツを新規作成できる
　カーソルが乗ると表示されるボタンによって、表示順序を自由に変更できる
　ツリーアイテムのドラッグドロップによって、アイテムを別の場所へ移動させることも出来る

###　インポート/エクスポート機能
　コンテンツをファイルに一括・部分入出力が出来る
　出力データはjson形式で、画像などのバイナリデータも一緒に保存される

###　フレームウインドウによる編集
　コンテンツの編集はポップアップされる仮想フレームウインドウで行う
　リッチテキスト編集とHTMLデータの両建てで、好きな形で編集できる
　プレビュー確認は本番コンテンツと同じ場所に表示される
　画像はコピペでもファイルのドラッグドロップでも自動的にサーバに保存され表示用リンクが生成される

###　サーチエンジン対策
　残念ながらGoogleのボットはこのシステムのJavaScriptを理解してくれなかった
　まったくの分からず屋だ
　仕方がないのでボット用の静的HTMLの吐き出しに対応した
　パンくずリスト付きである
　もちろんサイトマップも付けてある豪華特典付きだ

###　ブラウザの進む戻る
　SPAページは履歴を適切に管理しないと、一つ前の項目に戻ろうと戻るボタンで別サイトに吹っ飛ばされる
　もちろんそうならないように対策済みだ
　リロードボタンを押した場合の処理も対策済みである

#動作速度
　画像が6個配置されているページを読み込んだ場合の結果
　アイコン系の画像もいくつか読み込んでおり、Googleアナリティクスも動作させている
　nginxでhttp2の転送高速化は有効になっており、コンテンツのgzip圧縮は画像以外すべてに適用している
　使っているサーバはGCEのf1-micro(共有vCPUx1 メモリ0.6GB HDD10GB)という貧弱極まりないワンコイン格安構成だ

###　ページ更新時(キャッシュを利用しない強制更新)
　237msで画像の読み込みまで完了している
![image.png](https://qiita-image-store.s3.amazonaws.com/0/267629/2e11ab24-c691-edde-faef-9ebce5784e4b.png)


###　コンテンツ切り替え時
　これも画像のキャッシュをクリアした状態で読み込んでいる
　切り替え時の数値データが出ないが、グラフを見ると121ms程度だ
　画像がないページなら28msで表示を完了する
　これだけのレスポンスが出ていれば、遅いと感じることはまず無いだろう
![image.png](https://qiita-image-store.s3.amazonaws.com/0/267629/112e4f7c-8581-a977-a7eb-aa614aeb1e10.png)

#まとめ

　私は車輪の再発明を旨として開発を行っている
　しかし困ったことに再発明の前提条件である車輪が少なすぎるのだ
　「もっと車輪をよこせ」声を大にしてそう言いたい

　そして気がついてしまった
　こんな物を作っている間に、今日は盆休み最終日だったのだ