サーバサイド担当からクライアント技術者に転身する際の注意点
WebサイトはAjaxの大ブレイク以降、凝ったクライアント処理を作りこんでいるサイトがうんと増えてフロントエンドエンジニアという職業が生まれました。
スマートフォンのアプリやゲームの開発需要増加によってもクライアントサイドのエンジニア求人は増加しています。
「ずっとサーバサイドをやってたけど、クライアント側もやってみたいなぁ。でも、出来るかなぁ?」 という方も多いかと思います。
私はエンジニアキャリアの前半はずっとサーバサイドエンジニア(Java)をやっていました。
その後、AjaxやHTML5を使ったフロントエンド開発を経験し、今はスマートフォンのゲーム開発(Unity、C#)をやっています。
やってみて感じたのはクライアント側にはサーバサイドにはない難しさ、複雑さがあるということです。そしてもちろん面白さもありました。
そんな経験を踏まえて「サーバサイド技術者がクライアント技術者にコンバートする際の注意点」を紹介します。
Contents
1. 処理が始まるタイミングが一つじゃない
サーバの場合処理が始まるタイミングは一つでリクエストがあったらレスポンスを返すだけですが、クライアントの場合
- ボタンを押された時
- アニメーションが終わった時
- 通信が終わった時
- スクロールされた時
等、処理が始まるタイミングが複数あります。
2. 同期と非同期を使い分ける場面が多い
サーバの場合、通常はマルチスレッド・ブロッキングIO(同期IO)なので、基本的に同期処理になります。
同期処理はコードが上から下へ順番に実行されていくので分かりやすいのですが非同期処理は上から下へ実行していく過程で非同期な部分を読み飛ばして次の処理に行ってしまいます。
非同期な処理の結果が返ってきたところでコールバック関数が呼ばれるので、コードを読む際にどういう順番で実行されるかを強く意識する必要があります。
ブラウザ上で動かすJavaScriptやUnityでサーバー通信する場合も非同期IOです。
クライアント側って通信してる間も画面の描画を続けなければならないので非同期IOの方が都合がいいためです。
3. タイミングに依存するバグが多い
クライアントには処理が始まるタイミングが複数あり、非同期処理も多数使われるため、タイミングに依存するバグが多くなります。
「このバグ原因が分からないなぁ?」としばし頭を悩ませた結果、原因が「そっかぁ、ここが非同期だから、この処理が終わる前にここに来てしまうのかぁ」ということがよくあります。
しかも、この手のバグは原因が分かりずらいので厄介です。ちょっとしたタイミングの差で起きたり起きなかったりするので、解析が難しいんです。
4. 長い生存期間の変数が多い
クライアント側はサーバ側よりも状態を持つ変数が多いので、長い生存期間の変数が多くなります。
サーバの場合、状態はセッション属性かDBに持たせますが、クライアントの場合、メモリー上かファイルに持たせます(ほとんどはメモリーに持たせることが多い)。
それに、その状態の変化も(特にゲームの場合)激しく頻繁に更新し続けます。ですから、変数の状態に依存するバグも発生しやすくなります。
「変数のスコープ・生存期間は出来る限り小さくしましょう」というのはプログラミングの鉄則ですが、クライアントの場合、状態管理の必要性から長い生存期間の変数が多くなってしまうんです。
5. ロジックの結果を表示に反映させる必要がある
サーバのアウトプットはリクエスト属性やJSON項目にセットするだけですし、自分で項目名や構造を決められますが、クライアントのアウトプット先は画面なのでUIのAPIにアウトプットします。
UIのAPIを調べる必要がありますし、表示というものはタイミングにとても敏感なので、もう少し、ほんの0.3秒後に表示した方が良い等の細かい調整が必要となる場面が多くあります。
ロジック的には正しくても演出的にはNGという場合が多々あるんです。
6. 動作する端末のシステムリソースが小さい
サーバに比べるとクライアント端末のシステムリソースはとても小さくなります。
サーバの端末がサーバ用PCやワークステーションであるのに対し、クライアントの端末はスマホのアプリやブラウザだからです。
よって、CPUやメモリー等のシステムリソースの消費を出来るだけ小さくする工夫が必要になります。
特にメモリーリークでアプリが落ちるという現象が起きやすいのでとりわけメモリーの消費量には注意が必要です。
逆にサーバにあってクライアントにないものは?
1. 負荷分散、スケーラビリティ
負荷分散やスケーラビリティをクライアント側で考慮する必要はありません。
クライアントの端末を多重化するなんてことはあり得ないので負荷分散、スケーラビリティを考える必要はありません。
ただし、複数コアのCPUやGPUの処理効率を上げて性能を引き出す必要はあるので、並列処理の知識が必要になります。とはいえ、その辺はフレームワークやゲームエンジンなどのローレベルレイヤーのソフトウェアがやってくれるので、アプリケーション開発においては、そこまで意識しなくてもいいかもしれません。
2. DBアクセス
クライアント側ではファイルIOやSQLiteのような簡易DBアクセスはあるにせよ、リモートにある何100万件もレコードの入ってるDBに直接アクセスすることは通常ありません。
なので、DBのパフォーマンスを考えたSQLを書くスキルは必要ありません。
複雑でしんどい面もあるけど見た目が楽しいのがクライアントプログラム
サーバ側とクライアント側、両方をやってみた私個人の感想としては、クライアントプログラムの方がロジック的に難しいものが多い印象です。
やってて「しんどいなぁ」とか、「サーバサイドの方がシンプルで分かりやすかったなぁ」なんて思うことがよくあります。とはいえ、やってやれないほど難しいわけではありません。要は慣れの問題です。おそらくクライアントサイドのエンジニアがサーバーサイドに転身する場合も同じように難しさを感じるのだと思います。
両方やってみると、プログラミングに対する考え方も広がるので、エンジニアとして上を目指すという意味でも、とてもいいことです。
一番早くスキルを身につける方法は仕事でクライアントサイド担当になることです。
私の場合、初めは趣味でUnityを使ったゲーム開発をしていましたが、仕事でゲーム開発プロジェクトに入ってからのほうがずっと早く上達しました。
ですから、スキルアップのための転職というのはとてもいい選択だと思います。今なら、転職を支援する仕組みもたくさんあるので、気軽にトライしてみるといいと思います。