やまろぐはてな

yamanokuの技術メモ。Qiitaは怖くて書けない。

Promise処理について雑にまとめる

Promiseとは

簡単に言うと非同期処理を行う時にコールバック地獄、ネストの深層化を回避して記述をだいぶ楽にするオブジェクト。ES2015です。

非同期処理とは

例えばAの処理の後にBの処理があるとする。javascriptとはシングルスレッドで動く同時に処理を行うということができないものなので、通常であればA、Bの処理で動く。その辺の順番を変えて処理を行うのを非同期処理という。

分かりやすい例はApiと連携するAjax通信を受け取ったレスポンス(200とか404とか)の結果によって処理を行うやつ。

非同期処理の例

例 – ajax通信後順番に処理を行う

var fetchSomething1 = function(done) {
  // API1にアクセス
  doAjaxStuff(someOptions, {
    success: function(data) {
      done(); // 成功したら渡されたfunctionを実行
    }
  });
};

// fetchSomething1と同じようにそれぞれ別のAPIにアクセスするfunction群
var fetchSomething2 = function(done) { /* 省略 */ };
var fetchSomething3 = function(done) { /* 省略 */ };
var fetchSomething4 = function(done) { /* 省略 */ };

var doSomethingFinally = function() {
  // APIにアクセスして取得してきたデータを使って何かする
};

こういう関数を登録しておき、順番に処理を行うとする。通常だと

fetchSomething1(function() {
  fetchSomething2(function() {
    fetchSomething3(function() {
      fetchSomething4(doSomethingFinally);
    });
  });
});

こうなるが、これが

fetchSomething1()
  .then(fetchSomething2)
  .then(fetchSomething3)
  .then(fetchSomething4)
  .then(doSomethingFinally);

こうなる。コールバック地獄、ネスト深層化問題の回避がよく分かる。

// Callback
fetchSomething1(function() {
  fetchSomething2(function() {
    fetchSomething3(function() {
      fetchSomething4(doSomethingFinally, function() {
        // fetchSomething4のエラー処理
      });
    }, function() {
      // fetchSomething3のエラー処理
    });
  }, function() {
    // fetchSomething2のエラー処理
  });
}, function() {
  // fetchSomething1のエラー処理
});

// Promise then & catch
fetchSomething1()
  .then(fetchSomething2)
  .catch(/* fetchSomething1のエラー処理 */);
  .then(fetchSomething3)
  .catch(/* fetchSomething2のエラー処理 */);
  .then(fetchSomething4)
  .catch(/* fetchSomething3のエラー処理 */);
  .then(doSomethingFinally)
  .catch(/* fetchSomething4のエラー処理 */);

エラー処理も含めると更に分かりやすくなる。こういう風に書くと見やすくなってメンテナンス性も上がりますね。

ブラウザ対応状況 – CanIUse

f:id:cardboarder:20170528175745p:plain

発表されてからだいぶ時間が経ったのでブラウザ対応であれば、現状IE11以外だったら大丈夫。

パフォーマンス対決

jsPrefにて計測。

Promise vs Callback

f:id:cardboarder:20170528202919p:plain

Native Promise vs Callback

f:id:cardboarder:20170528202638p:plain

非同期処理だとそこまで差はないけどそのまま使うPromiseだと圧倒的にCallbackのがパフォーマンス良い。素で使わないほうがよさそう。

おまけ – Promise と async/await のイメージについて

このGifが一番イメージしやすい。

参考

javascript無効にしたときのユーザビリティとかについて

社内で話した内容で気づけてよかったことなのでまとめてみる。自戒も込めてます。

  • 最近はjavascript無効な環境とかに対して優しくする意識はないのではないか
    • SPAとかなんかjavascriptあり気なんだしでかいFlash1つ置いててiPhoneで見る場合のと同義っぽい(※SPAをdisってる訳ではない)
  • javascriptでガッチリ組みすぎてるのもアレだけど、とはいえ今のレイアウトはjavascriptありきのものばかりだよね
  • そうなるとjavascriptが動作してなくて崩れてたとしても情報はちゃんと見せてあげたい
  • リッチな表現はjavascriptにのみ任せて、それ以外の基本動作は抜きでもちゃんと機能するようにしたい
  • 以下例みたいな考え方をスタンダードにしたい
    • アコーディオンは通常時は出しておき、javascript読み込みで非表示にする
    • ローディングとかを入れる時、ローディング自体をすでに出しておきsetTimeOutで消えるみたいな処理にしない(消えなくなる)
    • Googleとかのウェブフォントも極力js読み込みなどを避ける
    • javascriptで動作しないと表示しないテキストをやめる(重要なやつだと特に)
      • text()とかで出来る限り入れない・表示非表示で切り替える。
    • formのバリデーションはブラウザのバリデーションも意識してやる(最低限required付けるとか)
    • WAI-ARIAについても考えておく必要はある
    • javascriptバリバリ使っているサイトだったら最低限の礼儀としてnoscriptタグをちゃんと使おう

結局のところマークアップなりの時点でHTMLの構造をしっかり作れという感じなのですが、デザインでもjavascript使えて当然なリッチなものも多いのでその辺意識しないと結構大変だなと思うようになってます。

まあ結局ケースバイケースでjavascriptやれる部分はjavascriptでやるという部分はやっておき、万一のことはnoscriptなりできっちり表示しといたほうがいいよなと感じます。

というか最近フロントエンド界隈でのフレームワークだのビルドツールだのどうだこうだの話もありますが、まずは根本の話をしませんか、という気持ちがあります。こちらからは以上です。

参考

website-usability.info www.webprofessional.jp

最近考えてる「使いまわせるCSS」について

色々設計思想がありますが

結局のところ、しっかりと定まった案件だったはずが、どこかで「アレがほしいコレがほしい」という継ぎ足しが発生して設計が崩れ去るみたいなことはザラにあるようなので、CSSに期待するということ自体もはや間違ってることなのかもしれない。なので自分はCSSを書く時に極力無駄に広げないようにしている。

個人的に考える使いまわせるやつ

自分の中で考えた方法としては、コンポーネント単位というよりもFLOCSSのUtilitiesみたいなものを用意しておいて必要なものを補填していく、というやり方。以下は例。

1. 要素間の空き・余白について

marginなりpaddingなりがあると思いますが、以下みたいなので調整すればいいんじゃないのかなと思ってる

.mt-10 { margin-top: 10px;}
.mt-100 { margin-top: 100px;}
.pt-10 { padding-top: 10px;}
.pt-100 { padding-top: 100px;}

空きとか余白がある要素にいちいちクラス付与させんのかよ頭おかしいんか?と思われそうだけど、逆にこうした方が急に要素の空きや余白に変動があったときにでも対応できるし、誰が見ても分かりやすいんじゃないかと思う。

2. Modifierについて

btnという要素があってそれの幅が狭い・普通・広いバージョンを作る際にsmallとかdefaultとかlargeとかつけると思うけど逆にその間をものを作る時、命名に困るなどはあると思う(small-x?large-s?とか)。そのくらいだったら以下みたいにいさぎよく設定したい。

.btn-w200 {
 max-width: 200px;
}

もし幅可変のbtnを作るんだったらdisplay: inline-blockみたいに作ってpaddingで横余白とかで調整するというのがあればいいんじゃないだろうか。

3. レイアウトに関しては大枠を作っておく

flexレイアウトにしろclearfixレイアウトにしろ、中にどれくらいの大きさが入っても安心できる外枠をつくるべきかな。clearfixはなんだかんだで愛用できるものだし、flexに関しては基本以下設定でいいんじゃないのかな。あとは中の子要素で調整。

.container {
  display: -webkit-flex;
  display: flex;
  -webkit-flex-wrap: nowrap;
  flex-wrap: nowrap;
  -webkit-align-items: stretch;
  align-items: stretch;
}

IE11のmin-heightバグ問題とかは各自なんとかしてください。

4.命名に困ったときに関して

たとえば似たような色があって機能もそこまで大した差異がないものを命名する時、ECSSのようにそのページのみにしか存在しないものとして作るのが良いかもしれない。黄色系統でも濃いのと薄いのが存在した場合はyellow-01とかyellow-02とかやらない。

.color--works { /* 制作ページでしか使わないカラー */ }
.color--mypage { /* マイページでしか使わないカラー */ }

こういう設計ってそもそもあるんかな

webnaut.jp と思ったらやりたいがほぼ一致しているのがここに書いてた。FLOU設計というそうです。

厳密に言えば僕のはclassの作り方・もたせ方をどうするかーみたいなことなんですけども。

結論

本当はこんなことしてないでスタイルガイドを確立させてそこにモノを落とし込むやり方が100倍良いと思う。お前らはもう少しスタイルガイドに対して意識した方がいい。

実例とか示せればいいかなとも思うのでネタがまとまったらまた何か更新します。こちらからは以上になります。

フロントエンドエンジニアってどんな生き物なのか

f:id:cardboarder:20170226213138j:plain

こないだ他業種(SE)の人と偶然呑む機会があって、自分の同僚が「MEをやってます」って伝えたんだけど「MEってなんですか?」と返されました。

弊社ではマークアップエンジニア=MarkupEngineerの頭文字からそれぞれとってMEと略されて「MEチームの皆さんは何か有りますか」などと聞かれている。この辺は独自文化っぽいので分からなくて当然かなとは思いました。

と「マークアップ」の話をしてみても結局何をやってるのかと聞かれてしまいフロントエンドとバックエンドという部類があって、前者から枝分かれしているのがマークアップエンジニアことMEです、みたいに説明しました。(以下引用)

  1. バックエンドエンジニアとは、単一の環境、つまりサーバ上で仕事をする人のことを指します。彼らは、新しいソフトウェアをインストールしたり、ハードウェアをアップグレードしたりするなど、環境を変更する権限を持ちます。
  2. フロントエンドエンジニアとは、全く異なる数えきれないほどの環境で仕事をする人のことを指します。最新のデスクトップコンピュータから3年落ちのものだったり、メモリが少なく処理に時間がかかるような古い電話だったりと様々です。彼らは、ユーザのブラウザに対して何もすることができないため、その環境を変更することができません。それでも、すべての環境で動作するコードを作る必要があります。

http://postd.cc/front-end-and-back-end

この辺は同じエンジニアという分類で括ってあげることでだいたい理解してくれましたが、たとえば親のような仕事でもパソコンに触れる機会が全くない人間にどう伝えるか、というのが最近悩ましいということがあります。(めんどくさいのでwebサイトを作る仕事やっていますと伝えてます。そんなもんじゃないでしょうか)

いわゆるフロントエンドエンジニアって範囲が広義すぎるから何をもってして従事できているのかが正直分からんのが実際のところで、明確な身分証明みたいなものも免許みたいなものもないので人に説明するのはなんか難しいねという感じです。

あと人によっては見栄などで大した技術もないのにプロのエンジニアですみたいに経歴詐称したりする世界らしいのでそのへんも厳しいです。

逆に言えば自分たちの業種からみたシステム、インフラ、バックエンド側って具体的にどういう仕事してるんだみたいに思う人間が多いんじゃないかとは思う(そもそもデザイナーの業務もあまり分かってないというのはあると思う)。歩み寄りをすることを怠ってはいけないなとは感じます。

久々の更新でしたが特にオチはないです。写真には特に意味はないと思います。

初心者にGit教える時に必要最低限のCUIコマンド

f:id:cardboarder:20170116221632p:plain

前提条件

ガチ初心者でgitの操作をCUIで学ぶため、基本1人でmasterで作業するという「いやお前それGit管理じゃないだろそれ」という前提でやってもらます。いいんだよ細かいのはこれから学んでいけば。

作業前にリポジトリとかはどこかで作って置いたほうがよい(Github、Bitbucket、backlogなど)。

必要なコマンド群

リポジトリのクローン ... gitを使う設定

git clone https://xxxxxxxx/xxxx.git

※この時もしかしたらログインIDやパスワード聞かれるかもだが、気にせず入力してください

作業ファイル全追加 ... 作業したファイルを保存

git add -A

コミットメッセージ ... 何の作業をしたかの記録

git commit -m "commit message"

プッシュ ... サーバーにアップする

git push

プル ... 人が作業した分を同期・ダウンロード

git pull

右のはあくまでもそうした意味ではなく、イメージ。だいたいこれで足りる。自分は足りた。

cloneした後に「作業 → add → commit → push」を基本ローテーションとして作業。

必要に応じて他の初心者を入れて同様に作業させて、pullを理解してもらう。コンフリクト起こしたら、その時は都度修正、コミットなどしてくれ。

基本の骨組みはこのイメージでいいのではないか

実際Gitは様々なコマンドがあったりフローが存在して、いわゆる「ちゃんと理解できたらちゃんと使える」代物とも言われてるので、使いこなすにはある程度知識や経験が伴う。

とはいえ自分がやってきた中では基本このイメージさえできていれば、後はそれに付随する肉付きをしていけばいいんじゃないかと思っている。

たとえば作業でpushまでしたけど実は違ったものが最新になっていたのでそれを直すというのがあった際に、上記コマンドであれば作業後に再びadd、commit、pushなどをする一連の流れがあるわけだが、そのままだと煩雑なコミットログになりかねない(別に慣れる間であれば気にしなくて良いのだが)

そのためにgit revertだったりresetだったりcheckoutというコマンドが調べて出てくるのだが、そうした時に学んでいけばいいんじゃないかとは思う。

それなりに親切なGit

あとGitは丁寧なので、たとえば新しくブランチを切って作業して何も考えずadd、commitしてpushすると「リモートにそんな追従ブランチねーよ」と教えてくれて以下のコマンドを提示してくれます。

git push --set-upstream origin branch

アメリカ語だけど頑張って訳せばそれなりにちゃんと教えてくれてるんだというのがわかる。なので極端に怖がらなくてよいのだ。

極端な言い方をさせてもらえば、やり方次第でなんとかなるのがGitである。

Git教育について知見が欲しい

ウチではこうやってるよ的なのを募集しています。

こちらからは以上です