Post

๐Ÿฅœ [React] Lazy-Loading ์•Œ์•„๋ณด๊ธฐ

ํ•ด๋‹น ํŽ˜์ด์ง€๋Š” lazy-loading ์— ๋Œ€ํ•ด ์•Œ์•„๋ณด๊ณ 

๊ทธ์— ๋”ฐ๋ฅธ ๊ฐ„๋‹จํ•œ ์‚ฌ์šฉ๋ฐฉ๋ฒ•์„ ์•Œ์•„๋ณด๋Š” ํŽ˜์ด์ง€์ž…๋‹ˆ๋‹ค.

์™œ?

ํ˜„์žฌ ์ง„ํ–‰ ์ค‘์ธ ํ”„๋กœ์ ํŠธ์—์„œ ๊ธ€ ๋ชฉ๋ก ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜๋Š”๋ฐ ๊ธ€์ด ๋„ˆ๋ฌด ๋งŽ์•„

์‚ฌ์šฉ์ž๊ฐ€ ์›ํ•˜๋Š” ๋งŒํผ๋งŒ ๋กœ๋”ฉํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ์—†์„๊นŒ ์‹ถ์–ด ์•Œ์•„๋ณด๊ฒŒ ๋˜์—ˆ๋‹ค.



Lazy-Loading ์ด๋ž€?


ํŽ˜์ด์ง€๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๋Š” ์‹œ์ ์— ๋‹น์žฅ ํ•„์š”ํ•˜์ง€ ์•Š์€ ๋ฆฌ์†Œ์Šค๋“ค์„ ์ถ”ํ›„์— ๋กœ๋”ฉํ•˜๊ฒŒ ํ•˜๋Š” ๊ธฐ์ˆ 


์ผ๋ฐ˜์ ์œผ๋กœ ํŽ˜์ด์ง€์— ์ ‘๊ทผํ•˜๋ฉด ํŽ˜์ด์ง€ ๋‚ด์šฉ์ด ๋ชจ๋‘ ์š”์ฒญ ๋œ๋‹ค.

์‚ฌ์šฉ์ž๊ฐ€ ๋ชจ๋“  ํŽ˜์ด์ง€ ๋‚ด ๋ชจ๋“  ์ •๋ณด๋ฅผ ๋‹ค ์ด์šฉํ•œ๋‹ค๋ฉด ์ƒ๊ด€์—†์ง€๋งŒ

์‚ฌ์šฉ์ž๋“ค์€ ์ž๊ธฐ๊ฐ€ ์›ํ•˜๋Š” ํŠน์ • ์ •๋ณด๋ฅผ ์–ป๊ธฐ๋งŒ ํ•˜๊ณ  ๋‚˜๊ฐˆ์ˆ˜๋„ ์žˆ๋‹ค.

๋”ฐ๋ผ์„œ ๊ทธ์— ๋”ฐ๋ฅธ ์“ธ๋ฐ์—†๋Š” ์š”์ฒญ๊ณผ ๋‚ญ๋น„๊ฐ€ ์ด๋ฃจ์–ด์ง„๋‹ค.

๊ทธ๋Ÿฌํ•œ ์ƒํ™ฉ์„ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•œ ๊ฒƒ์ด lazy-loading ์ด๋ผ๊ณ  ํ•œ๋‹ค.



๊ตฌํ˜„ ๋ฐฉ๋ฒ•

์šฐ์„ ์ ์œผ๋กœ ์‚ฌ์šฉ์ž๊ฐ€ ํ•„์š”ํ•œ ์ •๋ณด๋ฅผ ์–ป๊ธฐ ์œ„ํ•ด ์Šคํฌ๋กค์„ ๋‚ด๋ฆฌ๋ฏ€๋กœ

์Šคํฌ๋กค์„ ๊ฐ์ง€ํ•˜๊ณ  ์žˆ์–ด์•ผ ํ•œ๋‹ค.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
  const [isLoading, setIsLoading] = useState<boolean>(false);
  const sentinel = useRef<HTMLDivElement | null>(null);
  // ๋งจ ํ•˜๋‹จ component ์˜ ref

  useEffect(() => {
    const observer = new IntersectionObserver(
      (entries) => {
        if (entries[0].isIntersecting && !isLoading) {
            // ๊ฐ์ง€ ํ–ˆ์„ ๋•Œ์˜ ๋กœ์ง ์ถ”๊ฐ€
            // setIsCounter((current) => current + 1);
        }
      },
      { threshold: 1.0 }
    );

    if (sentinel.current) {
      observer.observe(sentinel.current);
    }

    return () => observer.disconnect();
  }, []);


ํ˜„์žฌ ๋ณด์—ฌ์ฃผ๊ณ  ์žˆ๋Š” ์ •๋ณด์˜ ๋งˆ์ง€๋ง‰ (sentinel) ์— ๋‹ฌํ–ˆ์„ ๋•Œ

์ƒˆ๋กœ ๋กœ๋”ฉ (loading) ์„ ํ•ด์•ผํ•œ๋‹ค.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
  useEffect(() => {
    const getResponse = async () => {
      setIsLoading(true);
      try {
        const response = await getNowPlayingList(isCounter);

        if (response.status === 200 && response.data.results) {
          setIsList((prev) => [...prev, ...response.data.results]);
        }
      } catch (error) {
        // ์—๋Ÿฌ ์ฒ˜๋ฆฌ
      } finally {
        setIsLoading(false);
      }
    };

    getResponse();
  }, [isCounter]);
  // counter ๊ฐ€ ๋ณ€๊ฒฝ๋์„ ๋•Œ ์‹คํ–‰
  // getNowPlayingList๋Š” page ๋ฅผ number type ์œผ๋กœ ๊ฐ€์ง

์žฅ์ 

  1. ์‚ฌ์šฉ์ž๊ฐ€ ์ฒ˜์Œ ์›น์‚ฌ์ดํŠธ์— ์ ‘๊ทผํ•  ๋•Œ ๋ฆฌ์†Œ์Šค์˜ ์ผ๋ถ€๋งŒ ๋‹ค์šด๋กœ๋“œ ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์ฝ˜ํ…์ธ ์˜ ์ œ๊ณต ์†๋„๊ฐ€ ๋น ๋ฅด๋‹ค. ์ฆ‰ ์„ฑ๋Šฅ์ด ํ–ฅ์ƒ๋œ๋‹ค.
  2. ์ฝ˜ํ…์ธ ๊ฐ€ ์ง€์†์ ์œผ๋กœ ๊ณต๊ธ‰๋˜๊ธฐ ๋•Œ๋ฌธ์— ์‚ฌ์šฉ์ž๊ฐ€ ์›น์‚ฌ์ดํŠธ๋ฅผ ์ดํƒˆํ•  ํ™•๋ฅ ์„ ๋‚ฎ์ถœ ์ˆ˜ ์žˆ๋‹ค.
  3. ์‚ฌ์šฉ์ž๊ฐ€ ํ•„์š”๋กœ ํ•˜๋Š” ๊ฒฝ์šฐ์—๋งŒ ์ฝ˜ํ…์ธ ๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ ๋•Œ๋ฌธ์— ๋ฐฐํ„ฐ๋ฆฌ, ์‹œ๊ฐ„, ์‹œ์Šคํ…œ ๋ถ€๋‹ด ๋“ฑ์ด ๋‚ฎ์•„์ง„๋‹ค. ์ฆ‰ ๋น„์šฉ์ด ๊ฐ์†Œ๋œ๋‹ค.

๋‹จ์ 

  1. ๋กœ๋”ฉ ์‹œ๊ฐ„์ด ๊ธธ์ˆ˜๋ก ์›ํ•˜๋Š” ํƒ€์ด๋ฐ์— ๋กœ๋”ฉ์„ ๋งˆ์น˜์ง€ ๋ชปํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

ํ™•์ธํ•˜๋Š” ๋ฒ•

Dev Tools -> Network -> img ๋กœ ๋“ค์–ด๊ฐ€ ํ™•์ธํ•ด๋ณด๋ฉด ์ •์ƒ์ ์œผ๋กœ ์ž‘๋™ํ•˜๋Š”์ง€ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

image-main

This post is licensed under CC BY 4.0 by the author.