๐ŸŽธ ๋ฐ๋ชจ_5์ฃผ์ฐจ - boostcampwm-2022/web33-Mildo GitHub Wiki

1. ํ”„๋กœ์ ํŠธ ๋ช… : Mildo(๋ฐ€๋„)

  • ๋ฐ˜์‘ํ˜• ์›น ํ™˜๊ฒฝ์—์„œ ์„œ์šธ์‹œ ์‹ค์‹œ๊ฐ„ ์ธ๊ตฌ ๋ฐ€๋„ ์ •๋ณด๋ฅผ ์ œ๊ณตํ•˜๋Š” ๊ฒƒ์„ ๋ชฉํ‘œ

2. ์ด๋ฒˆ ์ฃผ ๊ตฌํ˜„ ๋‚ด์šฉ

แ„‰แ…ณแ„แ…ณแ„…แ…ตแ†ซแ„‰แ…ฃแ†บ 2022-12-08 แ„‹แ…ฉแ„’แ…ฎ 8.55.09.png

  1. ์ง€๋„์— ํ‘œ์‹œ๋œ ๋งˆ์ปค ํ•„ํ„ฐ๋ง ๊ธฐ๋Šฅ ๊ตฌํ˜„
  2. ์ฃผ์š” ์žฅ์†Œ ๊ฒ€์ƒ‰ ๊ธฐ๋Šฅ ๊ตฌํ˜„
  3. ์ฃผ์š” ์žฅ์†Œ ๋ถ๋งˆํฌ ๋“ฑ๋ก ๊ธฐ๋Šฅ ๊ตฌํ˜„
  4. https ์ ์šฉ
  5. ์„ฑ๋Šฅ ๊ฐœ์„ ์„ ์œ„ํ•œ ๋ฆฌํŒฉํ† ๋ง

3. ์ฃผ์š” ๊ตฌํ˜„ ๋‚ด์šฉ

์ฃผ์š” ์žฅ์†Œ ๊ฒ€์ƒ‰

์ด์šฉ์ž์˜ ๋ชจ๋“  ์ž…๋ ฅ์— ๊ฒ€์ƒ‰ API๋ฅผ ํ˜ธ์ถœํ•ด์•ผ ํ•˜๋Š”๊ฐ€?

  • ์‚ฌ์šฉ์ž๊ฐ€ ํ•œ ๊ธ€์ž์”ฉ ์ž…๋ ฅํ•  ๋•Œ๋งˆ๋‹ค ๊ฒ€์ƒ‰ API๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ์€ ์„œ๋ฒ„์— ๋ถ€๋‹ด๋ฅผ ์ค„ ์ˆ˜ ์žˆ์Œ

  • ์ฒ˜์Œ์— debounce๋ฅผ ์ ์šฉํ•˜๋ ค๊ณ  ํ–ˆ์œผ๋‚˜ React 18์—์„œ ์ƒˆ๋กœ์šด Hooks์ธ useTransition , useDeferredValue ๊ฐ€ ์ถ”๊ฐ€๋˜์—ˆ๋‹ค๊ณ  ํ•˜์—ฌ ์ด๋ฅผ ์ด์šฉํ•ด์„œ ๊ตฌํ˜„ ์‹œ๋„

    โ†’ useTransition ๊ณผ useDeferredValue ๋Š” ์ด์šฉ์ž ๊ธฐ๊ธฐ์˜ ์„ฑ๋Šฅ์— ๋”ฐ๋ผ ๋นจ๋ฆฌ ์ฒ˜๋ฆฌ์‹œํ‚ฌ์ง€ ๋Šฆ๊ฒŒ ์ฒ˜๋ฆฌ์‹œํ‚ฌ์ง€ ์ •ํ•ด์ฃผ๊ธฐ ๋•Œ๋ฌธ์— ๊ธฐ๊ธฐ์˜ ์„ฑ๋Šฅ์ด ์ข‹๋‹ค๋ฉด hooks๋ฅผ ์ ์šฉํ•˜๊ธฐ ์ „๊ณผ ์ฐจ์ด๊ฐ€ ์—†์Œ

  • ํด๋ผ์ด์–ธํŠธ์ธก ๋ถ€๋‹ด์ด ์•„๋‹ˆ๋ผ ์„œ๋ฒ„์ธก ๋ถ€๋‹ด์„ ์ค„์—ฌ์ฃผ๋ ค๊ณ  debounce๋ฅผ ์ ์šฉํ•˜๋ คํ•œ ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์— ๋‹ค์‹œ setTimeout๋ฅผ ํ†ตํ•ด ์ง์ ‘ debounce ๊ตฌํ˜„

before debounce

  • before debounce

  • ํ•œ ๊ธ€์ž์”ฉ ์ž…๋ ฅํ•  ๋•Œ๋งˆ๋‹ค ์š”์ฒญ

after debounce

  • after debounce

  • ์š”์ฒญ ํšŸ์ˆ˜๊ฐ€ ๋ˆˆ์— ๋„๊ฒŒ ์ค„์Œ

UI

ํ™”๋ฉด ํฌ๊ธฐ์— ๋”ฐ๋ฅธ ์• ๋‹ˆ๋ฉ”์ด์…˜ ์ ์šฉ

  • element ์†์„ฑ ์ค‘ ์‹ค์ œ ์ฝ˜ํ…์ธ  ๊ธธ์ด๋ฅผ ์˜๋ฏธํ•˜๋Š” clientWidth๋ฅผ ์ด์šฉํ•ด์„œ ํ…์ŠคํŠธ์™€ ๋ชจ๋‹ฌ ๊ฐ„์˜ ๊ธธ์ด ์ฐจ์— ๋”ฐ๋ผ ์• ๋‹ˆ๋ฉ”์ด์…˜ ์—ฌ๋ถ€๋ฅผ ๊ฒฐ์ •ํ•˜์˜€์Œ

แ„’แ…ชแ„†แ…งแ†ซ_แ„แ…ณแ„€แ…ตแ„‹แ…ฆ_แ„„แ…กแ„…แ…ณแ†ซ_แ„†แ…ฉแ„ƒแ…กแ†ฏ_แ„Œแ…ฆแ„†แ…ฉแ†จ_แ„‰แ…ณแ†ฏแ„…แ…กแ„‹แ…ตแ„ƒแ…ตแ†ผ.gif

  • ๋ชจ๋‹ฌ ๊ธธ์ด๊ฐ€ ๋„“์„ ๋•Œ๋Š” ํ…์ŠคํŠธ๊ฐ€ ์›€์ง์ด์ง€ ์•Š์Œ

  • ์ข์•„์ง€๋ฉด ๊ฐ€๋กœ๋กœ ํ๋ฅด๋Š” ์• ๋‹ˆ๋ฉ”์ด์…˜ ์ ์šฉ

ํ™”๋ฉด ํฌ๊ธฐ์— ๋”ฐ๋ผ ์—ฐ๊ด€๊ฒ€์ƒ‰์ฐฝ ๋„ˆ๋น„ ์กฐ์ ˆ

แ„‹แ…งแ†ซแ„€แ…ชแ†ซแ„€แ…ฅแ†ทแ„‰แ…ขแ†จแ„‹แ…ฅ_UI_before.gif

  • ํ™”๋ฉด์ด ์ข์•„์ง€๋ฉด ๊ฒ€์ƒ‰์ฐฝ๋ณด๋‹ค ๊ธธ์ด๊ฐ€ ๊ธธ์–ด์ง

ezgif.com-gif-maker.gif

  • ์—ฐ๊ด€๊ฒ€์ƒ‰์ฐฝ์˜ ๊ธธ์ด๊ฐ€ ๊ฒ€์ƒ‰์ฐฝ๋ณด๋‹ค ๊ธธ์–ด์ง€์ง€ ์•Š๋„๋ก ์ˆ˜์ •

์ƒ์„ธ ์ •๋ณด 2๋‹จ๊ณ„ ๋ชจ๋‹ฌ react-query ์ ์šฉ

Day21 - ์บ์‹ฑ ์ „.gif

์™œ ์บ์‹ฑํ•˜๋ ค ํ•˜๋Š”๊ฐ€?

  • ๋ชจ๋‹ฌ์ฐฝ์„ ํŽผ ๋•Œ๋งˆ๋‹ค api ์„œ๋ฒ„์— ์š”์ฒญ

  • ๋”ฐ๋ผ์„œ ๋ชจ๋‹ฌ์ฐฝ์„ ํŽผ ๋•Œ๋งˆ๋‹ค 1.2์ดˆ~1.8์ดˆ๋ฅผ ๊ธฐ๋‹ค๋ ค์•ผ ํ•จ

  • ๊ทธ๋ž˜์„œ jotai๋ฅผ ์ด์šฉํ•ด ํ•œ ๋ฒˆ ์‘๋‹ต ๋ฐ›์€ ๋ฐ์ดํ„ฐ๋Š” ์ „์—ญ ์ƒํƒœ๋กœ ์ €์žฅํ•˜๊ณ , ์ดํ›„ ๊ฐ™์€ ์ง€์—ญ์— ๋Œ€ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณด์—ฌ์ค˜์•ผ ํ•  ๋•Œ์—๋Š” ์ „์—ญ ์ƒํƒœ์—์„œ ๊ฐ€์ ธ์™€์•ผ ํ•จ

์™œ ๋ฆฌ์•กํŠธ ์ฟผ๋ฆฌ๋ฅผ ์ ์šฉํ•˜๋ ค ํ•˜๋Š”๊ฐ€?

  • otai๋ฅผ ์ด์šฉํ•ด ์ „์—ญ ์ƒํƒœ๋กœ ๊ด€๋ฆฌํ•˜๋ฉด ์บ์‹ฑ ํšจ๊ณผ๋ฅผ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์—ˆ์ง€๋งŒ, ํ•œ ๋ฒˆ ์ „์—ญ ์ƒํƒœ๋กœ ์ €์žฅ๋œ ๋ฐ์ดํ„ฐ๋Š” ์ดํ›„ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์Œ

    ex) ์˜คํ›„ 2์‹œ์— ์ฒ˜์Œ ๋ชจ๋‹ฌ์ฐฝ์„ ์—ด๊ณ  ์ƒˆ๋กœ๊ณ ์นจ์„ ํ•˜์ง€ ์•Š์€ ์ƒํƒœ์—์„œ ์˜คํ›„ 9์‹œ์— ๋ชจ๋‹ฌ์ฐฝ์„ ์—ด๊ฒŒ ๋˜๋ฉด, ์˜คํ›„ 2์‹œ๋ฅผ ๊ธฐ์ค€์œผ๋กœ 24์‹œ๊ฐ„ ์ด๋‚ด์˜ ์ธ๊ตฌ ๋ฐ€๋„ ์ •๋ณด ๊ฐ€ ํ‘œ์‹œ๋จ

  • ์ข€ ๋” ๋ณธ๊ฒฉ์ ์œผ๋กœ ์บ์‹ฑํ•˜๊ธฐ ์œ„ํ•ด ๋ฆฌ์•กํŠธ ์ฟผ๋ฆฌ๋ฅผ ์ ์šฉํ•˜๊ธฐ๋กœ ํ•จ

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

  • ์ด์ „ ์ฝ”๋“œ

    ...
    
    const [cache, setCache] = useAtom(secondLevelInfoCacheAtom);
    
    ...
    
    // ์ „์—ญ์— areaName์„ ํ‚ค๋กœ ๊ฐ–๊ณ  ์žˆ๋Š” ์†์„ฑ์ด ์žˆ์œผ๋ฉด hit
    if (cache[areaName]) {
      setGraphInfo(cache[areaName]);
      return;
    }
    
    // ์•„๋‹ˆ๋ฉด api ํ˜ธ์ถœ
    const { data } = await apis.getPastInformation(areaName);
    
    ...
    
    1. ํ•ด๋‹น ์ง€์—ญ์˜ 24์‹œ๊ฐ„ ์ด๋‚ด์˜ ์ธ๊ตฌ ๋ฐ€๋„ ์ •๋ณด ๊ฐ€ ์ „์—ญ ์ƒํƒœ์— ์ €์žฅ๋˜์–ด ์žˆ์œผ๋ฉด hit

    2. ์—†์œผ๋ฉด api ์„œ๋ฒ„์— ์š”์ฒญํ•˜๊ณ  ์ „์—ญ ์ƒํƒœ์— ์ €์žฅ

  • ๋ฆฌ์•กํŠธ ์ฟผ๋ฆฌ ์ ์šฉ ํ›„

    // hooks/useGraphInfo.tsx
    
    ...
    
    const { data: graphInfoResponse } = useQuery(
    		// query key
        ['getGraphInfo', areaName],
    
    		// query function
        async () => {
          ...
          const result = await apis.getPastInformation(firstLevelInfo[0]);
    
          return result;
        },
    
    		// options
        {
          enabled,
          staleTime: QUERY_TIME.STALE_TIME, // 5๋ถ„
          cacheTime: QUERY_TIME.CACHE_TIME, // 30๋ถ„
          onSuccess: data => {
            success(data);
          },
          onError: e => {
            console.log('error', e);
          }
        }
      );
    
    ...
    
    1. query key

      • key-value๋กœ ์ €์žฅ

        ex) [โ€™getGraphInfoโ€™, โ€˜์„œ์šธ์—ญโ€™]

    2. query function

      • ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ ํ•จ์ˆ˜
    3. query options(์ค‘์š”)

      • enabled
      • staleTime
      • cacheTime

์บ์‹ฑ ํ›„

Day21 - ์บ์‹ฑ ํ›„.gif

  • ์„œ์šธ์—ญ์„ ๋‹ค์‹œ ์—ด์—ˆ์„ ๋•Œ ๊ทธ๋ž˜ํ”„ ๊ทธ๋ ค์ง€๋Š” ์†๋„๊ฐ€ ๋นจ๋ผ์ง

Day21 - ์บ์‹ฑ ํ›„4.gif

  • ์„œ์šธ์—ญ์„ ๋‹ค์‹œ ์—ด์—ˆ์„ ๋•Œ ๋„คํŠธ์›Œํฌ์— ๋‹ค์‹œ ์ฐํžˆ์ง€ ์•Š๋Š”๋‹ค.

https ์ ์šฉ

https ์œ„์น˜ ์ •๋ณด ์š”์ฒญ.PNG

์™œ https๋ฅผ ์„ค์ •ํ•˜๋ ค ํ•˜๋Š”๊ฐ€?

  • ์„œ๋น„์Šค์— ์ฒ˜์Œ ๋“ค์–ด๊ฐ€๋ฉด ์‚ฌ์šฉ์ž ์ดˆ๊ธฐ ํ™”๋ฉด ์„ค์ •์„ ์œ„ํ•ด ๋ธŒ๋ผ์šฐ์ €์—์„œ ์‚ฌ์šฉ์ž ์œ„์น˜ ์ •๋ณด ํ—ˆ์šฉ ์š”์ฒญ์„ ๋ณด๋ƒ„

  • ๋ฐฐํฌ ํ›„, https๋ฅผ ์„ค์ •ํ•˜์ง€ ์•Š์œผ๋ฉด ์œ„์น˜ ์ •๋ณด ์ œ๊ณต ์š”์ฒญ์„ ์•„์˜ˆ ํ•˜์ง€ ์•Š์Œ

Mixed Content ์—๋Ÿฌ

  • client๋Š” https๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  server๋Š” http๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Mixed Content ์—๋Ÿฌ ๋ฐœ์ƒ

    Mixed Content: The page at 'https://www.mildo.live/' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint 'http://www.mildo.live:3001/api/auth'. This request has been blocked; the content must be served over HTTPS.
    
    • ํ˜ผํ•ฉ ์ฝ˜ํ…์ธ (Mixed Content)๋Š” https๋ฅผ ํ†ตํ•ด์„œ ์ ‘์†ํ•œ ์‚ฌ์ดํŠธ์—์„œ http ํ†ต์‹ ์œผ๋กœ ์Šคํฌ๋ฆฝํŠธ, ๋™์˜์ƒ ๋“ฑ์˜ ์ž์›์„ ์š”์ฒญํ•˜๋Š” ๊ฒƒ์œผ๋กœ, ํฌ๋กฌ ๋ธŒ๋ผ์šฐ์ €๋Š” ํ˜ผํ•ฉ ์ฝ˜ํ…์ธ ๊ฐ€ ์žˆ์„ ๊ฒฝ์šฐ ํ•ด๋‹น ์ฝ˜ํ…์ธ ๋ฅผ ์ฐจ๋‹จํ•จ
  • ๋ฐฐํฌ ์„œ๋ฒ„์˜ Nginx์—์„œ ๋ฆฌ๋ฒ„์Šค ํ”„๋ก์‹œ ์„ค์ •์„ ํ•˜์—ฌ Mixed Content ์—๋Ÿฌ ํ•ด๊ฒฐ

    // etc/nginx/sites-enabled/default.conf
    server {
            ...
    
            location / {
                    root /usr/share/nginx/html/client/build;
                    index index.html index.htm index.nginx-debian.html;
            }
    
            location /api {
                    proxy_set_header Host $host;
                    proxy_set_header X-Real-IP $remote_addr;
                    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                    proxy_set_header X-Forwarded-Proto https;
                    proxy_http_version 1.1;
                    proxy_pass http://www.mildo.live:3001;
            }
    }
    
  • ๋ฆฌ๋ฒ„์Šค ํ”„๋ก์‹œ(Reverse Proxy)๋Š” ํด๋ผ์ด์–ธํŠธ์˜ ์š”์ฒญ์„ ๋Œ€์‹  ๋ฐ›์•„ ๋‚ด๋ถ€ ์„œ๋ฒ„๋กœ ์ „๋‹ฌํ•˜์—ฌ ์‘๋‹ต์„ ๋ฐ›์•„์˜ค๋Š” ๊ฒƒ

  • ํด๋ผ์ด์–ธํŠธ์—์„œ root location(/)์œผ๋กœ ์š”์ฒญ ์‹œ์—๋Š” html ํŒŒ์ผ์„ ๋ณด๋‚ด์คŒ

  • ํด๋ผ์ด์–ธํŠธ์—์„œ /api ๋กœ ์‹œ์ž‘ํ•˜๋Š” ์ฃผ์†Œ๋กœ ์š”์ฒญ ์‹œ nginx๊ฐ€ ๋Œ€์‹  ์š”์ฒญ์„ ๋ณด๋‚ด๊ณ  ์‘๋‹ต์„ ๋ฐ›์•„์™€ ํด๋ผ์ด์–ธํŠธ์— ์ „๋‹ฌ

4. ์•ž์œผ๋กœ ํ•  ์ผ

  • ๊ธฐ๋Šฅ ๊ตฌํ˜„ ๋งˆ๋ฌด๋ฆฌ, ์ฝ”๋“œ ๊ฒ€ํ†  ๋ฐ ๋ฆฌํŒฉํ† ๋ง
  • ์„ฑ๋Šฅ ํ…Œ์ŠคํŠธ ํ›„ ๊ฐœ์„ 
  • ์‹œ๋‚˜๋ฆฌ์˜ค๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์‹œ์—ฐ ์˜์ƒ ์ฐ๊ธฐ
  • ํ”„๋กœ์ ํŠธ ์†Œ๊ฐœ์„œ ๊ฒ€ํ†  ๋ฐ ์™„์„ฑ

5. ๋ฐฐํฌ ์ฃผ์†Œ

Mildo

https://www.mildo.live/