MaedaCSSJavaScriptUI/UXパフォーマンスプラグイン前回投稿した『jsdo.itでアクセスの多かったUIデザインに役立つJavaScriptコード紹介』という記事では、jsdo.itというサービスのウィジェットを15個表示させることにしました。ウィジェットはJavaScriptのdocument.write()が使われていたため、15個も表示させるとページがこれでもかというくらい重くなり、投稿も半ば諦めモードになりかけました。最終的にはdocument.write()が書き出すiframeを取り出し、遅延ロードさせるという方法でなんとか乗り切りました。その辺の話を詳しく書こうと思います。目次jsdo.it上のコードをページに埋め込むコードを15個埋め込むとさすがに重い...ページが激重の原因はdocment.write()docment.write()は非同期処理ができないiframe要素の遅延ロードを試すことにiframe要素の遅延ロードの実装にはlayzr.jsが使えそうlayzr.jsの実装方法iframe要素のレスポンシブ対応iframe要素の遅延ロードの実装完了jsdo.it上のコードをページに埋め込むjsdo.it内で書いたコードは、ウィジェットとしてブログなど好きなページに埋め込むことができるようになっています。jsdo.itのそれぞれのページに設置してある「ブログに埋め込む」というボタンを押すと、ページに埋め込むためのscriptタグがコピーできるようになっています。コピーできるscriptタグは以下のようになっています。src="http://jsdo.it/blogparts/f9Cy/js?width=654&height=424&view=readme"></script>上記のscriptタグをページに貼り付けると以下のようにjsdo.itのコードが表示されるようになっています。コードを15個埋め込むとさすがに重い...上記のように簡単にjsdo.itのコードをページ内に埋め込むことができるので、手軽にコードの紹介もできると思ったのが誤りでした...。何を欲張ったのかこのjsdo.itのコードを15個表示させることにしました。記事を書くためにせっせとウィジェットを15個コピーしてはページに埋め込んでいきました。して気づいた時にはすでに時遅し、ページが激重になっていました...。プレビューもままならず、途方に暮れることになりました。記事も書いたし、投稿を辞めるわけにもいかず、いろいろ悩んだ挙句とにかくこの問題を解決させる道を模索することにしました。ページが激重の原因はdocument.write()まずscriptタグで読み込んでいるjsファイルがどうなっているか見てみることにしました。以下のscriptタグ内のsrc属性の値の部分(jsファイルのURL)をコピーしてブラウザのアドレスバーに貼り付けました。http://jsdo.it/blogparts/f9Cy/js?width=654&height=424&view=readme展開されたjsファイルの中身は以下のようになっていました。0px;\"></iframe></div>");おわかりのように、激重の原因はdocument.write()でした。document.write()の問題点と言えば、document.write()による書き出しが終わるまで、それ以降のページのレンダリングを止めてしまうことです。それに拍車をかけるように、ウィジェット内には激重の代表格と言われているFacebookやTwitterのソーシャルボタンが使われていました。15個のウィジェットの表示が終わるまで、ページの読み込みが終わらないという最悪の状態となっていました。docment.write()は非同期処理ができないこれを解決するために、まず考えたのはscrpt要素にasync属性やdefer属性をつけて非同期でウィジェットを表示させることでした。docment.write()がくせものたる所以はここにあって、docment.write()はasync属性やdefer属性に対応していないということです。要するに、実行された場所で即座に内容の生成を行うdocment.writeに対して、非同期系の処理を与えるということは無理があるということです。いうことでウィジェットの非同期での表示は諦めざるをえませんでした。MDNただ調べてみると以下のようにdocument.write()を非同期で実行させるような裏技的な方法は存在するようです。自分はブログの記事に対して実装するのは面倒くさいと思って別の方法を探すことにしました。...iframe要素の遅延ロードを試すことにということで次に考えたのは、document.write()で書き出されるHTMLタグの部分を直接ブログの記事内に貼り付けることでした。上記でも触れたように、jsdo.itのscript要素のsrc属性に指定されているJSファイルを開くと以下のようになっています。0px;\"></iframe></div>");document.write()内のHTMLタグ部分を抜き出して、整形し直すと以下のようになります。これをそのままページに貼り付けることにしました。></iframe></div>ただ、これだけではdocument.write()とやっていることは変わらず、相変わらず激重なままです。そこで考えたのが、iframe要素の遅延ロードです。これしか方法はないかなと思いました。遅延ロードの実装は、手っ取り早くjQueryプラグインに頼ることにしました。遅延ロードと言ったら、まず真っ先に思いつくのは、定番中の定番となっているlazyloadだと思います。jQuerylazyloadはよく画像の遅延ロードに使われていますね。調べてみるとiframeにも対応しているようでした。以下のブログを見るとiframeの対応はなんだか手間がかかりそうな感じがしたので、これも諦めて違うプラグインを探すことにしました。ネットショップ運営の気になる備忘録iframe要素の遅延ロードの実装にはlayzr.jsが使えそうそして見つけたのがlayzr.jsというJavaScriptのライブラリです。loading.軽量で、高速で、モダンで、jQueryなど何にも依存しないJSライブラリとなります。以下のブログ記事を見ると、すごく簡単にiframeの遅延ロードを実装できることがわかりました。blogさっそくlayzr.jsを使ってiframeの遅延ロードを実装することにしました。layzr.jsの実装方法layzr.jsのダウンロードまずlayzr.jsを以下のGitHubのページよりダウンロードします(npmやbowerにも対応しています)。GitHubのページに記載のCDNのURLをコピーします。GitHublayzr.jsの読み込みダウンロードしたlayzr.jsをページに読み込みます。src="layzr.js"></script>iframeのsrc属性をdata-layzr属性に変更iframeのsrc属性をdata-layzr属性に変更します。height="424"></iframe></div>新しいインスタンスを生成する以下のコードを記載し、ページ読み込み後に、Layzrオブジェクトの新しいインスタンスを生成するようにします。false);</script>ローディング画像を設定するこれで遅延ロードされるようになりましたが、ロードされるまで空白が表示された状態となっているので、ローディング画像を設定しておきます。iframeのsrc属性にローディング画像を設定することができます。src="https://preloaders.net/preloaders/719/Appearing%20squares.gif"></iframe></div>ローディング画像は以下のサイトのものを使わせてもらいました。忘れてはいけないのが、iframeのスマホ対応です。画面サイズに合わせてiframeのサイズをフレキシブルに変更する必要があります。今回はcssを使ってスマホ対応しました。書いたcssのコードは以下のようになります。}}</style>iframeのスマホ対応についての詳細は、当ブログの以下の記事を参考にしてください。実装後のjsdo.itのウィジェットは以下のように遅延して表示されるようになりました。layzr.jsは複数のiframeにも対応しています。上記で紹介した方法でインスタンスをひとつ生成するだけで、複数のiframeを遅延ロードさせることができるようになります。複数のiframeに遅延ロードを実装した例は当ブログの前回の記事になりますので、ぜひご確認ください。15個のウィジェットを表示させていますが、それほどもっさり感は感じないと思います。maesblogまとめフロントエンドに力を入れている面白法人カヤックのサービスらしからぬ重々なウィジェットにかなり面食らいましたが、なんとか上記のような実装を施し、記事を公開することができました。今回利用したlayzr.js、なかなか使えると思います。今回はiframeの遅延ロード方法を紹介しましたが、もちろん画像にも使えます。オプションもいろいろ用意されているようなので、その辺りも今後詳しく見ていこうと思っています。世の中には激重なウィジェットがたくさん存在していると思います。いった解決策もあるものだと参考にしてもらえれば幸いです。maechabinホーム目次トップ。