マークアップ講座 Part3 デバイス最適化


#デバイス最適化


#スマートフォン端末

##解像度

###スマートフォン解像度

####代表的な解像度

|デバイス|CSSピクセル（ブラウザピクセル）|デバイスピクセル比|解像度|インチ|
|:--|:--:|:--:|:--:|:--:|
|iPhone 6 Plus|414 ✕ 736|2.61(!!)|1080 ✕ 1920|5.5|
|iPhone 6|375 ✕ 667|2|750 ✕ 1334|4.7|
||||||
|iPhone 5S|320 ✕ 568|2|640 ✕ 1136|4|
|iPhone 5|320 ✕ 568|2|640 ✕ 1136|4|
|iPhone 4S|320 ✕ 480|2|640 ✕ 960|3.5|
|iPhone 4|320 ✕ 480|2|640 ✕ 960|3.5|/
|iPhone 3GS|320 ✕ 480|1|320 ✕ 480|3.5|
|iPhone 3G|320 ✕ 480|1|320 ✕ 480|3.5|
||||||
|GALAXY Note 3 SC-01F|360 ✕ 640|3|1080 ✕ 1920|5.7|
|GALAXY S4 SC-04E|360 ✕ 640|3|1080 ✕ 1920|5|
|GALAXY S III SC-06D|360 ✕ 640|2|720 ✕ 1280|4.8|
|GALAXY S II|320 ✕ 533|1.5|480 ✕ 800|4.3|
|Nexus S|320 ✕ 533|1.5|480 ✕ 800|4|
||||||
|Xperia Z Ultra（ファブレット）|540 ✕ 918|2|1080 ✕ 1920|6.4|
|XPERIA A SO-04E|360 ✕ 598|2|720 ✕ 1280|4.6|


###タブレット解像度

####代表的な解像度

|デバイス|CSSピクセル（ブラウザピクセル）|デバイスピクセル比|解像度|インチ|
|:--|:--:|:--:|:--:|:--:|
|iPad Air|768 ✕ 1024|2|1536 ✕ 2048|9.7|
|iPad 3|768 ✕ 1024|2|1536 ✕ 2048|9.7|
|iPad|768 ✕ 1024|1|768 ✕ 1024|9.7|
||||||
|iPad mini|768 ✕ 1024|1|768 ✕ 1024|7.9|
||||||
|Nexus 10|800 ✕ 1280|2|1600 ✕ 2560|10|
|Nexus 7 （2013）|600 ✕ 960|2|1200 ✕ 1920|7|


##Retinaディスプレイ（高精細ディスプレイ）

RetinaディスプレイはApple社の高精細ディスプレイ
高精細ディスプレイはデバイスピクセル比が１より大きいディスプレイのこと
　

###Retinaディスプレイ向けデザイン

2014年現在、制作上おもに重要とされる高精細ディスプレイはスマートフォン、タブレット搭載のもの

※ PCの高精細ディスプレイへのデザイン対応はまだ一般的とは言えない
　

####iPhone 5S、iPhone 5対応の場合

- デザインカンプは短辺横640pxで作成
- 短辺横320pxのリキッドレイアウトでマークアップ(※)
- デザインの最小単位（最も細い罫線など）を2pxでデザイン

(※) 次項で説明
　

####iPhone 6 Plus（予想）対応の場合

- デザインカンプは短辺横1080pxで作成
- 短辺横360pxのリキッドレイアウトでマークアップ(※)
- デザインの最小単位（最も細い罫線など）を3pxでデザイン

※ iPhone 6 Plus発売後、徐々に3倍psdに移行することが予想される

(※) 次項で説明
　

##スマートフォン・ブラウザ

|browser|最新ver|vendor|engine|
|:--|:--|:--|:--|
|iOS Mobile Safari|7|Apple|WebKit|
|iOS Chrome（ネイティブアプリ UIWebView）|36|Google|WebKit|
|Android Mobile Safari（標準ブラウザ）|4|Apple|WebKit|
|Android Mobile Safari - Chrome（新標準ブラウザ）|1（Chrome 18）|Google|WebKit|
|Android Chrome|36|Google|Blink|

※ 上記ブラウザが占めるモバイルブラウザシェア 約89% （2014年9月現在）
http://www.netmarketshare.com/
　

#スマートフォン・マークアップ

##スマートフォン・マークアップ実践

###viewport

```
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no">
```

- width=device-width

- initial-scale=1.0

- maximum-scale=1.0

- user-scalable=no
　

####width

ウィンドウの横幅を設定
device-widthにして端末毎のCSSピクセルのデフォルトの横幅に設定
　

####initial-scale

デフォルト表示時の拡大率
1.0に設定して拡縮をさせない
　

####maximum-scale

表示拡大率の最大値
1.0に設定して拡大表示を抑止
　

####user-scalable

ピンチ動作の可否を設定
noに設定してピンチ動作を抑止
　
#####※ デバイスのorientation

ユーザーがスマートフォンを持っている時の位置
ポートレート（縦位置）とランドスケープ（横位置）

ユーザーの設定によりオリエンテーション変更は止めることができる

スマホブラウザではコンテンツ側からオリエンテーション変更を止めることはできない
　

###format-detection

```
<meta name="format-detection" content="telephone=no,address=no,email=no">
```

自動的にリンクを生成する機能
不要な動作を防ぎたい場合はオフにしておく
　

###画像表示 1 img要素の場合

短辺横640px（デバイスピクセル比2）のデザインカンプにおいて、画像の横幅値が200pxの画像の場合

```
■ HTML
<img src="sample.png" class="sample-image">

■ CSS
.sample-image {
  width: 100px;
}
```

CSSによって横幅値をデザインカンプの半分に表示されるよう設定する
　

###画像表示 2 背景画像の場合

短辺横640px（デバイスピクセル比2）のデザインカンプにおいて、画像の縦・横幅値が200pxの正方形画像の場合

```
■ HTML
<div class="sample-block"></div>

■ CSS
.sample-block {
  width: 100px;
  height: 100px;
  background-image: url(sample.png);
  background-repeat: no-repeat;
  background-size: 100px 100px;
}
```

CSSによって縦・横幅値をデザインカンプの半分に表示されるよう設定する
　

###スマートフォン最適化CSS

####font

```
html {
  font-family: Helvetica, Roboto, 'Droid Sans', 'Hiragino Kaku Gothic Pro', sans-serif;
}
```

font-familyの一例
　

####text-size-adjust

```
html {
  -webkit-text-size-adjust: 100%;
}
```

ランドスケープ表示時にフォントが拡大されるのを抑止
　

####tap-highlight-color

```
a {
  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
```

Androidにおいてタップ時に表示される枠を解消
　

####break-all

```
* {
  word-break: break-all;
}
```

横幅表現に限りがあるスマートフォンにおける英文の表示トラブルを防止
　

###画像最適化

####減色・圧縮

#####ImageAlpha （Mac）

『ImageAlpha — image minifier (like JPEG with transparency!)』
http://pngmini.com/


#####Pngyu （Win、Mac）

『Pngyu』
http://nukesaq88.github.io/Pngyu/
　

####適正化

#####ImageOptim （Mac）

『ImageOptim — better Save For Web』
http://imageoptim.com/

余分な情報をクリーンアップして軽量化
※ gruntに組み込むことも可能
　

###ホームアイコン

ジェネレータ

『Makeappicon - Generate app icons of all sizes in a click!』
http://makeappicon.com/

1024✕1024で出力した画像（jpg, png, psd）をドラッグドロップ
　

####ホームアイコンデザインの注意点

アイコンの角を丸めなくてもiOS側で角は丸められる
ただしAndroidでは直角のまま出力される

角を丸めてデザインする場合はテンプレートを利用する

『App Icon Template』
http://appicontemplate.com/
http://appicontemplate.com/ios7
　

####ホームアイコンの設置

```
<link rel="apple-touch-icon" sizes="152x152" href="/icon/Icon-76@2x.png">
<link rel="apple-touch-icon" sizes="144x144" href="/icon/Icon-72@2x.png">
<link rel="apple-touch-icon" sizes="120x120" href="/icon/Icon-60@2x.png">
<link rel="apple-touch-icon" sizes="114x114" href="/icon/Icon@2x.png">
<link rel="apple-touch-icon" sizes="76x76" href="/icon/Icon-76.png">
<link rel="apple-touch-icon" sizes="72x72" href="/icon/Icon-72.png">
<link rel="apple-touch-icon" sizes="60x60" href="/icon/Icon-60.png">
<link rel="apple-touch-icon" sizes="57x57" href="/icon/Icon.png">
<link rel="shortcut icon" href="/icon/favicon.ico">
```

※ 「favicon.ico」自作
16✕16pxのpngを出力し拡張子を.icoに変更
　

####iOS6までの記述 「-precomposed」がiOS7で不要に

```
<link rel="apple-touch-icon-precomposed" sizes="152x152" href="/icon/Icon-76@2x.png">
<link rel="apple-touch-icon-precomposed" sizes="144x144" href="/icon/Icon-72@2x.png">
<link rel="apple-touch-icon-precomposed" sizes="120x120" href="/icon/Icon-60@2x.png">
<link rel="apple-touch-icon-precomposed" sizes="114x114" href="/icon/Icon@2x.png">
<link rel="apple-touch-icon-precomposed" sizes="76x76" href="/icon/Icon-76.png">
<link rel="apple-touch-icon-precomposed" sizes="72x72" href="/icon/Icon-72.png">
<link rel="apple-touch-icon-precomposed" sizes="60x60" href="/icon/Icon-60.png">
<link rel="apple-touch-icon-precomposed" sizes="57x57" href="/icon/Icon.png">
<link rel="shortcut icon" href="/icon/favicon.ico">
```

iOS6までは rel="apple-touch-icon-precomposed" のように「-precomposed」接尾辞をつけて、アイコンに自動でかけられてしまう反射効果を明示的にかからないように設定していた

iOS7からのフラットデザインにより効果は付与されなくなったため、「-precomposed」は不要になる

Android OSのアイコン選択にも影響があった「-precomposed」が不要になるのは歓迎できる
　

####画像遅延読み込み

ファーストビューから外れる画像は初期レンダリング時にロードしないでおく
スクロールなどのユーザーアクションに応じて残りを読み込む
初期レンダリング時のリクエスト数削減に効果大

jQuery Pluginを利用した例

『Lazy Load Plugin for jQuery』
http://www.appelsiini.net/projects/lazyload
http://www.appelsiini.net/projects/lazyload/enabled_timeout.html
　

#####* jQuery

```
<script src="[自ドメイン jQuery ファイルパス]/jquery-2.1.1.min.js"></script>
```

ver.2が利用できます
　

##【TOPIC】スマートフォンとSEO

- SPサイトにおいても基本はPCと同じ、重要なSEO要素はtitle要素、description、keywords、h1、etc...

- レスポンシブそのもののSEO効果は特別に高くはない

- レスポンシブにおいてPCとSPが同構造であるためキーワード運用効率は高いと言える

- PCとSPが同URL構造であることも評価される

- SPサイトにおけるSEO重要項目は、"スマートフォン適正化サイトが存在すること"
　

##検証環境

###シミュレーター

####iOS ： iOSシミュレーター （Mac）

『Xcode』
https://developer.apple.com/jp/xcode/

※ iOSシミュレーターを一発起動
『iWebInspector』
http://www.iwebinspector.com/
　

####Android ： Genymotion （Win、Mac、Linux）

『Genymotion』
http://www.genymotion.com/
　

###Browser

『Chrome Developer Tools』
https://developer.chrome.com/devtools
　

###リンクツール

####Chrome to Mobile 拡張機能 （Chrome Mobile）

『Chrome to Mobile 拡張機能』
https://support.google.com/chrome/answer/2451559?p=ib_chrome_to_mobile&rd=1
　

####Chrome to Phone 拡張機能 （Android）

『Google Chrome to Phone 拡張機能』
https://chrome.google.com/webstore/detail/google-chrome-to-phone-ex/oadboiipflhobonjjffjbfekfjcgkhco
　

#フロントエンドパフォーマンス

##リソース記述位置

###worst case

JS → HTML → CSS

http://test0001.s-ej.com/54/s01.html
http://www.webpagetest.org/result/140911_Y0_6AK/

Start Render遅延
　

###bad case

HTML → JS → CSS

http://test0001.s-ej.com/54/s02.html
http://www.webpagetest.org/result/140911_GD_6B1/

FOUC(Flash of Unstyled Content)発症
　

###good case

CSS → HTML → JS

http://test0001.s-ej.com/54/s03.html
http://www.webpagetest.org/result/140911_01_6BS/
　

##リクエスト数

###bad case

10 requests each
style1〜10.css
img1〜10.jpg
script1〜10.js

http://test0001.s-ej.com/54/s11.html
http://www.webpagetest.org/result/140911_M5_74P/

Speed Index遅延
　

###good case

concated 1 request each
style.all.css
img.all.jpg
script.all.js

http://test0001.s-ej.com/54/s12.html
http://www.webpagetest.org/result/140911_3M_753/
　

##minify、画像最適化

###bad case

concated 1 request each
style.all.css
img.all.jpg
script.all.js

http://test0001.s-ej.com/54/s12.html
http://www.webpagetest.org/result/140911_3M_753/

Speed Index遅延
　

###good case

concated and minified 1 request each
style.all.min.css
img.all.comp.jpg
script.all.min.js

http://test0001.s-ej.com/54/s13.html
http://www.webpagetest.org/result/140911_84_7F5/
　

#コーディングレギュレーション

##PC

###HTMLテンプレートサンプル

```
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>[title値]</title>
<meta name="author" content="[コピーライト]">
<meta name="description" content="[ページ概要]">
<meta name="keywords" content="[キーワード],[キーワード],[キーワード]・・・">
<!--ogp-->
<meta property="og:title" content="[ページタイトル]">
<meta property="og:type" content="[ページtype]">
<meta property="og:description" content="[記事の説明]">
<meta property="og:url" content="[ページURL]">
<meta property="og:image" content="[画像URL]">
<meta property="og:site_name" content="[サイトのタイトル]">
<meta property="og:locale" content="[言語]">
<meta property="fb:admins" content="[facebookユーザーID]">
<meta property="fb:app_id" content="[facebookアプリID]">
<!--/ogp-->
<!--twitter card-->
<meta property="twitter:card" content="[カードtype]">
<meta property="twitter:site" content="[サイト名]">
<meta property="twitter:title" content="[ページタイトル]">
<meta property="twitter:description" content="[ページ概要]">
<meta property="twitter:image" content="[画像URL]">
<meta property="twitter:url" content="[ページURL]">
<!--/twitter card-->
<link rel="shortcut icon" href="/icon/favicon.ico">
<link rel="canonical" href="[正規化フルパス URL]">
<!--css-->
<link rel="stylesheet" href="[スタイルシートパス]">
<!--/css-->
<!--ga-->
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-xxxxxxxx-x', 'auto');
ga('send', 'pageview');
</script>
<!--/ga-->
</head>
<body>

<p>contents here.</p>

<!--JS-->
<script src="[自ドメイン jQuery ファイルパス]/jquery-1.11.1.min.js"></script>
<script src="[共通 JavaScript]"></script>
<script>
/*[ローカル JavaScript]*/
</script>
<!--/JS-->
</body>
</html>
```

https://github.com/sekiyaeiji/html_template/blob/master/pc.html


##SP

###HTMLテンプレートサンプル

```
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>[title値]</title>
<meta name="author" content="[コピーライト]">
<meta name="description" content="[ページ概要]">
<meta name="keywords" content="[キーワード],[キーワード],[キーワード]・・・">
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no">
<meta name="format-detection" content="telephone=no,address=no,email=no">
<!--ogp-->
<meta property="og:title" content="[ページタイトル]">
<meta property="og:type" content="[ページtype]">
<meta property="og:description" content="[記事の説明]">
<meta property="og:url" content="[ページURL]">
<meta property="og:image" content="[画像URL]">
<meta property="og:site_name" content="[サイトのタイトル]">
<meta property="og:locale" content="[言語]">
<meta property="fb:admins" content="[facebookユーザーID]">
<meta property="fb:app_id" content="[facebookアプリID]">
<!--/ogp-->
<!--twitter card-->
<meta property="twitter:card" content="[カードtype]">
<meta property="twitter:site" content="[サイト名]">
<meta property="twitter:title" content="[ページタイトル]">
<meta property="twitter:description" content="[ページ概要]">
<meta property="twitter:image" content="[画像URL]">
<meta property="twitter:url" content="[ページURL]">
<!--/twitter card-->
<!--icon-->
<link rel="apple-touch-icon" sizes="152x152" href="/icon/Icon-76@2x.png">
<link rel="apple-touch-icon" sizes="144x144" href="/icon/Icon-72@2x.png">
<link rel="apple-touch-icon" sizes="120x120" href="/icon/Icon-60@2x.png">
<link rel="apple-touch-icon" sizes="114x114" href="/icon/Icon@2x.png">
<link rel="apple-touch-icon" sizes="76x76" href="/icon/Icon-76.png">
<link rel="apple-touch-icon" sizes="72x72" href="/icon/Icon-72.png">
<link rel="apple-touch-icon" sizes="60x60" href="/icon/Icon-60.png">
<link rel="apple-touch-icon" sizes="57x57" href="/icon/Icon.png">
<link rel="shortcut icon" href="/icon/favicon.ico">
<!--/icon-->
<link rel="canonical" href="[正規化フルパス URL]">
<!--css-->
<link rel="stylesheet" href="[スタイルシートパス]">
<!--/css-->
<!--ga-->
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-xxxxxxxx-x', 'auto');
ga('send', 'pageview');
</script>
<!--/ga-->
</head>
<body>

<p>contents here.</p>

<!--JS-->
<script src="[自ドメイン jQuery ファイルパス]/jquery-2.1.1.min.js"></script>
<script src="[共通 JavaScript]"></script>
<script>
/*[ローカル JavaScript]*/
</script>
<!--/JS-->
</body>
</html>
```

https://github.com/sekiyaeiji/html_template/blob/master/sp.html