この記事では、ファッショナブルなウェブサイトのデザイン方法と、浅いものから深いものまで、HTML5 とブラウザーのレンダリング機構を通じて高パフォーマンスのサイトを構築する方法を紹介します。 & ブラウザの再描画とパフォーマンス最適化の原理も本文に含まれており、「WEB ローリングパフォーマンス最適化の現実」の拡張と継続でもあります。 読む前にこの記事を読んでください。 。站 はじめに 差ビジョン Web サイトが最近大流行しています。次のサイトをご覧ください:
OLD PULTENEY ROW to the Pole
Adidasスノーボード EBBC NEWSエイムズ・ボンド: 車、キャッチフレーズ、キス
ご存知ない方もいるかもしれませんが、これらは実際には、ローリングによってページの視覚的な構造が変化するステーションです。通常の状況では、ページ上の要素は拡大縮小、回転、またはスクロール位置への移動が行われます。
私たちの視差効果デモページ 視差ウェブサイトが好きかどうかは別問題ですが、私たちが確認できるのは、これは間違いなくパフォーマンスのブラックホールであるということです。その理由は、スクロールすると、ブラウザーは新しいコンテンツが表示される場所 (スクロールの方向に基づいて) のパフォーマンスの最適化を実行しようとするためであり、一般に、ブラウザーの視覚的な更新が少ないほど良いためです。これはパララックス Web サイトではまれです。大きな視覚要素がページ全体で何度も変更され、ブラウザーがページ全体を再描画する必要があるからです (これがパフォーマンス ブラックホールである理由については、私の記事「Web スクロール パフォーマンス最適化の実践」を参照してください) ")。 parallallaxのWebサイトの存在は、次の特性として要約できます。1。ページを上または下にスクロールするとき、背景要素は位置、回転またはスケールを変更します。
2. テキストや小さな画像などのページ コンテンツは、特別な上から下へスクロールします。おそらくこれがほとんどの人が選択する方法です。ページ上には多くの要素があり、スクロール イベントがトリガーされると、これらの要素で多くの視覚的な更新が発生します。ここではデモページを紹介します。
開発者ツールのタイムラインでフレーム モードを有効にして上下にスクロールすると、負荷の高い全画面描画操作に気づくでしょう。複数回スクロールすると、1 つのフレームに複数のスクロール イベントが表示され、それぞれがレイアウト作業をトリガーすることがあります。開発者ツールは、1 つのフレーム内に多数の描画操作と複数のイベントトリガーのレイアウトを表示します
60fps (一般的なモニターのリフレッシュ レートの 60Hz に一致) を達成するには、次の点に留意することが重要です。すべては約 16 ミリ秒以内に完了する必要があります。この最初のバージョンでは、スクロール イベントを取得するたびに視覚的な更新を実行する必要がありますが、以前の記事「requestAnimationFrame を使用して単純なアニメーションを実装する」および「Web スクロールのパフォーマンス最適化の実践」で説明したように、これは矛盾しています。ブラウザの更新リズム。そのため、フレームを見逃したり、1 つのフレームで多くの作業を完了したりすることになります。これにより、サイトが不快で不自然に見えやすくなり、ユーザーの不満につながる可能性があります。
ビジュアル更新コードをスクロール イベントから
requestAnimationFrameコールバックに移動し、スクロール イベントのコールバックでスクロール値を取得するだけです。この変更は 2 番目のデモで実証します。
ローリングテストを繰り返すと、それほどではありませんが、わずかな改善に気づく場合があります。その理由は、スクロールによってトリガーされるレイアウト操作は負荷が高く、現在はフレームごとに 1 回だけレイアウト操作を実行するためです。
開発者ツールは、1 つのフレーム内に多数の描画操作と複数のイベントトリガーのレイアウトを表示します
フレームごとに 1 つまたは数百のスクロール イベントを処理できるようになりましたが、最も重要なのは、最新のスクロールを保存するだけであるということです。 requestAnimationFrame コールバックがトリガーされ、視覚的な更新を実行するときに使用される値。重要なのは、スクロール イベントを受信するたびに視覚的な更新を最適化するのではなく、ブラウザーから与えられた適切なタイミングで視覚的な更新を最適化するようになったということです。これはかなり強力だと思いますか?
このアプローチの主な問題は、requestAnimationFrameを使用するかどうかに関係なく、基本的にページ全体のレイヤーを生成することになり、これらの視覚要素を移動するときに大規模でコストのかかる再描画が必要になることです。通常、再描画はブロック操作です (ただし、これは最適化されます)。つまり、ブラウザーは他の作業を同時に行うことができず、ブラウザーのフレーム処理時間制限である 16 ミリ秒を超えることがよくあり、これはパフォーマンスの遅れが生じることを意味します。デイトンの状況。
方法 2: DOM 要素と 3D 変換を使用する
絶対配置に加えて、使用できるもう 1 つの方法は 3D 変換 (トランスフォーム) です。この場合、3D Transform で処理された各要素が新しいレイヤーを生成することがわかります。対照的に、方法 1 では、何か変更があった場合にページの大部分を再描画する必要があります。メソッド これは、このメソッドの使用法が大きく異なることを意味します。3D 変換を適用した任意の要素のレイヤーを持つことができます。より多くの要素を変換してこれを行う場合、レイヤーを再描画する必要はなく、GPU は要素の移動とページ全体の合成を処理できます。もしかしたら、なぜ 3D ではなく 3D 変換が使用されるのか疑問に思っているかもしれません。その理由は、
2D変換では新しいレイヤーの取得が保証されないのに対し、 3D 変換では確実に取得されるためです。 これは 3D 変換を使用した別のデモです。スクロールすると、パフォーマンスが大幅に向上していることがわかります。 多くの場合、人々は -webkit-transform:translateZ(0)
テクニックを使用し、素晴らしいパフォーマンスの向上を確認できます (Yujie の注: このメソッドに関しては、実際には 3D 変換を使用してブラウザのハードウェア アクセラレーションを有効にしています。これについて言及している国内の資料はほとんどありませんが、中国のモバイルアプリ開発パフォーマンスの最適化に関する記事は数多くあります。海外では「Improving HTML5 Web Page Performance」を読むことができます。また、海外では「IncreasingPerformance of HTML and JavaScript on Mobile」を読むことができます。 .デバイス」)。この方法は現在は正常に動作しますが、いくつかの問題が発生します: 1. ブラウザーと互換性がありません。 2. 変換された要素ごとにブラウザーに新しいレイヤーを作成させます。レイヤーの数が多いと他のパフォーマンスのボトルネックが生じる可能性があるため、レイヤーの使用は控えめにする必要があります。3. 一部の Webkit バージョンのポートでは無効になっています。
したがって、この方法を採用する場合は十分に注意する必要があります。これは問題の一時的な解決策です。完璧な世界であれば、私たちはそんなことについて考えることすらしないでしょうし、ブラウザは日々改良されているので、いつかそれが必要なくなるかどうかは誰にもわかりません。方法 3: 固定位置 Canvas または WebGL を使用する
考慮する必要がある最後の方法は、ページ上で固定位置 Canvas を使用し、その上に変換された画像を描画することです。一見すると、これは最も効率的なソリューションではないかもしれませんが、いくつかの利点があります:
ページには Canvas 要素が 1 つしかないため、多くの合成作業が必要なくなりました。ハードウェア アクセラレーションによって単一のビットマップを効率的に処理できます。
Canvas 要素を使用すると新しいレイヤーが得られますが、レイヤーは 1 つだけですが、方法 2 では 3D 変換が適用される要素ごとに新しいレイヤーを作成したため、合成されたこれらのレイヤーを変換するための追加の作業が必要になります。
このメソッドのデモンストレーションを見て、開発者ツールで観察すると、そのパフォーマンスがさらに優れていることがわかります。このメソッドでは、Canvas 上で drawImage API を呼び出し、背景画像を設定し、各カラー ブロックが画面上の正しい位置に描画されるようにするだけです。
/** * Updates and draws in the underlying visual elements to the canvas. */ function updateElements () { var relativeY = lastScrollY / h; // Fill the canvas up context.fillStyle = "#1e2124"; context.fillRect(0, 0, canvas.width, canvas.height); // Draw the background context.drawImage(bg, 0, pos(0, -3600, relativeY, 0)); // Draw each of the blobs in turn context.drawImage(blob1, 484, pos(254, -4400, relativeY, 0)); context.drawImage(blob2, 84, pos(954, -5400, relativeY, 0)); context.drawImage(blob3, 584, pos(1054, -3900, relativeY, 0)); context.drawImage(blob4, 44, pos(1400, -6900, relativeY, 0)); context.drawImage(blob5, -40, pos(1730, -5900, relativeY, 0)); context.drawImage(blob6, 325, pos(2860, -7900, relativeY, 0)); context.drawImage(blob7, 725, pos(2550, -4900, relativeY, 0)); context.drawImage(blob8, 570, pos(2300, -3700, relativeY, 0)); context.drawImage(blob9, 640, pos(3700, -9000, relativeY, 0)); // Allow another rAF call to be scheduled ticking = false; } /** * Calculates a relative disposition given the page’s scroll * range normalized from 0 to 1 * @param {number} base The starting value. * @param {number} range The amount of pixels it can move. * @param {number} relY The normalized scroll value. * @param {number} offset A base normalized value from which to start the scroll behavior. * @returns {number} The updated position value. */ function pos(base, range, relY, offset) { return base + limit(0, 1, relY - offset) * range; } /** * Clamps a number to a range. * @param {number} min The minimum value. * @param {number} max The maximum value. * @param {number} value The value to limit. * @returns {number} The clamped value. */ function limit(min, max, value) { return Math.max(min, Math.min(max, value)); }
このアプローチは、大きな画像 (またはキャンバス上に書きやすいその他の要素) や大きなテキスト ブロックを扱う場合には非常に困難です。しかし、あなたの Web サイトでは、それが最も適切な解決策であることが判明する可能性があります。 Canvas 上でテキストを処理する必要がある場合は、fillText API を使用するとよいでしょうが、アクセス コストがかかり (テキストをビットマップに変換しただけです!)、テキストの折り返しやその他の問題に対処する必要があります。これを避けるように努める必要があります。
ここまで議論してきましたが、視差を扱うために Canvas 要素を使用する必要があると考える理由はありません。ブラウザがサポートしている場合は WebGL を使用できます。ここで重要なのは、WebGL がすべての API からグラフィック カードへの最も直接的な方法であり、サイトのエフェクトが複雑な場合、パフォーマンスが 60 fps に達する可能性が最も高いということです。
最もすぐに感じられる反応は、WebGL を使用するのは過剰である、または広くサポートされていないということかもしれませんが、Three.js のようなライブラリを使用する場合は、コードを抽象化する機能を使用している間、いつでも Canvas 要素の使用にフォールバックできます。一貫したフレンドリーな態度。私たちがする必要があるのは、Modernizrを使用して、対応するAPIのサポートを検出することです。以下は、両方のレンダリング方法をサポートするデモです。
このアプローチの最後の問題は、ページに余分な要素を追加したくない場合、Firefox や Webkit ブラウザーでは常にキャンバスを背景要素として使用できることです。明らかに、これは普遍的に適用できるわけではないため、これについては注意する必要があります。
段階的な劣化
開発者が他の方法ではなく絶対配置要素をデフォルトで使用する主な理由は、単純にブラウザーのサポートの問題である可能性があります。古いブラウザでは非常に質の悪いレンダリング エクスペリエンスしか提供できないため、このアプローチはある程度間違っています。最新のブラウザでも、絶対位置指定を使用しても必ずしも良好なパフォーマンスが得られるわけではありません。
より良い解決策は、古いブラウザで視差効果を試行せず、最適なブラウザのみを使用して、サイト効果をレンダリングするために正しい API を使用できるようにすることです。もちろん、Three.js を使用する場合は、必要なサポートに応じてレンダラーを簡単に切り替えることができるはずです。估 結論
絶対配置要素から固定配置を使用するキャンバスまで、多数の再ペイント領域を処理するいくつかの方法を評価しました。もちろん、これを実装する方法は、達成しようとしているものと特定の設計によって異なりますが、オプションがあることを知っておくのは良いことです。この記事の例では、比較的遅い 30fps 未満の効果からスムーズな 60fps の効果まで最適化することができました。
以上がHTML5を使って高機能なパララックスサイトを構築するためのグラフィックとテキストコードを詳しく解説の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。