フロントエンドカンファレンス福岡2019
https://gyazo.com/545b6bdc22476e47d0deda020d050fbc
HTML Optimization for Web Performance
なぜHTML最適化なのか?
最初のレンダリングに最適化されてないと表示のされ方がかわってくる
The origin of subresources
Independent of web page type
パフォーマンスのボトムアップができる
Easy to optimize relatively
比較的最適化しやすい要素
3 steps for HTML Optimization
プロセス順
Download HTML from requested URL
Parse HTML to construct DOM tree
HTML will be evaluated from the top
Load subresources
<link>
<script>
<img>
<iframe>
etc…
CSSは非同期的
JSは同期的
レンダリングをブロックすることもある
Display page
Layout nodes
Paint nodes
Measuring Performance Metrics
どう評価していくか
Load and DOMContentLoaded events
https://gyazo.com/6d2544b0ba36277fed5d71890221a6be
理想は上の表示
User Centric Performance Metrics
https://gyazo.com/5612a9f23b3ae25bc0a570a1b607db1f
現在の計測・指標
Visual Progress Score of the page
算出がむずかしめ
ブラウザ標準ではとれない指標
短いほどよい
Largest Contentful Paint
もっとも大きいコンテンツが表示されたタイミング
画像、SVG、映像など
background-image
標準化してない
Long Tasksがおわったときに取れば良いのでは?
PerformanceObserver API
code:PerformanceObserver.js
const po = new PerformanceObserver(list => {
for (const entry of list.getEntries()) {
// entry is a PerformanceEntry instance.
console.log(entry.entryType);
console.log(entry.startTime);
console.log(entry.duration);
}
});
// Start observing the entry types you care about.
po.observe({
});
ツール
結果
Optimizing HTML
サブリソースをすべて圧縮する
CSSロード
<link rel="stylesheet">は<head>内
JSロード
<script>は</body>直前
サードパーティにはdefer属性をつける
asyncはCPUのリソースをもってってしまう
preload
どれくらいプライオリティ(優先度)があるかを決められる仕様
Resource Hints
rel="dns-prefetch"
rel="preconnect"
rel="prefetch"
rel="prerender"
quicklink
クリック時の遷移早めてくれる
エンジニア
フロントエンド、バックエンドの区別なし
デザイナー
とにかく動くものを高速に大量につくる布陣
Webフロントエンドの開発スタイル
デザイナーが画面モックをつくってエンジニアにわたす
フロントエンドを書いたことがない人が対応する
直面した問題
デザイナーごとにUIの差異が大きくなる
画面モックと実装の差
CSSは毎回書いたりコピペするなど
stylesheetsディレクトリがカオス化
現在はAtomic Designをやらなくなった
Atomの最小で分割できないポイントが気になった
レベル1の捉えが難しい
1か2にする!という基準になった
高品質で統一感のあるUIの爆速開発
デザイナーとエンジニア、両者の共通言語になる
アクセシビリティの高い実装を
コントラスト比を考慮したカラーパレット調整
当初は自分たちが使う部分だけやればいいと思ってた
開発生産性の改善意識があったので正式なプロジェクトになった
UXチームに異動希望して異動した
Vibesが使われる=Vibes注入
Vibesペアプロ
ペアプロとコードレビューで自力でフロントエンドを作れる
入社してからCSSを書かなくても実装できてうれしい!との声 課題
実装の想定通りにコンポーネントが使われない
コンポーネント自体がなく、機能不足があったときに改善できない
機能不足を理由に渋られる
作るだけではなくうまく使ってもらうコミュニケーションが必要
設計思想を文章化する
デザイナーにVibesの実装を認識する
./github/ISSUE_TEMPLATE.md
デザインシステムをなぜ構築しているのか?
会社のミッション・ビジョンを実現するためにデザインシステムを作っている
やりたいと思ってる人が誰でも使えるものを作る
提供する価値を世界に伝えられられるUIである必要
当事者にとって働きやすいか?
給与明細を人に読み上げてもらう必要がない
ありとあらゆる業務がペーパーレスになってて良い
色弱当事者は日本人男性の20人に1人はいる
中小企業ほど高齢者比率は高い
世界を変えるためのデザインシステム
開発体験とUI開発とプロセスを大事にしていく
田村 亮弥
650人
主は受託開発
提案フェーズ
要件定義
設計・実装
テスト
リリース
保守対応
プロジェクト
5〜30人規模
フロントエンドは平均3、4名
3ヶ月〜数年単位
フロントエンドチーム
受託案件・アート案件のJS開発
実績
成田空港サイトリニューアル
イノベーション自販機
チームラボアプリ
スマホサイフ
マイナビバイト webサイト
実案件への採用と苦労話
採用実績
バックエンドAPIは自作
苦労話
ライブラリ読み込みがうまくいかない
window or documentが undefined
requireだとTree Shakingできない
自作ライブラリ化する
lodash-es
import文が解釈できなくエラーになる
build.transpileプロパティを使用する
メモリリーク
メモリ上限を上げたけど根本解決には至らず
原因
インスペクタのメモリスナップショットで開放されていないのを探る
Classの静的メンバのmapへ値が追加され続けた
複製パスを持つページ
同じページなのに複数パスを用意しないと行けない場合
/pages/cart.vueと/pages/cart/_cartId.vue
いずれかを参照してexportすればパスを量産できる
余談
lodash-es+Tree Shakingで激的な圧縮
動的なファイル追加とHMRが難しい
pug関連のloaderを設定
統一がされてなかった
オリジナルのルール
teamlab/eslint-config
体裁を揃えて保守性を上げる
便利機能
overrides
対象ファイルを上書きできる
thisを使わないクラスメソッド定義を許可
$_veeValidateという変数名を許可
--max-warnings
エラーにしない警告の上限を設定
0であればチェック後にエラーにする
厳格なチェックに向いてる
デザイナーにエンジニアから10の質問
質問
別に駄目ではない
クライアントの要望をやるのはオーダーメイド
それに適しているかどうかを判定する
2. スタイリングの役割ってなんなの?
情報設計したものを見やすく作る
個性を表現するか
3. スタイリングの難しさ
色をどうやって入れていくか
4. 色ってどうやって決めてます?
ブランドカラー、キーカラーを決める
トップページが作るのが主
色の面積がどれだけあるか
6:3:1(ベース:メイン:アクセント)
面積のバランスをどう変えるためにレイアウトやシェイプをつかう
5. デザインのリズムってどういうの?
デザイン原則
ジャンプ率
ホワイトスペース
情報の繰り返し
6. 情報をどう整理しているか
ワイヤー時点で重要度や一番伝えたいことを定義
全体をつくりながら粒度を調整してカンプへ落とし込む
機能より見た目という優先順位が逆転してしまうこともある
7. 機能的に迷ったときどうしてる?
エンジニア => Web標準仕様を優先する
情報を
隠さない
長いのが嫌?
遠ざけない
難しくしない
8. エンジニアとどんな会話ができるとデザインしやすい?
実装の制約
要件のスタイル順
マイクロインタラクション
パフォーマンス
9. 頼れるエンジニア蔵
話を聞いてくれる
デザイン視点を大事にする
設計=Design
10. デザイナーにとってフロントエンド技術をどう考える?
未知数な事が多い
進歩が早い
ソースがわからない
自分たちからは近寄りがたい
一番聞きたいのは実装に関する制約
機能の影響度
デザイナーもエンジニアと本当は話したい
会場内質問
デザイナーとして、エンジニアとして、絶対に譲れないものを教えてください
新津:奇抜なものではなく、伝わることを優先にしている
平尾:伝わらなければ意味がない
インターフェイスを作ってるので
デザイナーの方はどういった情報を日々取り入れていっているのか
エンジニアが情報を押してくれる
デザインに寄った情報はない
デザイナーからみてエンジニアがやらかしがちなよくないことってありますか?
検証不足
デザインとフロント実装の兼務をしてる人はいますか?
いるけど、多くはない(分業なので)
重要度はどう判断しているのか
ワイヤーを作る時点で解決している
どういうデザイナーが望ましい?
平尾:エンジニア知識・歩み寄りがある人が望ましい
新津:目的を定めて自走できる・ディレクター視線がある・場作り
Visual Regression Testing in Action
背景
View(フロントエンド)のテスト書いてますか?
キリがない
どこまでアサーションすれば良いのか
充実させると仕様がかわるとメンテがしんどい
コスパ重視でテストは人力でやろうというのは最悪の場合
テストで得られたDOM文字列を次回のexpectedとして利用する
初回や差分時はファイルをレビューする
pros
導入が容易
cons
文字列テストすることに意味がどれだけあるのか?
最終的に出力するものが重要
描画された画像そのものをスナップショットする
他のモチベーション
アプリケーション全体でCSSの検証
SCSSから他のCSS preprocessorへ移行したい 何をするべきか?
問題をクリアしていく
小さい問題を解いて、大きいものを解く
画像を出力する
アプローチ
パーツごとにキャプチャしていくパターン
ヘッドレスでやれそう
様々なフレームワークにサポート
テスト以外で役に立つ
カタログ利用
HMRが効くのでUI開発も便利
v3~5までサポート
UIフレームワークに依存しない
StorybookのURLさえ知っていれば動かせる
結構早いと思う
偽陽性誤検知
合ってるけど、間違ってるものだと判定してしまう
ソースコードを変えてないのにキャプチャ画像の比較時に差分が検証される
1. アニメーション
CSSアニメーションは強制停止する
JSによるものはユーザー側で切り替えてもらう
2. アセットロードを待つ
読み込み完了前にキャプチャされるとまずい
page.on('request')で監視
request.resoueceType()で判別したリソース種別が事前にわかる
3. レンダリングパイプライン
Metrics APIでレンダリングパイプラインにおける処理実行回数を計測
PaintとCompositeが定常かどうか知る術がないので不完全
出力したのを比較する
ディレクトリ同士を引数にして画像の差分比較を行う
回帰テストのワークフローに組み込みラッパーツール
シュルスクリプトが古代化してきてやばかったのでリファクタリングした
CIやSCMに依存せず、汎用的に使えるように
画像の出力
環境で違うものがうまれてしまう
大量のdiffができる
CIで生成された画像を使う
現在AWSとGCSを保存先にするプラグインを公開
プルリクコメント
コミットステータスと連動
意図的な変更なのかはレビューが必要
その場合はレビュワーのアプローブで通すようにする
レビュー
どのような変更なのかが可視化できるので負荷が軽減
フロントのスタックは複雑
当時はよいものがなかったので自作した
ユースケース
企業
パブリックレポジトリで行ってる
使用数
2~3万回 / 月 => 14万回 / 月
平均300~400枚数
パフォーマンス
画像1000枚超えもザラ
それに耐えられる・維持できるようにはしてる
Storycap、reg-cliは大変
画像の生成が支配的
使う人は何をやっていくか
テストはしっかり回していこう
あくまでもアサーションを楽にするだけ
テストコードはしっかり書く
コンポーネント設計
テストコードから制御できるようにする
local Stateに頼りすぎない
見た目はpropsで変更できるように
ReduxのStoreで切り出す
new Date()で差分が発生する自体があった
テスタビリティ
維持できるかどうかが開発者の責務
よくすることは設計にちゃんと向き合うことになる
必要性について
静的なWebサイトでも脆弱性は生まれる
location.hrefにXSS攻撃もできる
あらゆるサイトやアプリにおいてセキュリティに配慮が必要
Origin
http: プロトコル、スキーム
example.com: ホスト
:8080: ポート
同じオリジンかどうかは正規化で比較
Cross Origin
異なるOriginへのアクセス
同一じゃないとアクセス制限がある
許可が必要
DOM-based XSS
攻撃者から与えた文字列(ソース)をもとに
HTMLを操作すること(シンク)
対策
DOM操作をする
textContentやsetAttributeを用いる
リンク生成時はhttp://あるいはhttps://のみに制限
ライブらいの脆弱性はすぐアップデートする
mXSS - Mutation-based XSS
HTMLElementから文字列、文字列からHTMLElementへの変換は非対称
属性値にエラー実行を含んだものを入れるとタグ補完されてXSSが起こる
パースのモードが切り替わる
IEのみならず他のブラウザでも起こり得る
対策
HTMLElemnetを文字列操作しない
cloneNodeを使う
iframe sandboxを使う
オープンリダイレクト
指定したサイトを任意のものにリダイレクトされる
ハッシュタグ以降のものに遷移する場合
https://example.com/#//evil.example.com/ を与えた場合だと飛んでしまう
対策
URLインターフェースを使ってオリジンを確認
オリジン間の保護のしくみ
今後はCSPのframe-ancestorsを使う
Content Security Policy
レスポンスヘッダー指定でリソース読み込み元の制限
XSSで挿入したスクリプトは動かなくなる
違反時のレポートは飛ぶけどブロックされないチューニングもある
フォームの飛び先・親の設定もできる
許可したサイトにDOM-based XSSのある古いライブラリが残らないよう注意
他オリジンから読んでいいかの許可
Originヘッダー自体は攻撃社が自由に送信できる
ブラウザ内で読み込ませないために使う
機密情報に対しての認証は別途対応
XHRやfetch API以外にもimgやvideoでのcrossorigin属性も利用可能 ほかサイトから画像やJSの読み取りを制限する
scriptタグも制御
潜在的なサイドチャンネル攻撃への対策
CPUのプロセス情報が読めてしまう
Content-Typeが合わないときは読み込みをブロック
JSONやHTMLをJSや画像として読み込もうとさせる
SameSIte Cookie
Cookie送信を同一サイト内に限定する
モード
strict
lax
今後はこれがデフォルトになる?
資料一覧