NODE_OPTIONS="--trace-warnings"
をつけて run すれば OK
$ NODE_OPTIONS="--trace-warnings" npm run lint
以上。
NODE_OPTIONS="--trace-warnings"
をつけて run すれば OK
$ NODE_OPTIONS="--trace-warnings" npm run lint
以上。
いちいち「Alexa、リビングの電気をつけて」みたいに言うの、かったるくないですか?僕は仕事で使ってるMacの充電器をスマートプラグで管理してるので、いちいち「Alexa、充電つけて」と言わないと充電ができません。これが地味に面倒だったので、スマホのホーム画面から家電のオンオフを操作できるようにしました。
大雑把な方針は、まずルーチンを作成して、そのショートカットをホーム画面に追加する。これで、ホーム画面から1タップで家電を操作できる。
まずルーチンの作成について。
↑Google home を起動するとこういう画面のはず。ルーチンを選択する。
ルーチン一覧の下に追加ボタンがあるのでタップする。
開始条件は「音声コマンド」を選択して任意のフレーズを入れる。あとはアクションを設定して保存する。
AOS であればルーチンのショートカットをホーム画面に追加できる。
iOS はもう一工夫いるので、iOSについてのみ解説する。
まず「ショートカットアプリ」をインストールして起動する。そしてショートカット追加ボタンをタップする。
↑するとこのような画面になる。この画面でまず「アクションを追加」をタップして「Googleで調べる」コマンドを追加する。question のところにルーチン作成時に設定したフレーズを入れる。
これで準備完了なので、あとはホーム画面に追加すればOK。
↑共有メニューにホーム画面に追加という項目がある。
ちなみに、ショートカットのウィジェットからも操作可能。僕はこっちを使ってる。
結論: iPad は4本指で上にスワイプするとホーム画面に戻る便利機能があります。これをブラウザで行うと touchstart → touchmove → touchcancel の順で発火します。 touchend が永遠に発火しません。
結論で言いたいことは完結してるので、以下はその補足説明です。
iPad で4本指まとめて上へスワイプすると、ホームへ戻るかマルチタスク画面を開けます。これがすごく便利で毎日100回くらいやってます。マジです。
4本指以外にも3本指のジェスチャもたくさんあります。さて、もうお分かりかと思いますが、iPad に対応するにはマルチタップ前提でアプリを作る必要があります。
4本指でスワイプしようとすると、touchstartがまず発火します。次にtouchmoveが発火します。最後にtouchcancelが発火して終了です。 touchendは呼ばれません。
touchstart イベントは3本分がまとめて1回で発火したりします。touchcancel は1回で4本分すべてキャンセルされます。何度か試してみましたがいずれも touchcancel は1回だけでした。
というわけで、touchcancel イベントは iPad に対応する場合は必ず設定しましょう、という話でした。
今回、これを検証するにあたって touch event をログ表示する簡易ページを作りました。実際に試してみてください。
タイトルの通りです。React の再レンダリングを介さずにDOMを直接更新する方が高FPSを出せるか実験してみたけど、そんなに変わらなかったという話です。
ストップウォッチを作っていて、こんな感じの ControlledComponent を書いていました。とてもオーソドックスなコードです。
type TimerState = 'idoling' | 'working'; // ControlledStopwatch は prop で受け取った情報を描画するだけ。内部にステートを持たない const ControlledStopwatch: FC<{ onStart: (startAt: number) => void; onFinish: (endAt: number) => void; currentTime: number | null; state: TimerState; }> = ({ onStart, onFinish, state, currentTime }) => { return ( <div> {state === 'idoling' ? ( <button onClick={() => onStart(performance.now())}>start</button> ) : ( <button onClick={() => onFinish(performance.now())}>stop</button> )} {currentTime && <div>{currentTime / 1000} seconds</div>} </div> ); }; const Controlled: FC = () => { const [state, setState] = useState<TimerState>('idoling'); const startAt = useRef(0); const [currentTime, setCurrentTime] = useState<number | null>(null); const fps = 120; useEffect(() => { if (state === 'working') { // 1000/fps ミリ秒ごとに表示を更新する const id = setInterval(() => { setCurrentTime(performance.now() - startAt.current); }, 1000 / fps); return () => clearInterval(id); } }, [fps, state]); return ( <div className='App'> <ControlledStopwatch currentTime={currentTime} state={state} onStart={(val: number) => { setState('working'); startAt.current = val; }} onFinish={(endAt: number) => { setState('idoling'); console.log(endAt - startAt.current); }} /> </div> ); };
このストップウォッチは、1000/fps ミリ秒ごとに setCurrentTime を行い、React の再レンダリングをしています。しかし、書き換えるべき箇所は時刻の部分のみです。ならば 再レンダリングはややコストが高いのでは? と思ったのが検証しようと思ったきっかけです。
UncontrolledComponent は state をコンポーネント内部で持っている(親がステートをコントロールできない)コンポーネントです。一見すると親でステートを持てないのはデメリットにしか見えませんが、逆にいえば 「親がステートを管理しなくていい」コンポーネント です。
親は子のレンダリングに関して一切の責任を負わないため、再レンダリングせずに直接 DOM を更新して書き換えても問題ありません。そのため、高FPSが求められる作業に向いていそうに思いました。結論をいうと大差なかったんですが。
というわけで書き直したデモがこちらになります。
結果は上のデモをみてわかる通り、 目でみてわかるレベルの差はありませんでした 。60fpsで録画して確認してみたところ、どちらも60fps以上はバッチリ出ていたので、差を視認するのはかなり難しいはずです。
というわけで、 高いFPSを求めて UncontrolledComponent に書き直すのはそんなに意味なさそう という検証でした。
テレワークが始まり、コミュニケーションの主流は対面でのMTGではなくslackへと移行しつつあります。そこで感じたテキストベースコミュニケーションの良さと課題感を書きます。
まず、テキストとして残る。これが大きいです。コミュニケーションの証拠がしっかりと残るため、あとから見返したり検索したりできます。
例えば「あれ、〇〇さんに〇〇の件って伝えたっけ?」となったら検索すれば確認できるので楽です。
次に、非同期という点です。「とりあえずslackで投げたから返信待つ間に別のことやろう」というふうに、コミュニケーション以外の仕事と並行してできます。もちろんすぐに返信が欲しい場合はマズイですが、実際には緊急のタスクは少ないので問題になりづらいです。
最後に、テキストに起こすことでより相手に伝えやすくなります。自分の考えの整理にも繋がりますし、口頭でコミュニケーションを取るより、整理した上でわかりやすく説明できるはずです。
もちろん課題もいくつかあります。
まず、各々のタイピング速度に依存してしまうこと。タイピング速度が遅いとそれだけ返信に時間がかかりますし、文章の推敲をするような余裕が生まれづらいです。しかし、全員のタイピング速度を上げるよう強要するなんてできません。口頭と比べてレスポンスの速さが各人に依存してしまうのは課題です。
また、非同期であるという点は課題でもあります。特に緊急の時やステークホルダーが多い時はMTGを開いたほうが早い場合が多いです。
これはやや違うのですが、テキストベースの利点の一つとしてパブリックな場で発信できるというものもあります。これにより、会話に参加してない人もログを追ったりできます。しかし、クローズドな場所で連絡してるとこの利点を享受できません。僕は発言の99%をパブリックな場で行って極力DMを使ってないのでよいですが、他の人もそうとは限りません。
僕はテキストベースの方がトータル早くてエビデンスも残せるので、口頭より如実に優れていると思っています。