<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:series="http://organizeseries.com/"
	>

<channel>
	<title>DOM &#8211; HTML5Experts.jp</title>
	<atom:link href="/tag/dom/feed/" rel="self" type="application/rss+xml" />
	<link>https://html5experts.jp</link>
	<description>日本に、もっとエキスパートを。</description>
	<lastBuildDate>Sat, 07 Jul 2018 03:14:05 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=4.7.19</generator>
	<item>
		<title>Shared Workers復活？、CSSOM View更新ほか、2013年12月のWeb標準化動向</title>
		<link>/myakura/4888/</link>
		<pubDate>Tue, 04 Feb 2014 01:00:17 +0000</pubDate>
		<dc:creator><![CDATA[矢倉 眞隆]]></dc:creator>
				<category><![CDATA[最新動向]]></category>
		<category><![CDATA[プログラミング]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[DOM]]></category>
		<category><![CDATA[W3C仕様]]></category>

		<guid isPermaLink="false">/?p=4888</guid>
		<description><![CDATA[連載： WEB標準化動向 (3)TPACという大きなイベントも終了し、またホリデーシーズンに入ったこともあり、12月のW3Cはとても静か…と思いきや、結構な数の仕様に更新ありました。 また、先月ちょっとだけ取り上げたSh...]]></description>
				<content:encoded><![CDATA[<div class="seriesmeta">連載： <a href="https://html5experts.jp/series/webstandards-news/" class="series-156" title="WEB標準化動向" data-wpel-link="internal">WEB標準化動向</a> (3)</div><p><a href="https://html5experts.jp/wp-content/uploads/2014/02/W3C1.jpg" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2014/02/W3C1.jpg" alt="W3C" width="207" height="156" class="alignright size-full wp-image-5092" /></a>TPACという大きなイベントも終了し、またホリデーシーズンに入ったこともあり、12月のW3Cはとても静か…と思いきや、結構な数の仕様に更新ありました。</p>

<p>また、先月ちょっとだけ取り上げたShared Workersの今後について議論されるなど、思ったよりも動きのある12月でした。</p>

<h2>Shared Workers復活！？</h2>

<p><a href="https://html5experts.jp/myakura/3333/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">先月の記事</a>にて、WebApps WGのF2FにてShared Workersが削除されることを取り上げました。これはShared Workersの実装が乏しく、2つ以上の実装という勧告への要件を満たせないという懸念を受けてのアクションです。</p>

<ul>
<li><a href="http://lists.w3.org/Archives/Public/public-webapps/2013OctDec/0939.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Refactoring SharedWorkers out of Web Workers W3C spec</a></li>
</ul>

<p>しかし12月に入り、FirefoxがShared Workersを有効にしました（Firefox 29より利用可能となります）。</p>

<ul>
<li><a href="https://hg.mozilla.org/mozilla-central/rev/11f269e4597e" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">mozilla-central: changeset 159853 — Bug 924089 &#8211; Enable SharedWorker by default</a></li>
</ul>

<p>これを受け、Shared Workersを削除する必要があるのかといった議論が、WebApps WGのメーリングリストで交わされています。議論の中で<a href="http://lists.w3.org/Archives/Public/public-webapps/2013OctDec/0961.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">実はPrestoも実装していた</a>という話も出てきて、こないだの話はなんだったのだろう感が否めません。</p>

<p>とはいえ、この議論が出てきたのはその実装状況が不明だった、テストスイートによる検証がなされていなかったなど、現状把握を誰も行っていなかったことに起因します。メーリングリストでは、その後各ベンダーの担当者にWeb Workersのテストスイートを実行するよう要請したことで、実装状況と相互運用性の状況がわかりつつあります。</p>

<ul>
<li><a href="http://www.w3.org/wiki/Webapps/Interop/WebWorkers" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Webapps/Interop/WebWorkers &#8211; W3C Wiki</a></li>
</ul>

<p>議論を追うとテストケース自体への問題も指摘されており、Shared Workersが削除されるというよりもWeb Workers自体の問題に移行しているようです。</p>

<p>なお、Web Workersについてはいくつか機能追加の要望もあり、Level 2仕様への希望も出ました。Canvasの<code>ImageData</code>をWorkersで扱うインターフェースなどはすでにWHATWG HTMLで提案中ですが、synchronous message channelsなど別の機能も求められているようです。</p>

<p>冬休みに入ったためか議論が止まってしまい、今後は以前不透明です。とはいえ、実装が増えたことはShared Workersについて明るいニュースだったのではないでしょうか。</p>

<h2>CSSOM Viewが更新 ― <code>devicePixelRatio</code>、スムーズスクロール機能が追加</h2>

<p>2013年12月17日付けで、CSS WGから新しいCSSOM Viewの草案が公開されました。</p>

<ul>
<li><a href="http://www.w3.org/TR/2013/WD-cssom-view-20131217/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">CSSOM View Module</a></li>
</ul>

<p>CSSOM ViewはCSS関連のオブジェクトモデルのうち、ブラウザやシステムに関わるプロパティを定義する仕様です。古くからある<code>clientWidth</code>や<code>getBoundingClientRect()</code>、比較的最近では<code>matchMedia()</code>などが定義されています。</p>

<p>今回の草案の見どころは、<code>window.devicePixelRatio</code>とスムーズスクロール関連の機能が定義されたことでしょうか。<code>window.devicePixelRatio</code>プロパティはAppleが高解像度モードのためにWebKitに導入した独自拡張で、Retina Displayをはじめ高密度ディスプレイへの対応をする際に使われています（ちなみにこのプロパティ、iPhone 4で初めてRetina Displayが登場するよりもずっと前の<a href="http://trac.webkit.org/changeset/15312" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">2006年に実装</a>されています）。他のベンダーも追従し、最近では<a href="http://msdn.microsoft.com/en-us/library/ie/dn265030" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">IE11でも実装</a>されました。</p>

<p>今回のCSSOM Viewではブラウザのズームとピンチズームの概念も導入され、さらに<code>devicePixelRatio</code>がブラウザズームの影響を受けると定義されました。これはGecko, Blink, Tridentの挙動に沿ったものですがWebKitの実装はそうではなく、Appleはこの定義に反対しています（WebKitではブラウザのズームにも、画面解像度の変更においても<code>devicePixelRatio</code>の値が変化しません）。</p>

<p>スムーズスクロール機能は現在、JavaScriptライブラリやスニペットを使って実装されていますが、タイマーを使ってちまちま<code>scrollTo()</code>をするものであまり効率が良い感じがしません。
今回の草案では新たに<a href="http://dev.w3.org/csswg/cssom-view/#smooth-scrolling:-the-&#039;scroll-behavior&#039;-property" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><code>scroll-behavior</code>プロパティ</a>というCSSプロパティが定義されました。<code>scroll-behavior: smooth</code>と指定すれば、対応する実装がネイティブのスムーズスクロールを利用するよう支持できます。</p>

<p>ほかにも、新たなメソッド<code>moveTo()</code>、<code>moveBy()</code>、<code>resizeTo()</code>、<code>resizeBy()</code>の導入や、<code>resize</code>イベントと<code>scroll</code>イベントが定義されたりなど盛りだくさんです。</p>

<h2>続CSSOM View ― PPK氏によるDPR調査など</h2>

<p>ブラウザの互換性調査などで有名なPeter-Paul Koch氏が、devicePixelRatioやズーム、screen関連のDOMプロパティについてコメントを寄せました。デスクトップのページズームはdevicePixelRatioに影響させるすべきでないなど、今の流れと正反対の意見を唱えており、ちょっとした議論になりました。</p>

<ul>
<li><a href="http://lists.w3.org/Archives/Public/www-style/2013Dec/0110.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">[css-om] Issues with width and resolution media queries</a></li>
</ul>

<p>CSSOM Viewはもともとあまり互換性のなかったデスクトップブラウザ間の挙動を、なんとか合わせるために策定が始まりました。しかしviewportやデバイスピクセル比などモバイルからもたらされた概念が関わり、さらにはブラウザのバグなどもあり混沌としています。今回の議論は、そういった概念の整理に加え、現在出回っているモバイルブラウザの挙動と、プラットフォームとしてどうあるべきかという仕様の方向が異なっていることも背景にありそうです。</p>

<p>なお、デバイスピクセル比については、ほかにも<a href="http://lists.w3.org/Archives/Public/www-style/2013Dec/0154.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><code>resolution</code>媒体特性が返す小数点の位がとる幅</a>について議論されています。</p>

<h2>仕様の断片化にどう対処するか</h2>

<p>Jens O. Meiert氏がHTML WG、CSS WG、WHATWGに、仕様の断片化についてアドバイスをしていました。</p>

<ul>
<li><a href="http://meiert.com/en/blog/20131205/spec-fragmentation/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">CSS, HTML, and the Problem of Spec Fragmentation · Jens O. Meiert</a></li>
</ul>

<p>CSSはモジュール化というアプローチで策定されていますが、氏は以前より機能が増えすぎていることを問題視していました。また、CSSモジュールだけではなく、WHATWG仕様の一部やHTML仕様、SVGでもセレクタやプロパティが定義されてることに触れ、見通しの悪さも指摘しています。</p>

<p>HTMLについても、WHATWG HTMLとW3CのHTML5、それにHTML 5.1と細かなバリエーションがあります。氏は触れていませんが、拡張仕様やHTML仕様が参照するいくつかのDOM仕様も含めると、HTML関連仕様も数がかなり多くなりそうです。</p>

<p>Meiert氏は、実装する方においては都合がよいかもしれないが、開発者は複数の仕様の違いに戸惑うことを問題視しています。仕様の断片化についてはW3Cの勧告プロセスにあるのではないかと思いますが、たしかに仕様の分割が頻繁で、どの機能がどこにあるのかがわからなくなることしばしばと思います。</p>

<h2>Custom Elementsのメソッド名が変更</h2>

<p>いろんな「今年注目すべきWeb技術」的エントリで、ここ数年取り上げら続けているWeb Componentsですが、そのいち仕様であるCustom ElementsについてAppleよりコメントが寄せられました。<a href="w3c.github.io/webcomponents/spec/custom/" data-wpel-link="internal">Custom Elements仕様</a>はWeb Componentsの独自の要素を定義するための仕組みを用意します。要素を定義するためのメソッドはこれまで<code>document.register()</code>という名前でしたが、<code>register</code>という単語1語の名前が汎用的すぎるといったコメントが寄せられました。</p>

<ul>
<li><a href="http://lists.w3.org/Archives/Public/public-webapps/2013OctDec/0968.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">[custom elements] Improving the name of document.register()</a></li>
</ul>

<p>こういった名前に関する指摘は自転車小屋の議論に陥りやすく、W3Cで過去に起こった同様の議論でもあまりいい解決を見たことがありません。しかしながら、今回はApple, Mozilla, Googleなどベンダーの開発者からのフィードバックもあり、それなりに思慮深い話になった感じがします。</p>

<p>結果として、仕様は<code>document.registerElement()</code>を使うことになりました。Chromeの実装も変更されています。</p>

<h2>その他12月に公開されたWeb標準</h2>

<ul>
<li>12月3日付けで、<a href="http://www.w3.org/TR/2013/WD-css-shapes-1-20131203/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">CSS Shapes</a>がCSS WGよりLast Callとして公開されました。大きな変更はTPACでのF2Fにて決定された構文の変更が仕様書に反映されたことでしょうか。</li>
<li>12月3日付けで、<a href="http://www.w3.org/TR/2013/WD-hr-time-2-20131203/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">High Resolution Time Level 2</a>の草案がWeb Performance WGより初公開にしてLast Callというすっとんだかたちで公開されました。Level 2での機能追加は今のところWeb Workersでのサポートとなっています。</li>
<li>12月5日付けで、<a href="http://www.w3.org/TR/2013/WD-cssom-20131205/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">CSS Object Model</a>の草案がCSS WGより公開されました。カスケードされた後のスタイルや利用されるスタイルといったスタイルを取得するインターフェースや、CSSOMとしてセーフな値にする<code>CSS.excape()</code>メソッドなどが新たに定義されています。</li>
<li>12月10日付けで、<a href="http://www.w3.org/TR/2013/WD-DOM-Parsing-20131210/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">DOM Parsing and Serialization</a>がWebApps WGよりLast Callとして公開されました。<code>innerHTML</code>や<code>insertAdjacentHTML()</code>を定義する仕様です。</li>
<li>12月12日付けで、<a href="http://www.w3.org/TR/2013/REC-performance-timeline-20131212/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Performance Timeline</a>、<a href="http://www.w3.org/TR/2013/REC-user-timing-20131212/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">User Timing</a>が勧告されました。</li>
<li>12月17日付けで、<a href="http://www.w3.org/TR/2013/CR-pointerlock-20131217/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Pointer Lock</a>がWebApps WGより勧告候補として公開されました。</li>
<li>12月17日付けで、<a href="http://www.w3.org/TR/2013/WD-ime-api-20131217/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Input Method Editor API</a>の草案がWebApps WGより公開されました。IMEの候補ウインドウを描画するAPIが削除されたほか、Microsoftが提案したイベントやインターフェースが追加されました。</li>
</ul>
]]></content:encoded>
		
		<series:name><![CDATA[WEB標準化動向]]></series:name>
	</item>
		<item>
		<title>斉藤祐也の海外WEBテク定点観測＜Issue.5: 2013/08/31-2013/09/13＞</title>
		<link>/cssradar/2463/</link>
		<pubDate>Mon, 16 Sep 2013 22:00:17 +0000</pubDate>
		<dc:creator><![CDATA[斉藤 祐也]]></dc:creator>
				<category><![CDATA[プログラミング]]></category>
		<category><![CDATA[デザイン]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[DOM]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[W3C仕様]]></category>
		<category><![CDATA[WebGL]]></category>
		<category><![CDATA[海外]]></category>

		<guid isPermaLink="false">/?p=2463</guid>
		<description><![CDATA[プログレッシブ・エンハンスメントに対する熱い議論、Steve Losh氏による技術文書の正しい書き方、JavaScript本の名著であるEloquent JavaScript2版のクラウドファンディングなど、14日間（8...]]></description>
				<content:encoded><![CDATA[<p>プログレッシブ・エンハンスメントに対する熱い議論、Steve Losh氏による技術文書の正しい書き方、JavaScript本の名著であるEloquent JavaScript2版のクラウドファンディングなど、14日間（8/31～9/13）のWeb開発最新ニュース合計18件を紹介します！</p>

<p><span id="more-2463"></span></p>

<h2>注目ニュースピックアップ</h2>

<h3>プログレッシブ・エンハンスメントはもう過去の話なのか?</h3>

<p><img src="/wp-content/uploads/2013/09/89f510799f3c4e4ab09ee882e8d3c595.png" alt="progressive-enhancement:-zed’s-dead,-baby-:-tom-dale-1024x768" width="300" height="255" class="aligncenter size-full wp-image-2490" srcset="/wp-content/uploads/2013/09/89f510799f3c4e4ab09ee882e8d3c595.png 300w, /wp-content/uploads/2013/09/89f510799f3c4e4ab09ee882e8d3c595-207x175.png 207w" sizes="(max-width: 300px) 100vw, 300px" /></p>

<p>この14日間はプログレッシブ・エンハンスメントについて多くの議論が行われた。</p>

<p>事の発端はDaniel Mall氏が始めた<a href="http://sighjavascript.tumblr.com/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Sigh, JavaScript</a>という様々なWebサイトで、JavaScriptをオフにした際の状態をキャプチャしてリストするというTumblr。<br />
それに対して、Ember.jsのメンテナーであるTom Dale氏が<a href="http://tomdale.net/2013/09/progressive-enhancement-is-dead/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Progressive Enhancement: Zed’s Dead, Baby</a>と題した記事で「プログレッシブ・エンハンスメントはもう終わったアプローチである」と宣言した。<br />
そのTom Dale氏の記事に、Jake Archibald氏が<a href="http://jakearchibald.com/2013/progressive-enhancement-is-faster/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Progressive enhancement is faster</a>にて反論。
そして、Daniel Mall氏も<a href="http://danielmall.com/articles/progressive-enhancement/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">“Progressive Enhancement. Still Alive &amp; Kickin’.</a>でSign, JavaScriptを始めた理由を説明した。
これらの反論に対して、Tom Dale氏は<a href="http://tomdale.net/2013/09/maybe-progressive-enhancement-is-the-wrong-term/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Maybe Progressive Enhancement is the Wrong Term</a>にてプログレッシブ・エンハンスメントという言葉の意味は範囲を再確認している。
技術者的な視点だけではなく、デザイナからの視点でもこのトピックに対して様々な記事があがったりと、プログレッシブ・エンハンスメントそのものに対する興味関心の高さが分かるすばらしい議論となった。</p>

<h3><a href="http://stevelosh.com/blog/2013/09/teach-dont-tell/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">効果的なドキュメンテーションの作り方について &#8211; Steve Losh</a></h3>

<p><img src="/wp-content/uploads/2013/09/steve-losh-1024x768.png" alt="-steve-losh-1024x768" width="300" height="255" class="aligncenter size-full wp-image-2477" srcset="/wp-content/uploads/2013/09/steve-losh-1024x768.png 300w, /wp-content/uploads/2013/09/steve-losh-1024x768-207x175.png 207w" sizes="(max-width: 300px) 100vw, 300px" /></p>

<p>原題: Teach, Don&#8217;t Tell</p>

<p>Steve Losh氏によるテクニカル文書、主にプログラミング言語やライブラリなどのドキュメンテーションの書き方について、7つのアンチパターンを通して、よりよいドキュメントを書くために覚えておきたいことをまとめている。<br />
自分でオープンソースとしてライブラリなどを公開している方はもちろん、会社やチームのガイドラインを作成している人にも、勉強会などでプレゼンをする人にもおすすめできるすばらしいアドバイス。</p>

<h3><a href="https://eloquentjavascript.net/2nd_edition/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Eloquent JavaScript 第二版 &#8211; Marijn Haverbeke</a></h3>

<p><img src="/wp-content/uploads/2013/09/eloquent-javascript-second-edition-1024x768.png" alt="eloquent-javascript-second-edition-1024x768" width="300" height="255" class="aligncenter size-full wp-image-2483" srcset="/wp-content/uploads/2013/09/eloquent-javascript-second-edition-1024x768.png 300w, /wp-content/uploads/2013/09/eloquent-javascript-second-edition-1024x768-207x175.png 207w" sizes="(max-width: 300px) 100vw, 300px" /></p>

<p>原題: Eloquent JavaScript second edition</p>

<p>JavaScriptを学ぶ上で読んでおくべき書籍は?という質問には確実に名を連ねてくるのがMarijn Haverbeke氏による「Eloquent JavaScript」。解説だけではなく、実際に手を動かすエクササイズがあったりと、当時としては画期的な書籍で、さらにクリエイティブ・コモンライセンスでオンライン版は無料で公開されている。<br />
2007年に執筆されたこの本は、現在第二版に向けて執筆を始めている。筆者はその執筆のためにクラウド・ファンディングをしているので、興味がある方はぜひファンドに協力してみてはいかがだろう。</p>

<h3><a href="http://www.miscmagazine.com/great-design-always-means-great-style/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">すばらしいデザインは常にすばらしいスタイルである &#8211; MISC Magazine</a></h3>

<p><img src="/wp-content/uploads/2013/09/misc-magazine-great-design-always-means-great-style-1024x768.png" alt="misc-magazine-|-great-design-always-means-great-style-1024x768" width="300" height="255" class="aligncenter size-full wp-image-2488" srcset="/wp-content/uploads/2013/09/misc-magazine-great-design-always-means-great-style-1024x768.png 300w, /wp-content/uploads/2013/09/misc-magazine-great-design-always-means-great-style-1024x768-207x175.png 207w" sizes="(max-width: 300px) 100vw, 300px" /></p>

<p>原題: Great Design Always Means Great Style</p>

<p>Don Norman氏によるよいデザイン、よいスタイルについてのこの記事では、そもそもデザインにおけるスタイルとは単純な見た目のファッションではなく、パーソナリティのようなものではないかと説明。パーソナリティとは車でいうところのポルシェやBMV、メルセデス・ベンツのようなブランドに抱くイメージを分かりやすい例として紹介している。<br />
氏は記事を以下のように締めくくっている。
『すばらしいデザインとは常にすばらしいスタイルを意味する。正直で、理路整然としていて、一貫性があるものだ。』</p>

<h3><a href="https://dvcs.w3.org/hg/webperf/raw-file/tip/specs/ResourcePriorities/Overview.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">リソース・プライオリティ &#8211; W3C</a></h3>

<p><img src="/wp-content/uploads/2013/09/resource-priorities-1024x768.png" alt="resource-priorities-1024x768" width="300" height="255" class="aligncenter size-full wp-image-2491" srcset="/wp-content/uploads/2013/09/resource-priorities-1024x768.png 300w, /wp-content/uploads/2013/09/resource-priorities-1024x768-207x175.png 207w" sizes="(max-width: 300px) 100vw, 300px" /></p>

<p>原題: Resource Priorities</p>

<p>パフォーマンスは今ではインフラ担当の人間だけの問題ではなく、もちろんフロントエンド開発者だけの問題でもなく、全員の問題だ。<br />
その全員にはもちろんW3Cも含まれる。<br />
Resource Prioritiesという仕様はまだドラフト段階ではあるが、画像やスクリプト、ビデオやオーディオに対して、lazyloadやpostponeという属性を追加できるようにするものだ。<br />
これらの属性はJavaScriptを使ってすでに解決されつつある問題ではあるが、仕様として存在する意義は大きい。</p>

<h2>海外トレンドコラム</h2>

<h3><a href="http://www.nczonline.net/blog/2013/09/10/understanding-ecmascript-6-arrow-functions/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">ECMAScript 6のArrowファンクションについて &#8211; NCZOnline</a></h3>

<p><img src="/wp-content/uploads/2013/09/understanding-ecmascript-6-arrow-functions-nczonline-1024x768.png" alt="understanding-ecmascript-6-arrow-functions-|-nczonline-1024x768" width="300" height="255" class="aligncenter size-full wp-image-2494" srcset="/wp-content/uploads/2013/09/understanding-ecmascript-6-arrow-functions-nczonline-1024x768.png 300w, /wp-content/uploads/2013/09/understanding-ecmascript-6-arrow-functions-nczonline-1024x768-207x175.png 207w" sizes="(max-width: 300px) 100vw, 300px" /></p>

<p>原題: Understanding ECMAScript 6 arrow functions</p>

<p>ECMAScript 6で追加される予定のArrowファンクションについてNicolas Zakas氏による解説。<br />
Arrowファンクションはその名前の通り、関数のシンタックスを =&gt; このような矢印を使って置き換えることができるようになる。<br />
ただそれだけではなく、newができない、thisのバインディングが違うなどの点が異なる。</p>

<h3><a href="http://blogs.telerik.com/james-bender/posts/13-09-09/30-days-tdd-day-one-what-is-tdd" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">テスト駆動開発とはなにか、そしてどんなものなのか</a></h3>

<p><img src="/wp-content/uploads/2013/09/f2f340cc27327f56a607b57a4f283e07.png" alt="30-days-of-tdd:-day-one-–-what-is-tdd-and-why-should-i-use-it?-1024x768" width="300" height="255" class="aligncenter size-full wp-image-2478" srcset="/wp-content/uploads/2013/09/f2f340cc27327f56a607b57a4f283e07.png 300w, /wp-content/uploads/2013/09/f2f340cc27327f56a607b57a4f283e07-207x175.png 207w" sizes="(max-width: 300px) 100vw, 300px" /></p>

<p>原題: 30 Days of TDD: Day One – What is TDD and Why Should I Use It?</p>

<p>テスト駆動開発にについて、30日間連続で書き続けるチャレンジの1日目。第一回目は、そもそもテスト駆動開発とはどんなものか、そして、その開発ワークフローをどうして利用するべきなのかを解説。</p>

<h3><a href="http://www.stevesouders.com/blog/2013/09/05/domain-sharding-revisited/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">ドメイン・シャーディングをもう一度振り返ってみよう &#8211; High Performance Web Sites</a></h3>

<p><img src="/wp-content/uploads/2013/09/domain-sharding-revisited-high-performance-web-sites-1024x768.png" alt="domain-sharding-revisited-|-high-performance-web-sites-1024x768" width="300" height="255" class="aligncenter size-full wp-image-2482" srcset="/wp-content/uploads/2013/09/domain-sharding-revisited-high-performance-web-sites-1024x768.png 300w, /wp-content/uploads/2013/09/domain-sharding-revisited-high-performance-web-sites-1024x768-207x175.png 207w" sizes="(max-width: 300px) 100vw, 300px" /></p>

<p>原題: Domain Sharding revisited</p>

<p>パフォーマンスにおいて、SPDYやHTTP 2.0の時代が来るとアンチパターンになると言われている。だが、ドメイン・シャーディングというテクニックについて、スティーブ・サウダー氏は、そうとも言えないのではないかと話し、大抵のウェブサイトにおいては次の時代でも活用できるとしている。</p>

<h3><a href="http://www.shanehudson.net/2013/09/10/responsive-images-meeting-notes/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">レスポンシブ・イメージ会議メモ &#8211; Shane Hudson Dot Net</a></h3>

<p><img src="/wp-content/uploads/2013/09/responsive-images-meeting-notes-shane-hudson-dot-net-1024x768.png" alt="responsive-images-meeting-notes---shane-hudson-dot-net-1024x768" width="300" height="255" class="aligncenter size-full wp-image-2492" srcset="/wp-content/uploads/2013/09/responsive-images-meeting-notes-shane-hudson-dot-net-1024x768.png 300w, /wp-content/uploads/2013/09/responsive-images-meeting-notes-shane-hudson-dot-net-1024x768-207x175.png 207w" sizes="(max-width: 300px) 100vw, 300px" /></p>

<p>原題: Responsive Images Meeting Notes</p>

<p>9/10にパリで開かれたレスポンシブ・イメージに関する会議のメモ。若干散文的ではあるが、会議で話された内容について大事なポイントをおさえているので、非常に参考になる。先日、webkitにてsrcsetが実装されたが、レスポンシブな環境における画像の取り扱いについて、まだまだ課題は多い。今後も目が話せないトピックだ。</p>

<h3><a href="https://github.com/andreineculau/know-your-http-well" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">いまさら聞けないHTTP</a></h3>

<p><img src="/wp-content/uploads/2013/09/5ebe6ed3cbd7ffd9f21c8192915d65ae.png" alt="know-your-http-well-·-github-1024x768" width="300" height="255" class="aligncenter size-full wp-image-2487" srcset="/wp-content/uploads/2013/09/5ebe6ed3cbd7ffd9f21c8192915d65ae.png 300w, /wp-content/uploads/2013/09/5ebe6ed3cbd7ffd9f21c8192915d65ae-207x175.png 207w" sizes="(max-width: 300px) 100vw, 300px" /></p>

<p>原題: Know Your HTTP Well</p>

<p>もう本当にいまさら聞けないHTTPにまつわる話を、仕様やヘッダ、メディアタイプ(今後追加される様子)、メソッド、ステータスコードなどのように区分し、それぞれ詳しく解説している。あっという間に1000スターという人気のほどなので、いまさら聞けないのは私だけではなかったようです。</p>

<h3><a href="http://dev.opera.com/articles/view/mutation-observers-tutorial/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Mutation Observersの使い方 &#8211; Dev.Opera</a></h3>

<p><img src="/wp-content/uploads/2013/09/getting-to-know-mutation-observers-dev.opera-1024x768.png" alt="getting-to-know-mutation-observers---dev.opera-1024x768" width="300" height="255" class="aligncenter size-full wp-image-2485" srcset="/wp-content/uploads/2013/09/getting-to-know-mutation-observers-dev.opera-1024x768.png 300w, /wp-content/uploads/2013/09/getting-to-know-mutation-observers-dev.opera-1024x768-207x175.png 207w" sizes="(max-width: 300px) 100vw, 300px" /></p>

<p>原題: Getting to know mutation observers</p>

<p>JavaScriptが多く利用されるプロダクトの制作を行っているとあるDOMノードツリーが変わったタイミングを知りたいということはよくある。<br />
この記事で紹介をしているDOMレベル4仕様で定義されたMutation Observersは、これまで抱えてきた問題を解決してくれる。これまで利用してきたMutationEventとの違いを踏まえて、利用方法を解説。</p>

<h3><a href="http://gaslight.co/blog/does-coffeescript-have-a-future" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">CoffeeScriptに未来はあるのか?</a></h3>

<p><img src="/wp-content/uploads/2013/09/does-coffeescript-have-a-future-1024x768.png" alt="does-coffeescript-have-a-future?-1024x768" width="300" height="255" class="aligncenter size-full wp-image-2481" srcset="/wp-content/uploads/2013/09/does-coffeescript-have-a-future-1024x768.png 300w, /wp-content/uploads/2013/09/does-coffeescript-have-a-future-1024x768-207x175.png 207w" sizes="(max-width: 300px) 100vw, 300px" /></p>

<p>原題: Does CoffeeScript Have a Future?</p>

<p>CoffeeScriptはどんな役割を持った言語なのか、JavaScriptに変換される言語としてはよく使われる言語ではあるが、もしかするとJavaScriptそのものの変化にしたがって、もう必要がなくなるかも知れない。CoffeeScriptを愛してやまない著者のゆらぎを感じる非常にすばらしい記事。</p>

<h2>クローズアップ“ビデオ/スライド”</h2>

<h3><a href="http://www.youtube.com/watch?v=GNO_CYUjMK8" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">WebGLの基礎と応用 &#8211; Steven Wittens</a></h3>

<p><img src="/wp-content/uploads/2013/09/StevenWittensMakingWebGLDance.png" alt="StevenWittensMakingWebGLDance" width="300" height="255" class="aligncenter size-full wp-image-2493" srcset="/wp-content/uploads/2013/09/StevenWittensMakingWebGLDance.png 300w, /wp-content/uploads/2013/09/StevenWittensMakingWebGLDance-207x175.png 207w" sizes="(max-width: 300px) 100vw, 300px" /></p>

<p>原題: Making WebGL Dance</p>

<p><a href="https://html5experts.jp/cssradar/1995/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">前回の本連載</a>にてピックアップしたActo.netのSteve Wittens氏による、WebGLのイントロダクションビデオ。非常にベーシックな三角形から描画し、アンチエイリアスなどから始め、徐々に3Dの世界へ導いていく。数学的なアプローチは難しい部分も多いが、最終的なアウトプットを見ると、チャレンジする価値があると思わせるプレゼンテーション。</p>

<h3><a href="http://www.youtube.com/watch?v=x0VR3lUOpdc" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">ジャンク・バスターズ: Google Chromeにおけるレンダリングパフォーマンスについて &#8211; Nat Duca &amp; Tom Wiltzius</a></h3>

<p><img src="/wp-content/uploads/2013/09/NatDucaTomWiltziusJankBusters.png" alt="NatDucaTomWiltziusJankBusters" width="300" height="255" class="aligncenter size-full wp-image-2489" srcset="/wp-content/uploads/2013/09/NatDucaTomWiltziusJankBusters.png 300w, /wp-content/uploads/2013/09/NatDucaTomWiltziusJankBusters-207x175.png 207w" sizes="(max-width: 300px) 100vw, 300px" /></p>

<p>原題: Jank Busters &#8211; Chrome Rendering Performance</p>

<p>GoogleのNat Duca氏とTom Wiltzius氏によるJank Bustersシリーズのアップデート版。これまで両氏は何回か同じトピックでプレゼンテーションを行ってきているが、最新版にアップデートされたもの。アニメーションだけではなく、レンダリングプロセスを最適化するために知っておいたほうがよいことばかりをコンパクトに解説している。</p>

<h2>一歩先行く“コード”</h2>

<h3><a href="http://labs.bigroomstudios.com/libraries/animo-js" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">animo.js</a></h3>

<p><img src="/wp-content/uploads/2013/09/f247bd4f56e723017880fed026c25810.png" alt="animo.js-•-labs-by-big-room-studios-1024x768" width="300" height="255" class="aligncenter size-full wp-image-2479" srcset="/wp-content/uploads/2013/09/f247bd4f56e723017880fed026c25810.png 300w, /wp-content/uploads/2013/09/f247bd4f56e723017880fed026c25810-207x175.png 207w" sizes="(max-width: 300px) 100vw, 300px" /></p>

<p>jQuery依存が気にならない、ことはないが、Dan Eden氏作の<a href="http://daneden.me/animate/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">animation.css</a>をベースに、連続したアニメーションを行うのに非常にシンプルなシンタックスで可能にしている。</p>

<h3><a href="http://snorpey.github.io/jpg-glitch/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">JavaScriptでJPEG画像を壊してみよう</a></h3>

<p>原題: Image Glitch Experiment</p>

<p>正直なところ何の役に立つのかはわからないが、JavaScriptを使ってJPEG画像を破壊するツール。こういった実験的な実装は見ていて楽しいが、作るとより楽しいはず。</p>

<h3><a href="https://github.com/paulirish/frontend-feeds" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Paul Irishおすすめ。フロントエンド開発者のためのフィード</a></h3>

<p><img src="/wp-content/uploads/2013/09/00055ade3b88b9e6d4ef1879125cc369.png" alt="frontend-feeds-·-github-1024x768" width="300" height="255" class="aligncenter size-full wp-image-2484" srcset="/wp-content/uploads/2013/09/00055ade3b88b9e6d4ef1879125cc369.png 300w, /wp-content/uploads/2013/09/00055ade3b88b9e6d4ef1879125cc369-207x175.png 207w" sizes="(max-width: 300px) 100vw, 300px" /></p>

<p>原題: Frontend Feeds</p>

<p>私自身にとって、貴重な情報源であるGoogleのPaul Irish氏がまとめたフロントエンドデベロッパのためのフィード。<br />
以前にも彼はこの形式でフィードを共有していたが、今回はGitHub。Paulチョイスだけあって、非常にクオリティが高いのでおすすめ。</p>

<h2>海外で話題の“ツール”</h2>

<h3><a href="http://customelements.io/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Custom Element: モダンなWebアプリのためのWeb Componentsギャラリー</a></h3>

<p><img src="/wp-content/uploads/2013/09/custom-elements-a-web-components-gallery-for-modern-web-apps-1024x768.png" alt="custom-elements---a-web-components-gallery-for-modern-web-apps-1024x768" width="300" height="255" class="aligncenter size-full wp-image-2480" srcset="/wp-content/uploads/2013/09/custom-elements-a-web-components-gallery-for-modern-web-apps-1024x768.png 300w, /wp-content/uploads/2013/09/custom-elements-a-web-components-gallery-for-modern-web-apps-1024x768-207x175.png 207w" sizes="(max-width: 300px) 100vw, 300px" /></p>

<p>原題: Custom Elements &#8211; A Web Components Gallery for Modern Web Apps</p>

<p>まだまだ登録数は少ないが、Web ComponentsをGitHubのリポジトリから登録でき、検索可能にするギャラリーサイト。<br />
今後はコンポーネント数が増え、欠かすことができないツールになりえるかもしれない。</p>

<p>★次回の「斉藤祐也の海外WEBテク定点観測」は、9月30日にお届け予定です。★</p>
]]></content:encoded>
			</item>
		<item>
		<title>DOM操作の最適化によるJavaScriptチューニング（後編）</title>
		<link>/yoshikawa_t/1932/</link>
		<pubDate>Sun, 08 Sep 2013 22:00:47 +0000</pubDate>
		<dc:creator><![CDATA[吉川 徹]]></dc:creator>
				<category><![CDATA[プログラミング]]></category>
		<category><![CDATA[DOM]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[パフォーマンス]]></category>
		<category><![CDATA[ブラウザ]]></category>
		<category><![CDATA[高速化]]></category>

		<guid isPermaLink="false">/?p=1932</guid>
		<description><![CDATA[連載： パフォーマンスチューニング (5) 連載「Webサイト・アプリ高速化テクニック徹底解説」の第5回は、前回の「DOM操作の最適化によるJavaScriptチューニング（前編）」に続く後編です。後編では、create...]]></description>
				<content:encoded><![CDATA[<div class="seriesmeta">連載： <a href="https://html5experts.jp/series/performance-tech/" class="series-149" title="パフォーマンスチューニング" data-wpel-link="internal">パフォーマンスチューニング</a> (5)</div><p><style>.codecolorer-container+h3{margin-top:1.5em;}</style>
連載「Webサイト・アプリ高速化テクニック徹底解説」の第5回は、前回の「<a href="https://html5experts.jp/yoshikawa_t/1888/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">DOM操作の最適化によるJavaScriptチューニング（前編）</a>」に続く後編です。後編では、createElement()などのDOM操作メソッドを使ったさまざまなテクニックや、パフォーマンスを劣化させるよくあるパターンについて詳しく解説します。</p>

<div style="border: 1px solid gray; margin: 1em; padding: 1em;">
<article>
<h1>CodeIQとの連動企画！</h1>
この記事で学べるJavaScriptチューニングのテクニックを、実際に<a href="https://codeiq.jp/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">CodeIQ</a>の問題で試すことができます。もう既に自信がある方は腕試しに、もしくは理解度チェックのための復習として是非ご活用ください！<a href="https://codeiq.jp/ace/yoshikawa_t/q452" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">こちら</a>から問題にチャレンジ！
</article>
</div>

<!-- more -->

<h1>DOM操作の最適化によるJavaScriptチューニング（後編）</h1>

<p>前回は、DOM操作が遅い原因と仕組みについて簡単に説明し、チューニングのサンプルをいくつか解説しました。その中で、innerHTMLを利用したコードをサンプルにあげていますが、innerHTMLを利用する場合、いくつかの点で注意が必要です。</p>

<ul>
<li>HTMLの文字列を扱うため単純な子要素の追加ができない（子要素をすべて書き換えることになる）</li>
<li>追加する要素が多くなると、文字列連結のコストやHTMLをパースするコストが膨れ上がる</li>
<li>HTMLを直接扱うため、きちんとエスケープしないとクロスサイトスクリプティングの脆弱性を作りこむ可能性がある</li>
</ul>

<p>以上の点から、特に理由がなければinnerHTMLよりもDOM操作メソッドを使ったほうが良いでしょう。今回は、DOM操作メソッドを使ったさまざまなテクニックや、パフォーマンスを劣化させるよくあるパターンを紹介し、そのチューニング方法を見ていきます。</p>

<p>また、前回の記事のinnerHTMLを使ったサンプルでは、上に挙げたような複数の要因でパフォーマンスに影響与えていることから、レイアウト・レンダリングの遅さのみを理由とするには、あまり適切ではありませんでした（チューニング自体には問題はありませんので心配しないでください）。折を見て改訂したいと思います。ご指摘して頂いた方々、ありがとうございました。
本連載では、より良い情報を皆さんに届けるため、ご指摘や疑問点などがあれば是非フィードバックを頂ければと思います。フィードバックを受け、できるかぎり記事を更新していきたいと思います。</p>

<h2>DOM操作メソッドを使ったテクニック</h2>

<p>createElement()やappendChild()などのDOM操作メソッドを使った方法では、単純にinnerHTMLによるコードを置き換えるだけでなく、さまざまなテクニックがあります。ここでは、DOM操作メソッドを使う際に覚えておいた方がよいテクニックをいくつか紹介します。</p>

<h3>複数の要素をまとめて追加する</h3>

<p>複数の要素を追加する場合、構造によってはそのままでは一度に追加できないことがあります。例えば、次のサンプルのようにul要素にli要素を追加していくようなケースです。</p>

<pre><code>:javascript:
// サンプル1: ul要素にli要素を追加していく（低速）
var ul = document.querySelector('#output');
for ( var i = 0; i &lt; data.length; i++ ) {
  var li = document.createElement('li');
  li.textContent = data[i];

  // ループのたびにli要素を追加
  ul.appendChild(li);
}
</code></pre>

<p>このサンプルでは、ループのたびにli要素を追加していますので、DOMツリーへ更新が何度も発生します。こういった場合には、DocumentFragmentを利用して複数のli要素をまとめて追加することができます。次のコードは、DocumentFragmentを利用して書き換えたコードです。</p>

<pre><code>:javascript:
// サンプル1: ul要素にli要素をまとめて追加（高速）
var ul = document.querySelector('#output'),
    fragment = document.createDocumentFragment();

for ( var i = 0; i &lt; data.length; i++ ) {
  var li = document.createElement('li');
  li.textContent = data[i];

  // いったんDocumentFragmentに追加する
  fragment.appendChild(li);
}

// 最後にDocumentFragmentをul要素に追加する
ul.appendChild(fragment);
</code></pre>

<p>DocumentFragmentは、従来のDOMツリーとは分離された独立した小さなDOMツリーです。createDocumentFragment()メソッドを使って作成します。DocumentFragmentに追加された要素は、そのままでは見た目に影響を与えないため、まずはDocumentFragmentにli要素を追加していきます。そして、最後にul要素にそのDocumentFragmentを追加し、反映します。こうすることで、元のDOMツリーへの更新が1回だけで済みます。</p>

<h3>繰り返し同じような要素を追加する（テンプレート化）</h3>

<p>同じような要素を繰り返し追加する場合、要素をまた一から作成していくのは面倒です。また、要素が多くなってくるとパフォーマンス的にもあまり良くありません。例えば、ボタンが押されるたびに、次のような構造を持つli要素を追加していくことを考えてみましょう。</p>

<pre><code>:html:
&lt;li&gt;
  &lt;artcile class="item"&gt;
    &lt;h1 class="title"&gt;アイテム&lt;/h1&gt;
    &lt;p class="detail"&gt;詳細&lt;/p&gt;
  &lt;/artcile&gt;
&lt;/li&gt;
</code></pre>

<p>これを素直にDOM操作メソッド使って構築すると次のようにボタンが押されるたびに毎回要素を生成して構築する形になります。</p>

<pre><code>:javascript:
// ボタンがクリックされる度に複雑な要素を追加
button.addEventListener('click', function(){

  // 各要素を生成
  var li = document.createElement('li'),
      article = document.createElement('article'),
      h1 = document.createElement('h1'),
      p = document.createElement('p');

  // 各要素のプロパティを設定し、組み立てる（省略）

  ul.appendChild(li);
}, false);
</code></pre>

<p>サンプルでは、コードが多い部分を省略していますが、多くのDOM操作をしています。このような場合、構築される要素をテンプレート化して、それをcloneNode()を使ってコピーするようにすれば、DOM操作の数を減らすことができます。cloneNode()を利用すると次のようなコードになります。</p>

<pre><code>:javascript:
// テンプレートとしてli要素を構築
var template = document.createElement('li'),
    article = document.createElement('article'),
    h1 = document.createElement('h1'),
    p = document.createElement('p');

// 各要素のプロパティを設定し、組み立てる（省略）

// ボタンがクリックされる度にテンプレートから要素を追加
button.addEventListener('click', function(){

  // テンプレートから要素をコピー
  var li = template.cloneNode(true);

  // 一部書き換えて追加
  li.querySelector('.title').textContent = 'アイテム';
  li.querySelector('.detail').textContent = 'アイテムの詳細'
  ul.appendChild(li);
}, false);
</code></pre>

<p>こうすると、ボタン押すたびにテンプレートからコピーするだけなので効率的です。構築する要素が複雑になればなるほど、cloneNode()を利用する方が高速になります。cloneNode()の引数は、子要素を一緒にコピーするかどうかなので、trueを指定しておきます。また、cloneNode()ではイベントリスナーをコピーすることはできませんので注意してください。</p>

<h3>複数の要素をまとめて置き換える</h3>

<p>既に表示されているインターフェースに対して最新の情報を反映するような場合があるかと思います。その際に、表示するデータが細かいとDOM操作も細かくなってしまうことがあります。例えば、次のようなHTMLの各p要素の内容を書き換えることを考えてください。</p>

<pre><code>:html:
&lt;div class="results"&gt;
  &lt;p&gt;結果1&lt;/p&gt;
  &lt;p&gt;結果2&lt;/p&gt;
  &lt;p&gt;結果3&lt;/p&gt;
&lt;/div&gt;
</code></pre>

<p>これを単純に書き換える場合は、次のようなコードになりがちです。</p>

<pre><code>:javascript: 
var elements = document.querySelectorAll('.results p');
elements[0].textContent = '結果a';
elements[1].textContent = '結果b';
elements[2].textContent = '結果c';
</code></pre>

<p>この場合、3つのp要素を順に書き換えているので、DOMツリーへの更新が3回発生してしまいます。このような場合、replaceChild()を使って一度に置き換えることができます。</p>

<pre><code>:javascript:
var origin = document.querySelector('.results'),
    clone = origin.cloneNode(true);

// コピーした要素を更新する
var elements = clone.querySelectorAll('p');
elements[0].textContent = '結果a';
elements[1].textContent = '結果b';
elements[2].textContent = '結果c';

// 元の要素とコピーした要素を入れ替える
origin.parentNode.replaceChild(clone, origin);
</code></pre>

<p>この方法であれば、DOMツリーへの更新は1回で済みます。また、先ほどのサンプルと同様にcloneNode()がイベントハンドラーをコピーできないことに注意しましょう。</p>

<h2>パフォーマンスを劣化させるよくあるパターン</h2>

<p>ここからは、パフォーマンスを劣化させるよくあるパターンや、そのチューニング方法を紹介します。</p>

<h3>複数のスタイルの書き換え</h3>

<p>ある要素のスタイルを複数書き換える場合に、ついやってしまいがちなのが次のコードです。</p>

<pre><code>:javascript:
// 複数のスタイルの書き換え（低速）
element.style.background = 'gray';
element.style.border = '1px solid black';
</code></pre>

<p>この場合も、レイアウトが複数発生する可能性があるので、次のように記述しましょう。</p>

<pre><code>:javascript:
// 複数のスタイルの書き換え（高速）
// style属性で一度にすべて指定する
element.setAttribute('style', 'background: gray; border: 1px solid gray;');
</code></pre>

<p>setAttribute()を使ってsytle属性を使って一度に複数のスタイルを指定しています。また、あらかじめ指定するスタイルがある程度決っているなら、可読性やメンテナンスを考えてclass属性を使っても良いでしょう。</p>

<pre><code>:javascript:
// classを指定して複数のスタイルを適用する
element.className = 'hoge';
</code></pre>

<h3>アニメーション</h3>

<p>ある要素の位置やサイズを動かしてアニメーションさせるような場合、スタイルでposition: absoluteやpositon: fixedを指定しておくと良いでしょう。これは、レイアウト・レンダリングの範囲を最少化するためです。position: absoluteなどを指定すると他の要素との位置関係やサイズ計算から切り離されるため、その要素に対する変更が他の要素に影響しなくなります。そのため、レイアウト・レンダリングのコストが小さくなり、パフォーマンスが向上します。アニメーションのチューニングについては、また別の記事で触れますので楽しみにしていてください。</p>

<h3>スタイル情報の取得</h3>

<p>多くのDOM操作によるスタイル情報の取得の中でも、次に挙げるプロパティ、メソッドについては特に注意が必要です。</p>

<ul>
<li>getComputedStyle()</li>
<li>offset*系のプロパティ</li>
<li>client*系のプロパティ</li>
<li>scroll*系のプロパティ</li>
</ul>

<p>（offset*系のプロパティとは、offsetという単語を含むoffsetTop、offsetLeft、offsetHeight、offsetWidthなどのプロパティです）</p>

<p>これらのプロパティ、メソッドは、現時点での最新の情報を返そうとするため、それまでに実行したDOM操作があれば、すぐさまレイアウト・レンダリングを実行します。本来であればブラウザが自動的に最適化し、非同期に実行しているものを強制的に実行してしまうため大きなボトルネックになります。例えば、あるブロックを単純に右に動かすだけのコードを見てみましょう。</p>

<pre><code>:javascript:
// あるブロックを右に動かす
setInterval(function(){
  block.style.left = block.offsetLeft + 1 + 'px';
}, 1000 / 60 );
</code></pre>

<p>ここでは、あるブロックのoffsetLeftを取得し、1を加えてスタイルのleftに代入しています。leftの値を更新した後に、またすぐにoffsetLeftを参照しているので、その時点でレイアウト・レンダリングが発生し、遅くなります。そのため、offsetLeftの値をキャッシュしておき、以降はそれを利用するように変更しましょう。</p>

<pre><code>:javascript:
// あるブロックを右に動かす
// offsetLeftの値を一度キャッシュして以降は使いまわす
var left = block.offsetLeft;
setInterval(function(){
  left++;
  block.style.left = left + 'px';
}, 1000 / 60 );
</code></pre>

<p>このように、上記であげたプロパティ、メソッドは、多くのDOM操作をしているような箇所では特にボトルネックになりやすいので注意しましょう。（サンプルでは、JavaScriptを使っていますが、もちろんCSSで記述しても良いでしょう。）</p>

<h3>要素の取得</h3>

<p>それほど気にするほどの差ではありませんが、要素を取得する際にquerySelector()やquerySelectorAll()よりも、getElementById()やgetElementsByTagName()、getElementsByClassName()を利用した方が若干速くなります。</p>

<pre><code>:javascript:
// div要素をすべて取得
var elements = document.querySelectorAll('div');

// querySelectorAll()よりも若干速い
var elements = document.getElementsByTagName('div');
</code></pre>

<p>その他の違いにも、getElementsByTagName()などは、結果として返るリスト（NodeList）が常に現在のDOMツリーを反映したものになるのに対して、querySelectorAll()などは取得した時点のものになります。例えば、これらのメソッドで要素を取得した後に、要素が追加された場合、getElementsByTagName()で取得したリストではリストにその要素が自動的に追加されますが、querySelectorAll()ではリストに変化はありません。そういった違いも覚えておくと良いでしょう。</p>

<h2>まとめ</h2>

<p>ここまで前編、後編にわたってDOM操作の最適化について解説しました。いくつかのサンプルやパターンを交えて、チューニング方法を紹介してきましたが、もちろんこれ以外にもたくさんのテクニックがあります。細かいテクニックをあげていくときりがありませんが、重要なのはDOM操作自体の回数を減らすことと、DOMツリーへの更新とレイアウトやレンダリングなどの範囲、回数を減らすことです。それさえ覚えておけば、自分でいろいろなコードに応用できるかと思います。自分自身で考えてチューニングしていきましょう。</p>
]]></content:encoded>
		
		<series:name><![CDATA[パフォーマンスチューニング]]></series:name>
	</item>
		<item>
		<title>DOM操作の最適化によるJavaScriptチューニング（前編）</title>
		<link>/yoshikawa_t/1888/</link>
		<pubDate>Wed, 04 Sep 2013 22:00:03 +0000</pubDate>
		<dc:creator><![CDATA[吉川 徹]]></dc:creator>
				<category><![CDATA[プログラミング]]></category>
		<category><![CDATA[DOM]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[パフォーマンス]]></category>
		<category><![CDATA[ブラウザ]]></category>
		<category><![CDATA[高速化]]></category>

		<guid isPermaLink="false">/?p=1888</guid>
		<description><![CDATA[連載： パフォーマンスチューニング (4)連載「Webサイト・アプリ高速化テクニック徹底解説」の第4回は、JavaScriptのチューニングのうち、ボトルネックになりやすいDOM操作の最適化について解説します。前編・後編...]]></description>
				<content:encoded><![CDATA[<div class="seriesmeta">連載： <a href="https://html5experts.jp/series/performance-tech/" class="series-149" title="パフォーマンスチューニング" data-wpel-link="internal">パフォーマンスチューニング</a> (4)</div><p>連載「Webサイト・アプリ高速化テクニック徹底解説」の第4回は、JavaScriptのチューニングのうち、ボトルネックになりやすいDOM操作の最適化について解説します。前編・後編にわたって、DOM操作が遅くなる原因と仕組み、その解決策について詳しく解説します。</p>

<div style="border: 1px solid gray; margin: 1em; padding: 1em;">
<article>
<h1>CodeIQとの連動企画！</h1>
この記事で学べるJavaScriptチューニングのテクニックを、実際に<a href="https://codeiq.jp/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">CodeIQ</a>の問題で試すことができます。もう既に自信がある方は腕試しに、もしくは理解度チェックのための復習として是非ご活用ください！<a href="https://codeiq.jp/ace/yoshikawa_t/q452" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">こちら</a>から問題にチャレンジ！
</article>
</div>

<!-- more -->

<h1>DOM操作の最適化によるJavaScriptチューニング（前編）</h1>

<p>DOM（Document Object Model）とは、HTMLをアプリケーション（ここではJavaScript）から利用するためのAPIです。JavaScriptによるユーザーインターフェースの構築やレスポンスの表示など、インタラクティブな部分はほとんどがDOM操作によるものでしょう。このように、非常に利用頻度の高いDOM操作ですが、同時に性能的にボトルネックになりやすい箇所でもあります。これらのDOM操作の最適化について、今回から前編・後編にわたって詳しく解説していきます。</p>

<h2>DOM操作は書き方によってスピードに数十倍の差が出る</h2>

<p>DOM操作は、書き方によって非常にパフォーマンスに差が出ます。例えば、次のようなコードを見てみましょう。id属性に&#8221;output&#8221;と指定された要素に、data配列の中身を単純にリスト表示するだけのものです。</p>

<pre><code>:javascript:
// サンプル1: パフォーマンスが悪い
var ul = document.querySelector('#output');
for ( var i = 0; i &lt; data.length; i++ ) {
  ul.innerHTML += '&lt;li&gt;' + data[i] + '&lt;/li&gt;';
}
</code></pre>

<p>これは、非常にパフォーマンスが悪い例です。これを次のように書き換えるだけで、環境にもよりますが速度は数十倍にもなります。</p>

<pre><code>:javascript:
// サンプル2: サンプル1に比べてパフォーマンスが良い
var ul = document.querySelector('#output');
var html = '';
for ( var i = 0; i &lt; data.length; i++ ) {
  html += '&lt;li&gt;' + data[i] + '&lt;/li&gt;';
}
ul.innerHTML = html;
</code></pre>

<p>このように、ボトルネックとなっているDOM操作をチューニングすれば、パフォーマンスが大きく改善する可能性があります。ここからは、DOM操作が遅くなる原因と仕組みを解説しながら、対応策を見ていきます。</p>

<h2>なぜDOM操作は遅いのか？</h2>

<p>DOM操作はなぜ遅いのでしょうか。それには、大きく2つの理由があります。1つ目は、DOMの実装方法によるものと、2つ目は、DOM操作によるレンダリングのコストが非常に高いということが挙げられます。この2つの理由と対応方法を覚えておけば、さまざまなコードに応用できます。それぞれ見ていきましょう。</p>

<h3>ブラウザの実装による遅さ</h3>

<p>元々DOMは、特定のプログラミング言語を対象としたものではなく、別々の言語から汎用的にアクセスできるような仕様になっています。そのため、多くのブラウザでは、HTMLのレイアウトや描画を担当するレンダリングエンジンと、JavaScriptを担当するスクリプトエンジンに分かれています。このようにスクリプト部分をモジュール化することによってDOM操作に別のプラグラミング言語を使うことも容易になっています。しかしながら、そのデメリットとして、JavaScriptからDOM操作を行うということは、モジュール間をブリッジするコストが発生することにもなります。そのため、DOM操作自体がプリミティブな操作に比べて非常に低速になっています。そういった観点から、HTMLの要素の単純なプロパティ参照なども含めて、極力DOM操作を減らすようにすることが重要です。</p>

<h3>レイアウト・レンダリングによる遅さ</h3>

<p>DOM操作の結果は、実際のHTMLに反映される際に、ブラウザでさまざまな処理が起こります。例えば、要素が追加された場合には、それによって発生する各要素の大きさや位置といったレイアウトを他の影響する要素を含めて、すべて再計算しなければなりません。また、レイアウトの再計算が終わったあとには、それらを画面にレンダリングする必要もあります。そして、これらの処理は非常にコストが高いものです。そのため、DOM操作によってレイアウトやレンダリングに影響がある範囲、回数をなるべく減らす必要があります。</p>

<p>例えば、冒頭に示したサンプル1のコードでは、次のようにli要素をループが回るたびに追加しているため、レイアウトとレンダリングが何回も発生して非常に遅くなってしまう可能性があります（レイアウトやレンダリングは非同期で処理されるため、実際にはブラウザがある程度、自動的に最適化してくれます）。</p>

<pre><code>:javascript:
// 複数回、レイアウト、レンダリングされる可能性がある
for ( var i = 0; i &lt; data.length; i++ ) {
  ul.innerHTML += '&lt;li&gt;' + data[i] + '&lt;/li&gt;';
}
</code></pre>

<p>innerHTMLを利用しているため、少なくてもHTMLのパースはループのたびに発生します。また、古いブラウザでは文字列の連結自体が問題になることもあります。このコードを、レイアウトとレンダリングが1回になるように書き換えると次のようになります。（その他にも、innerHTMLを「+=」演算子で余分に参照していることや、innerHTMLの中身を毎回すべて書き換えていることも遅さの原因になっていますが、次のコードではそれらも改善しています。）</p>

<pre><code>:javascript:
// 変数にHTMLを格納しておき最後に1回だけ書き換える
var html = '';
for ( var i = 0; i &lt; data.length; i++ ) {
  html += '&lt;li&gt;' + data[i] + '&lt;/li&gt;';
}
ul.innerHTML = html;
</code></pre>

<p>最終的に、結果が表示されれば良いので、li要素のHTMLは、いったん別の変数に格納しておき、最後に1回だけinnerHTMLへ代入しています。これによって、DOM操作の回数もレンダリングの回数も以前のコードに比べて1回で済みます。</p>

<h2>innerHTMLとDOM操作メソッド</h2>

<p>ここまでのサンプルでは、innerHTMLを使ってDOM操作を記述していますが、createElement()やappendChild()などのDOM操作メソッドを使う方法もあります。次のサンプルは、サンプル2をDOM操作メソッドを利用して記述した例です。</p>

<pre><code>:javascript:
// サンプル3: createElement()を使った例
var ul = document.querySelector('#output');
var fragment = document.createDocumentFragment();
for ( var i = 0; i &lt; data.length; i++ ) {
  var li = document.createElement('li');
  li.textContent = data[i];
  fragment.appendChild(li);
}
ul.appendChild(fragment);
</code></pre>

<p>innerHTMLとDOM操作メソッドは、それぞれ良い点がありますが、基本的にはDOM操作メソッドを使っていくほうがクロスサイトスクリプティングの脆弱性を作りこみにくいので安全です（innerHTMLは、文字列をパースするためユーザーの入力値を使う場合はエスケープする必要があります）。これらのDOM操作メソッドを利用する方法は、次回で詳しく取り上げていきます。</p>

<h3>innerHTMLとDOM操作メソッドのスピード</h3>

<p>innerHTMLとcreateElement()などのDOM操作メソッドは、どちらが速いかといった形でよく比較されることが多いですが、パフォーマンスという観点からはそれほど気にしなくても良いでしょう。モダンな環境では、お互いの速度差はそれほど大きくありませんし、ブラウザは常にバージョンアップされていますのでベンチマークの結果はすぐに変わります。特定の環境に特化したチューニングを行うのでなければ、細かい速度差を気にするよりは、機能の違いで使い分けていきましょう（ちなみに、現在はIE、FirefoxはinnerHTMLの方が若干速く、Chrome、SafariはDOM操作メソッドの方が若干速くなっています）。</p>

<h2>次回の内容について</h2>

<p>今回は、DOM操作が遅くなる理由と、その対処方法について簡単に解説しました。次回は、createElement()によるDOM操作と、チューニングのためのさまざまなTipsを紹介していく予定です。お楽しみに！</p>
]]></content:encoded>
		
		<series:name><![CDATA[パフォーマンスチューニング]]></series:name>
	</item>
	</channel>
</rss>
