ホームページ > 記事 > ウェブフロントエンド > Web ページのパフォーマンスを向上させるためのヒント_html/css_WEB-ITnose
最近では、ページの読み込みサイズが数メガバイトになることが多く、パフォーマンスの最適化が避けられないホットなテーマになっています。 WEB アプリケーションがスムーズになればなるほど、ユーザー エクスペリエンスが向上し、アクセス数も増加します。つまり、美しすぎる CSS3 アニメーションや複数操作の DOM 要素がパフォーマンスへの影響を考慮しているかどうかを反省する必要があります。パフォーマンスの最適化について話す前に、ブラウザーのビジュアル描画における 2 つの用語を明確にする必要があります:
再描画: 一部の操作が DOM 要素の表示に影響を与えるが、レイアウトには影響しない場合、不透明度、背景などのブラウザーの再描画が発生します。 -色、可視性、アウトラインのプロパティ。ブラウザは DOM 内のすべてのノードの可視性をチェックする必要があるため、再描画は非常に重いロジックです。一部のレイヤーは再描画された要素のレイヤーの下に配置される可能性があります。
リフロー (リフロー): リフローはより破壊的な操作であり、ブラウザーがすべての要素の座標位置とサイズを再計算します。多くの場合、1 つの要素を変更すると、その子要素、親要素、隣接する要素も変更されます。
ユーザーまたはアプリケーション自体が何らかのロジックを実行しているかどうかに関係なく、これら 2 つの操作はブラウザーのプロセスをブロックします。極端な場合には、CSS の影響により JavaScript の実行が遅くなる可能性があります。以下は、リフロー イベントをトリガーするいくつかのシナリオです:
ブラウザの基礎となる実装は次のとおりです。異なるため、ページのレンダリングのオーバーヘッドも異なります。幸いなことに、パフォーマンスを最適化するための一般的なルールがいくつかあります。
2015 年になった今でも、私はインライン スタイルとテーブル レイアウトを使用しないと言っています。
HTML ドキュメントがダウンロードされると、インライン スタイルによって追加のリフロー イベントがトリガーされます。パーサーはテーブル レイアウトを解析するときに多数のセルのサイズを計算する必要があるため、重い操作になります。多くの場合、セルはテーブル ヘッダーの幅に基づいて決定されるため、table-layout:fixed を使用すると、パフォーマンスの消費を一部軽減できます。
Flexbox レイアウトを使用する場合は、ページのロード後にフレックス項目の位置とサイズが変更される可能性があるため、パフォーマンスが低下します。
スタイルの数が少ないほど、リフローが速くなります。また、過度に複雑なセレクターを使用しないようにしてください。この問題は、Bootstrap などのフレームワークを使用する Web サイトで特に深刻です。未使用の CSS、uCSS、grunt-uncss、gulp-uncss などのツールを使用して、無駄なスタイルを効果的に削除します。
DOM 階層の合理化とは、DOM ツリーのレベル数と各ブランチの DOM 要素の数を減らすことを指し、その結果、レベルと数が少なくなるほどリフローが速くなります。さらに、古いブラウザを考慮する必要がない場合は、無意味なパッケージのタグと階層を削除するように努める必要があります。
DOM ツリーを操作するときの粒度は可能な限り細かくする必要があり、これにより、ローカルの DOM 変更が全体に及ぼす影響を軽減できます。
アニメーションを使用する要素がドキュメント フローの外にあることを確認する必要があります。position:Absolute 属性と Position:Fixed 属性を使用する要素は、これらのレイヤーを変更しても、他のレイヤーの要素には影響しません。
表示: なしを使用すると、非表示の要素はページの再描画イベントやリフロー イベントをトリガーしないため、これらの要素が非表示になっている間にスタイルを設定し、その後、それらを表示状態に変換できます。設定が完了しました。
すべての DOM 要素を 1 語で更新する方が、複数回更新するよりもパフォーマンスが向上します。次のコードは 3 つのページ リフローをトリガーします:
var myelement = document.getElementById('myelement');myelement.width = '100px';myelement.height = '200px';myelement.style.margin = '10px';
次のコードは 1 つのページ リフロー イベントに減らすことができ、コードの保守性が向上します:
var myelement = document.getElementById('myelement');myelement.classList.add('newstyles');.newstyles { width: 100px; height: 200px; margin: 10px;}
同様に、DOM 操作の頻度も減らすことができます。以下に示すような順序なしリストを作成するとします。
各項目をバッチで追加すると、複数のページのリフローがトリガーされます。簡単で効率的な方法は、DOM フラグメントを使用してメモリ内に完全な DOM ノードを作成することです。それをすぐに DOM に追加します:
var i, li, frag = document.createDocumentFragment(), ul = frag.appendChild(document.createElement('ul'));for (i = 1; i <= 3; i++) { li = ul.appendChild(document.createElement('li')); li.textContent = 'item ' + i;}document.body.appendChild(frag);
这里的约束是指,尽量避免某个元素的变化引起大范围的变化。假设我们有一个 tab 选项卡的组件,选项卡内部的内容长短不一,这就导致了每个选项卡的高度不唯一。这一设计带来的问题就是每次切换选项卡时,周围的元素都要重新布局。我们可以通过一个固定高度来避免这一情况。
一次移动一像素的位置看起来虽然很流畅,但对于某些低性能终端会是很大的压力。一次移动四像素降低帧速虽然看起来稍有些迟钝,但性能压力降低了。这就是需要我们权衡的地方:流畅度和性能。
目前主流浏览器都在开发者工具中提供了监控页面重绘的功能。在 Blink/Webkit 内核的浏览器中,使用 Timeline 面板可以记录一个页面活动详情:
下面是火狐开发者工具中的 TimeLine:
在 IE 中这个功能被放置在了 UI Responsiveness 面板中:
所有的浏览器都使用绿色来显示页面重绘和页面回流事件。上面的测试只是几个简单的示例,其中没有调用繁重的动画效果,所以布局渲染在总时间中占据了较大比重。减少页面回流和页面重绘,自然提高页面性能。
本文根据 @Craig Buckler 的《 10 Ways to Minimize Reflows and Improve Performance 》所译,整个译文带有我们自己的理解与思想,如果译得不好或有不对之处还请同行朋友指点。如需转载此译文,需注明英文出处: http://www.sitepoint.com/10-ways-minimize-reflows-improve-performance/ 。
前端开发者,关注性能优化和动效设计,活跃于 Github @pinggod 、微博@ping4god 和博客 pinggod.com ,替身众多。如果你沉醉于 Kairosoft、午时三刻工作室的游戏,请来和我做朋友:)。