Upload
koji-ishimoto
View
3.071
Download
4
Embed Size (px)
DESCRIPTION
世の中にはパフォーマンス最適化のためのベストプラクティスと呼ばれるものがたくさんありますが、一体どれから手をつければよいのしょうか、また一体どれが一番効果のある対策と言えるのでしょうか?一般論を言えば、ネットワーク改善から手をつけるべきで、その中でもHTTPリクエストを減らすのが一番効果的です。リクエストを減らすポピュラーなテクニックであるCSS SpriteをSass/Compassを利用しながら効率良く改善していきましょう。
Citation preview
基礎編 : 2012
モバイルフロントエンド最適化
ネットビジネス総合事業本部 マークアップエンジニア 石本 光司2012.11.10 @Webridge Meeting SP12 featuring Frontrend
@t32k
デザインから考えるハイパフォーマンスWebサイト
Webパフォーマンス最適化のためのコーディング手法 心理学から考えるWebパフォーマンス
t32k.github.com/speed/
今日の流れ- あなたは何をされていますか?
- どちらが遅いのでしょうか?
- 私たちは何をすべきでしょうか?
- まとめ
あなたは何をされていますか?
back-end
つまり、あなたは?
front-end
back-end
つまり、あなたは?
front-end
僕は、フロントエンジニアだ!
1. HTTP リクエストを減らす
2. CDNを使用する
3. ブラウザーキャッシュを有効にする
4. Gzipを有効にする
5. スタイルシートは上部に設置
6. スクリプトは下部に設置
7. CSS Expressionsは避ける
8. JS/CSSファイルを外部化する
9. DNSルックアップを減らす
10. JS/CSSを縮小化する
11. リダイレクトを避ける
12. 重複スクリプトを削除する
13. ETagを設定する
14. Ajaxをキャッシュ可能にする
高速サイトのためのベストプラクティスby Yahoo! Developer Network
効果
難易度
高い
易しい難しい
低い
for front-end engineer
1効果
難易度
高い
易しい難しい
低い
23
4 56
78
910
1112
1314
for front-end engineer
1効果
難易度
高い
易しい難しい
低い
23
4 56
78
910
1112
1314
for front-end engineer
フロントエンドタスク
1. HTTP リクエストを減らす
5. スタイルシートは上部に設置
6. スクリプトは下部に設置
7. CSS Expressionsは避ける
8. JS/CSSファイルを外部化する
- - - - - - - - - - - - - - - - - - - - - - - - -
9. DNSルックアップを減らす
12. 重複スクリプトを削除する
フロントエンドタスク
1. HTTP リクエストを減らす5. スタイルシートは上部に設置
6. スクリプトは下部に設置
7. CSS Expressionsは避ける
8. JS/CSSファイルを外部化する
- - - - - - - - - - - - - - - - - - - - - - - - -
9. DNSルックアップを減らす
12. 重複スクリプトを削除する
developers.google.com/speed/pagespeed/insights
バックエンドタスク2. CDNを使用する
3. ブラウザーキャッシュを有効にする
4. Gzipを有効にする
- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
10. JS/CSSを縮小化する
11. リダイレクトを避ける
13. ETagを設定する
14. Ajaxをキャッシュ可能にする
バックエンドタスク2. CDNを使用する
3. ブラウザーキャッシュを有効にする
4. Gzipを有効にする- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
10. JS/CSSを縮小化する
11. リダイレクトを避ける
13. ETagを設定する
14. Ajaxをキャッシュ可能にする
90PageSpeed Score
+
どちらが遅いのでしょうか?
ネットワーク
ハードウェアvs.
今後10年間でインターネットの帯域幅速度は57倍になると思われているが、コンピューターの処理能力は100倍以上になるだろう。
モバイルサイト vs. アプリ: 来るべき戦略の転換 ‒ U-Site
ネットワークは、重いのよ!!
1,000
1,500
2,000
2,500
3,000
3,500
1Mbp
s
2Mbp
s
3Mbp
s
4Mbp
s
5Mbp
s
6Mbp
s
7Mbp
s
8Mbp
s
9Mbp
s
10M
bps
帯域幅別のページの読み込み速度(m
s)
More Bandwidth Doesn’t Matter (Much) « Mike's Lookout
なんで?
Chrome開発者ツール:ネットワークパネル
HTTPリクエストの中身
クライアント
サーバー
HTTPリクエストの中身
DNSルックアップ
ISP
クライアント
サーバー
HTTPリクエストの中身
DNSルックアップ
ISP
クライアント
サーバー
DNS Lookup
HTTPリクエストの中身
DNSルックアップ
ISP
クライアント
サーバー
DNS Lookup
最初の接続
HTTPリクエストの中身
接続の確立
DNSルックアップ
ISP
クライアント
サーバー
DNS Lookup
最初の接続
HTTPリクエストの中身
接続の確立
DNSルックアップ
ISP
クライアント
サーバー
DNS Lookup Connecting
最初の接続
HTTPリクエストの中身
接続の確立
DNSルックアップ
ISP
クライアント
サーバー
DNS Lookup Connecting
最初の接続 最初のHTTPリクエスト
HTTPリクエストの中身
接続の確立
DNSルックアップ
ISP
最初のデータ送信
最初のデータ受信クライアント
サーバー
DNS Lookup Connecting
最初の接続 最初のHTTPリクエスト
HTTPリクエストの中身
接続の確立
DNSルックアップ
ISP
最初のデータ送信
最初のデータ受信クライアント
サーバー
DNS Lookup Connecting Waiting
最初の接続 最初のHTTPリクエスト
HTTPリクエストの中身
接続の確立
DNSルックアップ
ISP
最初のデータ送信
最初のデータ受信
最後のデータ送信
最後のデータ受信クライアント
サーバー
DNS Lookup Connecting Waiting
最初の接続 最初のHTTPリクエスト
HTTPリクエストの中身
接続の確立
DNSルックアップ
ISP
最初のデータ送信
最初のデータ受信
最後のデータ送信
最後のデータ受信クライアント
サーバー
DNS Lookup Connecting Waiting Receiving
最初の接続 最初のHTTPリクエスト
HTTPリクエストの中身
接続の確立
DNSルックアップ
ISP
最初のデータ送信
最初のデータ受信
最後のデータ送信
最後のデータ受信クライアント
サーバー
DNS Lookup Connecting Waiting Receiving
最初の接続 最初のHTTPリクエスト
RTT
HTTPリクエストの中身
接続の確立
DNSルックアップ
ISP
最初のデータ送信
最初のデータ受信
最後のデータ送信
最後のデータ受信クライアント
サーバー
DNS Lookup Connecting Waiting Receiving
最初の接続 最初のHTTPリクエスト
RTTDL
DNSの名前解決
TCPコネクション確立に要する時間
ブラウザーキューからネットワークに接続するまでの時間
データのリクエストをサーバーに送信するのに要する時間
レスポンスの待ち時間
レスポンスボディをダウンロードするのに要する時間
DNS Lookup:
Connecting:
Blocking:
Sending:
Waiting:
Receiving:
ラウンドトリップタイムRTT
DL ペイロードサイズ
私たちは何をすべきでしょうか?
ラウンドトリップタイムRTT
CSS Sprite
ラウンドトリップタイムRTT
Requests 30 vs. 1 (CSS Sprite)
Requests 30 vs. 1 (CSS Sprite)
spritegen.website-performance.org
spritegen.website-performance.org
No Retina!
めんどくさい...
知ってる?
compass-style.org
t32k at MacBookPro in ~$ gem install compass$ compass create my_project$ cd /my_project$ compass watch
Command line
t32k at MacBookPro in ~$ gem install compass$ compass create my_project$ cd /my_project$ compass watch
Command line
@import "compass";@import "/sprites/category/*.png";@include all-category-sprites;
Sass + compass
.category-sprite, .category-chat, .category-fav, .category-home, .category-love, .category-mind, .category-new, .category-nightlife, .category-work { background: url(/sprites/category-s87c70fb891.png) no-repeat; }
.category-chat { background-position: 0 -168px; }
.category-fav { background-position: 0 -42px; }
.category-home { background-position: 0 -294px; }
.category-love { background-position: 0 -252px; }
.category-mind { background-position: 0 -84px; }
.category-new { background-position: 0 -210px; }
.category-nightlife { background-position: 0 0; }
.category-work { background-position: 0 -126px; }
CSS
.category-sprite, .category-chat, .category-fav, .category-home, .category-love, .category-mind, .category-new, .category-nightlife, .category-work { background: url(/sprites/category-s87c70fb891.png) no-repeat; }
.category-chat { background-position: 0 -168px; }
.category-fav { background-position: 0 -42px; }
.category-home { background-position: 0 -294px; }
.category-love { background-position: 0 -252px; }
.category-mind { background-position: 0 -84px; }
.category-new { background-position: 0 -210px; }
.category-nightlife { background-position: 0 0; }
.category-work { background-position: 0 -126px; }
CSS
// For Retina @2x@mixin sprites($map, $map-item, $isCommon:false) { @if $isCommon { display: inline-block; background-image: sprite-url($map); background-repeat: no-repeat; background-size: (image-width(sprite-path($map)) / 2) (image-height(sprite-path($map)) / 2); } @else { $pos-y: round(nth(sprite-position($map, $map-item), 2) / 2); width: image-width(sprite-file($map, $map-item)) / 2; height: image-height(sprite-file($map, $map-item)) / 2; background-position: 0 $pos-y; }}
@mixin
$sprites-category: sprite-map("sprites/category/*.png");.common-property { @include sprites($sprites-category, foo, true);}.indivisual-property-fav { @include sprites($sprites-category, fav, false);}.indivisual-property-chat { @include sprites($sprites-category, chat, false);}
Usage
.common-property { display: inline-block; background-image: url('/images/sprites/category-s13fa409ec6.png'); background-repeat: no-repeat; background-size: 21px 168px;}
.indivisual-property-fav { width: 21px; height: 21px; background-position: 0 -21px;}
.indivisual-property-chat { width: 21px; height: 21px; background-position: 0 -84px;}
CSS
•画像をPs/Fwで並べる
•画像をPs/Fwで並べる
•background-positionを測る
•画像をPs/Fwで並べる
•background-positionを測る
•コードに反映する
•画像をPs/Fwで並べる
•background-positionを測る
•コードに反映する
/(^o^)\オワタ
•画像ディレクトリに出し入れするだけ
•画像ディレクトリに出し入れするだけ
(´∀`)つ ミ
DL ペイロードサイズ
Gzip
DL ペイロードサイズ
github.com/h5bp/html5-boilerplate/blob/v4.0.0/doc/htaccess.md
圧縮効率を最大化する
Yourself
Don’tRepeat
.foo { -webkit-border-radius: 5px; -moz-border-radius: 5px; -ms-border-radius: 5px; -o-border-radius: 5px; border-radius: 5px;}
CSS
F****** CSS
知ってる?
@import "compass";.foo { @include border-radius(5px);}
Sass + compass
.foo { -webkit-border-radius: 5px; -moz-border-radius: 5px; -ms-border-radius: 5px; -o-border-radius: 5px; border-radius: 5px;}
Output CSS
F****** CSS
t32k.github.com/speed/articles/gzip.html
コードの一貫性を保つ
.foo { -webkit-border-radius: 1px; -moz-border-radius: 1px; -ms-border-radius: 1px; -o-border-radius: 1px; border-radius: 1px;}.bar { -webkit-border-radius: 3px; -moz-border-radius: 3px; -ms-border-radius: 3px; -o-border-radius: 3px; border-radius: 3px;}.baz { -webkit-border-radius: 5px; -moz-border-radius: 5px; -ms-border-radius: 5px; -o-border-radius: 5px; border-radius: 5px;}
CSS.foo { -ms-border-radius: 1px; -webkit-border-radius: 1px; -moz-border-radius: 1px; -o-border-radius: 1px; border-radius: 1px;}.bar { -moz-border-radius: 3px; -ms-border-radius: 3px; -o-border-radius: 3px; -webkit-border-radius: 3px; border-radius: 3px;}.baz { -o-border-radius: 5px; -webkit-border-radius: 5px; -ms-border-radius: 5px; -moz-border-radius: 5px; border-radius: 5px;}
.foo { -webkit-border-radius: 1px; -moz-border-radius: 1px; -ms-border-radius: 1px; -o-border-radius: 1px; border-radius: 1px;}.bar { -webkit-border-radius: 3px; -moz-border-radius: 3px; -ms-border-radius: 3px; -o-border-radius: 3px; border-radius: 3px;}.baz { -webkit-border-radius: 5px; -moz-border-radius: 5px; -ms-border-radius: 5px; -o-border-radius: 5px; border-radius: 5px;}
Uncompressed:.foo { -ms-border-radius: 1px; -webkit-border-radius: 1px; -moz-border-radius: 1px; -o-border-radius: 1px; border-radius: 1px;}.bar { -moz-border-radius: 3px; -ms-border-radius: 3px; -o-border-radius: 3px; -webkit-border-radius: 3px; border-radius: 3px;}.baz { -o-border-radius: 5px; -webkit-border-radius: 5px; -ms-border-radius: 5px; -moz-border-radius: 5px; border-radius: 5px;}
416B
.foo { -webkit-border-radius: 1px; -moz-border-radius: 1px; -ms-border-radius: 1px; -o-border-radius: 1px; border-radius: 1px;}.bar { -webkit-border-radius: 3px; -moz-border-radius: 3px; -ms-border-radius: 3px; -o-border-radius: 3px; border-radius: 3px;}.baz { -webkit-border-radius: 5px; -moz-border-radius: 5px; -ms-border-radius: 5px; -o-border-radius: 5px; border-radius: 5px;}
Compressed:.foo { -ms-border-radius: 1px; -webkit-border-radius: 1px; -moz-border-radius: 1px; -o-border-radius: 1px; border-radius: 1px;}.bar { -moz-border-radius: 3px; -ms-border-radius: 3px; -o-border-radius: 3px; -webkit-border-radius: 3px; border-radius: 3px;}.baz { -o-border-radius: 5px; -webkit-border-radius: 5px; -ms-border-radius: 5px; -moz-border-radius: 5px; border-radius: 5px;}
122B 130B
.foo { -webkit-border-radius: 1px; -moz-border-radius: 1px; -ms-border-radius: 1px; -o-border-radius: 1px; border-radius: 1px;}.bar { -webkit-border-radius: 3px; -moz-border-radius: 3px; -ms-border-radius: 3px; -o-border-radius: 3px; border-radius: 3px;}.baz { -webkit-border-radius: 5px; -moz-border-radius: 5px; -ms-border-radius: 5px; -o-border-radius: 5px; border-radius: 5px;}
CSS.foo { -ms-border-radius: 1px; -webkit-border-radius: 1px; -moz-border-radius: 1px; -o-border-radius: 1px; border-radius: 1px;}.bar { -moz-border-radius: 3px; -ms-border-radius: 3px; -o-border-radius: 3px; -webkit-border-radius: 3px; border-radius: 3px;}.baz { -o-border-radius: 5px; -webkit-border-radius: 5px; -ms-border-radius: 5px; -moz-border-radius: 5px; border-radius: 5px;}
-69%-71%
csscomb.com
Googleの検索結果ページでは、
HTML属性をアルファベット順に記述した場合、gzip後のサイズが
1.5%削減することができた。圧縮を有効にする - Make the Web Faster ̶ Google Developers
― Ludwig Mies van der Rohe
神は細部に宿る
そんなに心配しすぎない
まとめ
$ 私たちは何をすべきでしょうか?
$ 私たちは何をすべきでしょうか?
>> フロントエンドに着目しなさい
$ 私たちは何をすべきでしょうか?
>> フロントエンドに着目しなさい
$ 私たちは何をすべきでしょうか?
$ 私たちは何をすべきでしょうか?
>> フロントエンドに着目しなさい
$ 私たちは何をすべきでしょうか?
>> ネットワーク段階を改善しなさい
$ 私たちは何をすべきでしょうか?
>> フロントエンドに着目しなさい
$ 私たちは何をすべきでしょうか?
>> ネットワーク段階を改善しなさい
$ 私たちは何をすべきでしょうか?
$ 私たちは何をすべきでしょうか?
>> フロントエンドに着目しなさい
$ 私たちは何をすべきでしょうか?
>> ネットワーク段階を改善しなさい
$ 私たちは何をすべきでしょうか?
>> RTTとペイロードサイズを縮小しなさい
Thank you :)koji.ishimoto@t32kt32k
このスライドはJina Boltonさんのスライドを参考にしました。ありがとう @jina :)
photo credit- http://www.flickr.com/photos/expose_switch/4566783151/
- http://www.flickr.com/photos/ivko999/5082864854/
- http://www.flickr.com/photos/peasap/4684467836/
- http://www.flickr.com/photos/emrank/2191608962/
- http://www.flickr.com/photos/spilt-milk/6042115943/
- http://www.flickr.com/photos/avidlyabide/7509737450/
- http://www.flickr.com/photos/hinkelstone/2435823037/
- http://www.flickr.com/photos/alex-d/2770828285/
- http://www.flickr.com/photos/expose_switch/4566783201/
- http://www.flickr.com/photos/expose_switch/4566783171/