IntersectionObserver(feat.React)の使用
10709 ワード
IntersectionObserverの使い方が分かった以上、今は正式にウェブサイトに応用しなければなりません.
これはlazy loadingを適用する前のサイトの様子です.極端な例のために、ネットワークの状況をFast 3 Gに設定します.
Webページをロードすると、ページ上のすべての画像ファイルをダウンロードし、順番に表示されることを確認できます.
ページ内のすべての画像ファイルでIntersectionObserverを使用するには、各画像にObserverをアタッチし、IntersectionObserverを実行します.
ここで追加の問題が発生したのはreactrouterのためです.routerを使用して各ページを実装しましたが、このページのリフレッシュ中に画像をロードできないという問題が発生しました.
当初、
Lazy loadingを適用せずにWebPイメージを直接使用して最適化することを考慮すると、
既存の構造
これにより、さまざまなライフサイクルメソッドが使用できます.実際に、リフレッシュしてもコンポーネントDidMountメソッドが呼び出されることを確認しました.
最終クラスコンポーネントのコードは、次のようになります.
以前とは異なり、画像はロード前にロードされた画像を表示し、スクロール時にのみ必要な追加画像が表示されます.また、イメージはリフレッシュ時に正常にロードされます.
内容は複雑ではありませんが、実際のサイトに適用するには、思ったより時間がかかります.それに反応物の特性も問題になっているので、解決策を探しています.
しかし、このように解決した後、私は今本当に私のものだと思います!😁
問題の状況
これはlazy loadingを適用する前のサイトの様子です.極端な例のために、ネットワークの状況をFast 3 Gに設定します.
Webページをロードすると、ページ上のすべての画像ファイルをダウンロードし、順番に表示されることを確認できます.
IntersectionObserverの使用
ページ内のすべての画像ファイルでIntersectionObserverを使用するには、各画像にObserverをアタッチし、IntersectionObserverを実行します.
<img src={props.presrc} alt={props.label+' 이미지'} className="cards__item__img" data-lazy={props.src}/>
画像ラベルは以下のように設定されています.srcプロパティはプレースホルダ画像を指定し、実際に表示される画像はdata-lazyプロパティに指定します.const images = document.querySelectorAll("img");
const observer = new IntersectionObserver((entries, observer) => {
entries.forEach((entry) => {
if (!entry.isIntersecting) return;
const image = entry.target;
const src = image.getAttribute("data-lazy");
image.setAttribute("src", src);
observer.unobserve(image);
})
images.forEach((image) => {
observer.observe(image);
})
前述したように、すべての画像に1人の観察者を追加し、isIntersection法により画像のsrc属性を変更します.React Routerでの使用
ここで追加の問題が発生したのはreactrouterのためです.routerを使用して各ページを実装しましたが、このページのリフレッシュ中に画像をロードできないという問題が発生しました.
当初、
window.addEventListener('load', ~~)
によってこのイベントを解決しようとしたが、このイベントは最初は実行時に発生した.すなわち、App.js
は最初は実行時に発生しただけで、ルータページでどのようにリフレッシュしても解決できなかった.Lazy loadingを適用せずにWebPイメージを直接使用して最適化することを考慮すると、
class Component
を使用すべきだとふと思いました.(本当に稲妻のようにふと思い出した)既存の構造
App
| - Bread (빵 목록 보여주는 페이지)
| | - BreadList (실제 빵 종류들)
| | - Footer
| - Vegetable
| | - VegetableList
| | - Footer
| - Cheese
| | - CheeseList
| | - Footer
| - Sauce
| - SauceList
| - Footer
以前は、上記の構造はすべてfunctioncomponentとして宣言されていました.ここで画像をレンダリングするファイルは~List
で、これらのファイルはclass componentです.これにより、さまざまなライフサイクルメソッドが使用できます.実際に、リフレッシュしてもコンポーネントDidMountメソッドが呼び出されることを確認しました.
最終クラスコンポーネントのコードは、次のようになります.
class BreadList extends React.Component {
// componentDidMount 내에 IntersectionObserver를 선언
// 새로 고침 시에도 이 부분이 항상 실행됨. 문제 해결!
componentDidMount() {
const images = document.querySelectorAll("img");
const observer = new IntersectionObserver((entries, observer) => {
entries.forEach((entry) => {
if (!entry.isIntersecting) return;
const image = entry.target;
const src = image.getAttribute("data-lazy");
image.setAttribute("src", src);
observer.unobserve(image);
})
})
images.forEach((image) => {
observer.observe(image);
})
}
render() {
return (
<div>빵 목록들</div>
)
}
}
結果
以前とは異なり、画像はロード前にロードされた画像を表示し、スクロール時にのみ必要な追加画像が表示されます.また、イメージはリフレッシュ時に正常にロードされます.
内容は複雑ではありませんが、実際のサイトに適用するには、思ったより時間がかかります.それに反応物の特性も問題になっているので、解決策を探しています.
しかし、このように解決した後、私は今本当に私のものだと思います!😁
Reference
この問題について(IntersectionObserver(feat.React)の使用), 我々は、より多くの情報をここで見つけました https://velog.io/@gouz7514/IntersectionObserver-사용해보기-feat.-Reactテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol