Hatena::Groupsubtech

ういはるかぜの化学

Thursday, December 12, 2013

Internet Explorer 9/10で__defineGetter__, __defineSetter__ が存在しない 01:01 Internet Explorer 9/10で__defineGetter__, __defineSetter__ が存在しない - ういはるかぜの化学 を含むブックマーク はてなブックマーク - Internet Explorer 9/10で__defineGetter__, __defineSetter__ が存在しない - ういはるかぜの化学

このエントリーはInternet Explorer Advent Calendar 201312日目です。

ECMAScript 5th Editionにはオブジェクトのプロパティのゲッターとセッターを定義するためのObject.definePropertyというメソッドがあり、Internet Explorerは9からこのメソッドに対応しています。

このObject.definePropertyというものが標準になる前にほかのブラウザで先行実装されていた Object.prototype.__defineGetter__と__defineSetter__ という同じくゲッターとセッターを定義するメソッドがあったのですが9と10には実装されていません。ところが11になってそれを期待する実装が世の中には一定数あるせいなのか実装されたようです。

というわけで__defineGetter__と__defineSetter__を必要とする何かをInternet Explorer 910で動かしたくなることありますよね?ってお話です。

動かすためのshim

以下のようなコードを突っ込んであげれば__defineGetter__と__defineSetter__を利用できるようになります。簡単ですね。

やってることは__defineGetter__,__defineSetter__でdefinePropertyを呼び出しているだけです。

if (!Object.prototype.__defineGetter__) {
    Object.defineProperty(Object.prototype, '__defineGetter__', {
        enumerable: false,
        value: function (sprop, func) {
            var propDesc = Object.getOwnPropertyDescriptor(this) || {};
            propDesc.configurable = true;
            propDesc.get = func;
            Object.defineProperty(this, sprop, propDesc);
        }
    });
}
if (!Object.prototype.__defineSetter__) {
    Object.defineProperty(Object.prototype, '__defineSetter__', {
        enumerable: false,
        value: function (sprop, func) {
            var propDesc = Object.getOwnPropertyDescriptor(this) || {};
            propDesc.configurable = true;
            propDesc.set = func;
            Object.defineProperty(this, sprop, propDesc);
        }
    });
}
トラックバック - http://subtech.g.hatena.ne.jp/mayuki/20131212

Wednesday, December 11, 2013

Internet Explorer for Windows PhoneのWebサイトの優先設定とF12開発者ツールのプロファイル 02:13 Internet Explorer for Windows PhoneのWebサイトの優先設定とF12開発者ツールのプロファイル - ういはるかぜの化学 を含むブックマーク はてなブックマーク - Internet Explorer for Windows PhoneのWebサイトの優先設定とF12開発者ツールのプロファイル - ういはるかぜの化学

このエントリーはInternet Explorer Advent Calendar 201311日目です。

Internet Explorer for Windows Phoneの設定「Webサイトの優先設定」とは

Windows Phone 8版のInternet Explorerの設定には「Webサイトの優先設定」という項目があります。これは一体何なのかちょっと気になったので調べてみました。

f:id:mayuki:20131212021133p:image

結論から言えばこれはUser-Agentが普通のデスクトップのようなものになるだけっぽい、でした。

モバイル用サイト
Mozilla/5.0 (compatible; MSIE 10.0; Windows Phone 8.0; Trident/6.0; ARM; IEMobile/10.0; ARM; Touch; NOKIA; Lumia 620)
デスクトップ用サイト
Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; Trident/6.0; ARM; Touch; WPDesktop)

User-Agentを一般的なInternet Explorer 10を装うことでアクセスできる範囲を広げるための設定というのだということのようです。

viewportの設定が変わるとかそういうのは見たところなさそうなので、リクエストに関連するものとみてよさそうですね。

Internet Explorer 11のF12開発者ツールにある「エミュレーション」の「プロファイル」

ところでInternet Explorer 11のF12開発者ツールにある「エミュレーション」に「プロファイル」という設定項目があり、そこにはWindows Phoneという項目が用意されています。

f:id:mayuki:20131212021132p:image

これもまた一体なにかしら?と思ったのでちょっと調べてみました。

調べてみた結果、おおざっぱにいえば以下のような部分が変わります。

  • User-Agentが自動でWindows Phoneになる
  • meta要素によるviewport指定がきくようになる
    • 例えば width=300px であるとか width=device-width という指定がきく(device-widthだと文字サイズもスケールする)
    • width=300pxと指定するとhtml要素が300px相当になる
    • 画面サイズ(高さも含めて)は別な解像度の設定が反映される
  • -ms-text-size-adjust プロパティがきくようになる
    • 文字サイズだけ拡大するプロパティ

つまりどういうことかといえばこれはWindows Phone側にある設定がユーザー向けなのとは違って、Windows Phone 8向けのコンテンツを作るときにレイアウトの参考にできるという開発者向けのエミュレーション設定なのです。

まとめ

というわけでユーザーがPC版を要求する必要もなくなるよう、F12のエミュレーション設定でWindows PhoneでもアクセスできるWebサイトを増やしていきましょう…。-webkit-だけしか書いてないとかやめましょう…。

トラックバック - http://subtech.g.hatena.ne.jp/mayuki/20131211

Tuesday, December 10, 2013

Flip ahead (ページフリップ)を使う、実装する Flip ahead (ページフリップ)を使う、実装する - ういはるかぜの化学 を含むブックマーク はてなブックマーク - Flip ahead (ページフリップ)を使う、実装する - ういはるかぜの化学

このエントリーはInternet Explorer Advent Calendar 201310日目です。

Internet Explorer 10からFlip ahead(ページフリップ)という機能がつきましたのでその紹介を。

Flip ahead (ページフリップ)とは

Internet Explorerを起動して使ってると「ページフリップを有効にしますか?」みたいなメッセージが出てお前は何を言っているのかと思った人も多そうな気がします。

Flip aheadというのはどういう機能かというと新しいUIInternet Explorerで使える機能で、サイト側で「次のページのURL」をブラウザに教えることでフリップ(指ではじく操作)して次のページに遷移できる機能です。

新しいUIInternet Explorerではブラウザの戻る/進むがフリップ操作でできるようになっていますが、通常「進む」は一度見て戻った場合にしか使えません。そこでこのFlip aheadを使うとまだ見ていない次のページも進むと同じ操作で進めるというわけです(挙動的には「次へ」が使えるようになるだけなので一応マウスでも操作できます)。

これが何が嬉しいかというとどんどんめくっていくような感覚でブラウズできるようになるのがよいところです。Tumblrのテンプレートに組み込んでみたやつBingGoogleといったところで試せます。

うまく動かないときは設定を確認

もしかしたら設定が無効になっているかもしれません。その時はチャームからInternet Explorerの「設定」の「プライバシー」からページフリップを項目を有効にしてください。

Internet Explorer 11でのFlip ahead

さらにInternet Explorer 11ではFlip aheadで指定されている次のページはプリレンダリングの対象ともなるようになっているため、さらに体感的にめくる感触が良くなっています。

じつは昨日の先読みの話は今回の前振りとして用意したわけでした。

実装方法

さてそんな便利そうなFlip aheadですがいい感じで勝手にやってくれるわけはなく、ページコンテンツ側での対応が必要になります。必要にはなるのですがいたって簡単です。次のようなlink要素を追加するだけで独自拡張でもありません。

<link rel="next" href="http://www.example.com/" />

これを書くだけでプリレンダリングまでやってくれます。簡単ですね。

ちなみにrel="prev"で前のページのURLも指定することができます。

まとめ

Flip aheadはページ分割されているコンテンツなどでは有用ですし、組み込みも簡単かつ悪影響も考えにくいので是非組み込んでみてはいかがでしょうか。

トラックバック - http://subtech.g.hatena.ne.jp/mayuki/20131210

Monday, December 09, 2013

サイトを先読みに対応させる 01:29 サイトを先読みに対応させる - ういはるかぜの化学 を含むブックマーク はてなブックマーク - サイトを先読みに対応させる - ういはるかぜの化学

このエントリーはInternet Explorer Advent Calendar 2013の9日目です。

今日は開発者向けのお話です。Internet Explorer 11から対応したGoogle Chromeなども以前から対応しているサイトの先読みの機能についての話です。

サイトの先読みって何?

そもそもサイトの先読みというのは現在表示しているページの先をあらかじめ読み込んでおくことでブラウジングの体感速度を上げる手法です。

例えば検索エンジンで検索結果の上位ページはクリックされる可能性が高いリンクです。つまり現在見ているページ(=検索結果)から遷移する先がある程度予想できます。ということは検索結果をユーザーが見ているうちにリンク先を裏側で読み込んでおけば検索結果からリンク先へ飛んだ際にすぐさま表示できるわけです。

例えばBing(英語版)だと検索結果の一番目のサイトを先読み/プリレンダリングするといったことが行われています。

f:id:mayuki:20131210012748p:image:w640

"Windows Azure"で検索した結果の一番目にポインターをホバーするとツールチップに「Preloading …」と出てきて先読みしていることがわかります。バックグラウンドでの先読みが完了していればクリックしての遷移がとても速くなります。

先読みの方法

リンク先をあらかじめ読み込んでおくと言ってもいくつか方法があります。Internet Explorer 11では以下の方法に対応しています。

DNS解決をあらかじめ行う(dns-prefetch)
DNSの名前解決をバックグラウンドで行うことで次に遷移するときにDNS解決の時間を短縮する
リソースを先読みする(prefetch)
リソースを先読みしてキャッシュに格納しておくことでリソースの読み込みを早くする
ページをプリレンダリングする(prerender)
ページ丸ごとバックグラウンドで読み込んでレンダリングしておくことで高速に遷移できるようにする(上のBingはこれです)

先読みの指示の仕方

先読みの方法が3つあることがわかったので実際にブラウザにどう指示すれば先読みしてくれるのか?というお話です。

DNS解決をあらかじめ行う(dns-prefetch)

DNS解決をあらかじめ行っておくこと(DNSプリフェッチ)で何が嬉しいかというと、リンク先に遷移しようとしたときやリソースを取得しようとしたときにはじめてDNS解決行われることによる無駄な時間を減らすことができます。

DNSプリフェッチをブラウザに指示するには以下のようなlink要素を記述します。

<link rel="dns-prefetch" href="http://www.example.com/" />

こうすることで www.example.comIPアドレスをあらかじめキャッシュするようになります。

リソースを先読みする(prefetch)

リソースの先読みは後から差し込まれる画像などを先読みしておくことでキャッシュしておくというものです。

リソースの先読みをブラウザに指示するには以下のようなlink要素を記述します。

<link rel="prefetch" href="http://www.example.com/" />
ページをプリレンダリングする(prerender)

ページのプリレンダリングはリソースのダウンロードに加えてレンダリングも完了させておくという先読みの中でも最強の先読みともいえます。

プリレンダリングしてほしい旨をブラウザに指示するには以下のようなlink要素を記述します。

<link rel="prerender" href="http://www.example.com/" />

実に簡単ですね。こうすると裏側で指定されたURLを取得してレンダリングします。

ちなみにInternet Explorer 11ではJavaScriptからlink要素を差し込んでも認識するようです(Bingはそうしてた)。

プリレンダリングの注意点と制限

プリレンダリングはバックグラウンドでレンダリングしておくという挙動のため単純な先読みよりもセンシティブな挙動となります。そのためいくつかの制限やページ制作の注意点があります。

なお前提としてプリレンダリングを指示する側のページでは一つのページしかプリレンダリングを指示できません。

実はPrerender and prefetch support (Windows)に書いてありますがざっと説明します。

プリレンダリングできる条件

指定されたURLのページがプリレンダリングできる条件として最低限以下のものを満たしている必要があります。

  • 従量制ネットワークの場合にはプランによって決まる(プランの詳細は謎。ConnectionCost.Conservativeだとダメとかかも)
  • 対象のURLがファイルのダウンロードとならないこと
  • 対象のURLhttp スキームまたは https スキームであること
  • 対象のURLはトップレベルのドキュメントであり、iframeではないこと
  • link要素を含むページが表示状態であり、フォアグラウンドなタブ(選択状態)であり最小化されていないこと
プリレンダリングが一時停止される場合

さらに以下の条件を満たさない場合にはレンダリングは途中で停止されます。つまり以下の条件に当たった瞬間にそこでプリレンダリングは一時停止するということのようです。

  • プリレンダリング対象のページ中で何らかのUI通知が発生した場合
    • alertやウィンドウを開いたり、何らかの通知が発生したり
  • プリレンダリング対象のページ中のvideo要素またはaudio要素でメディアが自動的に再生された場合
    • autoplay属性とか
  • プリレンダリング対象の履歴が変更される場合
    • window.historyが更新されるようなナビゲーションが発生したり
プリレンダリングされたページが破棄される場合

プリレンダリングされたページも以下のような特定の条件を満たすとその状態が破棄されます。

  • プリレンダリングしたページを5分以内に表示しなかった場合
  • ユーザーが別なページを開いた場合
  • ユーザーが別なタブに切り替えた場合
  • JavaScriptによって別なプリレンダリング対象を指定したlink要素が差し込まれた場合
  • プリレンダリング対象ページを読み込み中にエラー(404とか)が発生した場合
プリレンダリングによる副作用

プリレンダリングは裏側でページの実行が行われるのでいくつか副作用が発生します。特にJavaScriptによる処理が動いてしまうので注意が必要です。

  • ActiveX コントロールはユーザーがページを表示した瞬間に使えるようになる
    • そのためreadyStateで利用できるかどうか確認する
  • ページが表示されたときにアニメーションが動作しないことがある
    • プリレンダリング中にアニメーションが発動して完了してしまうと何も起きなくなる
  • タイマーが予期しない結果となることがある
    • 多分Interval通りにこないとかそういうこと
  • CookieやIndexedDB, Web Storageによるデータの保持はそのまま維持されます

ドキュメントにはloadまでに起こる問題といった書かれ方をしているので、ページのloadイベントまでは普通に実行されそこで一時停止するものと考えられます。

なのでDOMContentLoadedで行った処理はそのまま反映されてしまう可能性がありますので注意が必要です。

まとめ

ページの先読みはユーザーの行動を概ね予測できる場合にはとても強力に動作します。

ページのロードにかかる時間は当然同じわけですが、ユーザーのインタラクションを待ってから遷移するのと非同期でバックグラウンドで取りに行って用意しておくのでは体感には大きな差が出ますのでうまく使えば大変効果的ではないでしょうか。

トラックバック - http://subtech.g.hatena.ne.jp/mayuki/20131209

Sunday, December 08, 2013

Internet Explorerでタブの同期ができるのは最大何台? 01:16 Internet Explorerでタブの同期ができるのは最大何台? - ういはるかぜの化学 を含むブックマーク はてなブックマーク - Internet Explorerでタブの同期ができるのは最大何台? - ういはるかぜの化学

このエントリーはInternet Explorer Advent Calendar 2013の8日目です。

Windows 8.1Internet Explorer 11MicrosoftアカウントでWindowsにサインインしているときに別なコンピューターで開いているタブを同期するという機能があります。

ちょっと話は変わってWindows 8.1ではWindowsストアに紐づけられるコンピューターは81台ということになっています。とするとInternet Explorerで同期できるのも81台ぐらいなのかしら?と思ったりするわけです。

何台同期できるの?

というわけでひたすらWindowsをセットアップしまくって同期しまくってみました。が、結論から言うと、あまりにも手間がかかる(初回セットアップ+同期待ちの時間がかかる)ので限界に到達できていないのでわかりません…。

f:id:mayuki:20131209010630p:image:w640

とはいえとりあえず40台ほど同期できるのは確認できました。普通なら困らないですね。引き続き調べていきたいところですね…。

同期しまくってわかったこと

同期しまくっていていくつか気付いたことがありました。

Windows ServerにはMicrosoftアカウントでのサインインはできない

最初はWindows AzureWindows Server 2012 R2を100台ぐらい展開してひたすらサインインしていけばいけると思っていたのですがまさかのMicrosoftアカウント紐づけ機能がないという罠でした。

そのため一つ一つセットアップしていくという予想以上に時間のかかる展開に…。

同期のユーザー識別はSIDかなにかっぽい

同期のユーザー識別にはSIDを使っているような雰囲気があります。というのはどういうことかというと、今回最初にある程度Windows 8.1をセットアップした状態でSysprepで一般化という複数コンピュータへの展開のための初期化をするということをしました。

で、最初Sysprepする前にMicrosoftアカウントでユーザーを作っておいて、セットアップしたのちサインインすればと思ってやってみたのですがどうにもおかしな状態になりました。

タブが同期されないのもそうなのですが、スタートも吹き飛んでしまったので完全に同じユーザーで不整合が起きて残念なことが起きるようです。たぶんこれはHyper-VVMwareParallelsとか仮想マシンとして複数差分イメージを作っていて使っている場合とかにも起きると思うので注意が必要です。

無人インストールにMicrosoftアカウントでの紐づけはない

無人インストール時にユーザーを作れますが、ドメインアカウントやローカルアカウントは作れてもMicrosoftアカウントでの紐づけまでやる方法は用意されていません。まあ当たり前ですね。

たまに同期したものが消える

同期していたコンピューターの項目がたまに消えます。何か理由があるのかなと思いつつ謎です。スクリーンショットを見ていただければわかりますが50台ぐらいまで起動していますが40個しか同期した項目がありません。

おまけ: どうやったのか

ちなみにどうやったのかというと以下のような手順です。

  • Hyper-VWindowsのOOBE直前の仮想マシンを作る(WindowsセットアップしてSysprep)
  • 新しい仮想マシンを作って差分ディスクにする
  • その時点で一度スナップショットをとる
  • 起動してセットアップ&Microsoftアカウントでサインイン
  • タブを開いて同期されるまで待つ(ほかの仮想マシンで確認する)
  • 同期されたらスナップショットを適用してセットアップに戻って以下略

というわけで同期は数分間隔なので時間が超かかるのでした…。

トラックバック - http://subtech.g.hatena.ne.jp/mayuki/20131208