Number Type

  • 자바스크립트는 일부 다른 언어들과 다르게 숫자를 Number로만 표현한다.
  • 모든 숫자를 포함해야 하기 때문에 모든 수를 실수로 처리한다.
  • Number 타입은 64비트의 고정된 크기의 공간을 확보하므로, 정확하게 표현할 수 있는 숫자의 범위가 제한된다.
  • 만약 이보다 큰 수가 있다면?
    • BigInt()
      • Number가 안정적으로 나타낼 수 있는 최대치인 2^53 - 1보다 큰 정수를 표현할 수 있는 내장 객체이다.
      • BigInt를 사용했다면 BigInt 연산을 유지해야 한다!

원시 타입

  • 자바스크립트에서 원시 값이란 객체가 아니면서 메서드 또는 속성도 가지지 않는 데이터이다.
  • 원시 값에는 7 종류가 있다.
    • string
    • number
    • bigint
    • boolean
    • undefined
    • symbol
    • null
  • 모든 원시 값은 ‘불변’하여 변형할 수 없다.
  • 원시 값 자체와, 원시 값을 할당한 변수를 혼동하지 않는 것이 중요하다.
  • 이미 생성한 원시 값은 객체, 배열, 함수와 달리 변형할 수 없다.

실행 컨텍스트(Execution Context)

  • 실행 가능한 코드에 제공할 환경 정보를 모아놓은 객체
    • 변수 객체, 스코프 체인, this 정보가 담겨있다.
  • 자동으로 전역 컨텍스트가 생성된 후 함수 호출 시 함수 컨텍스트가 생성된 후에 함수 실행
  • 함수 실행이 마무리 될 경우 해당 컨텍스트는 사라지고 페이지가 종료되면 전역 컨텍스트도 사라진다.

실행 컨텍스트의 역할

  1. 전체 코드의 환경과 순서를 보장한다.
    • 환경 정보 객체를 콜 스택에 쌓아올리고 → 가장 위에 쌓여있는 컨텍스트와 관련 있는 코드 실행
  2. 실행 컨텍스트가 활성화되는 시점에 선언된 변수 hoisting
  3. 외부 환경 정보 구성
  4. this 값 설정

호이스팅(Hoisting)

  • 인터프리터가 코드를 실행하기 전 함수, 변수, 클래스 또는 임포트의 선언문을 해당 범위의 맨 위로 끌어올리는 것처럼 보이는 현상
  • 예시
    • 변수가 선언된 줄 이전에 해당 범위에서 변수 값을 사용할 수 있는 값 호이스팅
    • 변수가 선언된 줄 이전 해당 범위의 변수를 참조할 수 있지만 ReferenceError을 던지지 않고 값이 항상 정의되지 않음인 선언 호이스팅
    • 변수 선언 시 변수 선언된 줄 앞의 범위에서 동작이 변경
    • 선언의 부작용은 선언이 포함된 나머지 코드를 평가하기 전 발생

클로저(Closure)

  • 주변 상태에 대한 참조와 함께 묶인 함수의 조합
  • 내부 함수에서 외부 함수의 범위에 대한 접근을 제공
  • 함수 생성 시 함수가 생성될 때마다 생성된다.

→ 중첩된 함수는 외부 범위에서 선언한 변수에도 접근할 수 있다.

실용적인 클로저

  • 어떤 데이터와 그 데이터를 조작하는 함수를 연관시키기 때문에 유용하다.
  • 객체지향 프로그래밍과 같은 맥락

⇒ 오직 하나의 메소드를 가지고 있는 객체를 일반적으로 사용하는 모든 곳에 클로저를 사용 가능

function outter() {
	var title = 'coding everybody';
	return function () {     //return이 나올 시 outter 함수의 생은 마감
		alert(title);          //하지만 그의 자식인 내부함수는 계속 생존해 외부 함수가 남긴 변수 사용
	}
}
inner = outter();
inner();
  • private variable 사용 시 유용하게 사용 가능하다.

클로저의 세 가지 범위

  • 지역 범위
  • 포함하고 있는 범위
  • 전역 범

가비지컬렉터의 역할

  • 개발 시 유효하지 않은 메모리를 가비지라고 일컫는다.
  • 메모리는 제한된 자원이기 때문에, 사용하지 않는 메모리 영역은 다시 사용할 수 있도록 회수되어야 한다. 이 과정을 자동으로 수행하는 것이 바로 가비지 컬렉션
    • 이런 자동 메모리 관리는 개발자가 메모리 관리에 대해 고민할 필요가 없다는 잘못된 인식을 심어줄 수 있다.
  • ⇒ 가비지 컬렉션
  • 참조 추적: 가비지 컬렉터는 메모리 내에서 현재 사용 중인(참조되고 있는) 데이터와 더 이상 사용되지 않는(참조되지 않는) 데이터를 추적한다.
  • 참조 해제: 변수나 데이터가 더 이상 참조되지 않거나 그 참조 값이 null로 설정되면, 가비지 컬렉터는 해당 메모리 영역이 필요하지 않다고 판단한다.
  • 메모리 회수: 필요하지 않은 메모리 영역이 발견되면, 가비지 컬렉터는 이 영역을 해제하여 메모리를 반환하고, 이후 프로그램이 다른 데이터를 저장하는 데 이 메모리를 사용할 수 있도록 한다.

메모리 생존주기

  1. 필요할 때 할당한다.
  2. 할당된 메모리를 사용한다.
  3. 더 이상 필요하지 않으면 해제한다.

값 초기화

  • 프로그래머가 메모리 할당을 신경 쓸 필요가 없도록 JS는 값을 선언할 때 자동으로 메모리를 할당한다.

함수 호출을 통한 할당

  • 함수 호출의 결과 메모리 할당이 일어나기도 한다.
  • 메소드가 새로운 값이나 오브젝트를 할당하기도 한다.

순환참조

  • import 시 발생할 수 있는 순환 참조 에러

메모리 관점에서의 순환 참조

  • 서로 다른 두 객체가 서로를 참조하여, 가비지 컬렉션 알고리즘의 대상에 포함되지 않아 해당 객체들이 불필요해져도 메모리 회수되지 않고 존속하게 되는 문제이다.
function f() {
  const x = {};
  const y = {};
  x.a = y; // x는 y를 참조합니다.
  y.a = x; // y는 x를 참조합니다.

  return "azerty";
}

f();

// 두 객체가 불필요해지는 순간 할당된 메모리가 회수되어야 하지만 두 객체가 서로를 참조하고
 있으므로 참조 - 세기 알고리즘은 둘 다 가비지 컬렉션의 대싱으로 표시하지 않는다. 

이벤트 루프 & 동시성 모델

  • 자바스크립트의 런타임 모델은 코드의 실행, 이벤트 수집과 처리, 큐에 대기 중인 하위 작업을 처리하는 이벤트 루프에 기반한다.
  • 이벤트 루프는 JS의 단일 스레드에서 비동기 코드를 처리할 수 있게 돕는다.
  • JS의 코드 순차적 실행⇒ 비동기 작업이 완료되면 해당 작업의 콜백을 이벤트 큐에 추가
    • 위의 반복적인 행동을 이라고 부른다.
  • ⇒ 이벤트 루프는 콜 스택이 비어있는 지 확인하고 비어있을 경우 이벤트 큐에서 콜백을 가져와 실행
  • ⇒ 비동기 작업 발생 시 작업을 백그라운드로 넘김

동시성?

  • JS는 이벤트 루프를 기반으로 한 동시성 모델이다.
  • 여러가지 작업을 동시에 호출하는 것을 의
  • 이벤트 루프는 코드 실행, 이벤트 수집과 처리, 큐에 존재하는 하위 작업들을 처리한다.

프로토 타입

  • 모든 객체들이 메소드와 속성들을 상속받기 위한 템플릿으로써 프로토타입 객체를 가진다는 의미.
  • 프로토타입 객체도 또 다시 상위 프로토타입 객체로부터 메소드와 속성을 상속 받을 수도 있고 그 상위 프로토타입 객체도 마찬가지.
    • 객체가 특정 속성이나 메서드에 접근할 때 해당 객체에 없으면 이 프로토타입 체인을 따라 상위 객체에서 찾는다.
    ⇒ 이를 프로토타입 체인이라 부른다.

출처

https://velog.io/@kados22/FE-기술-면접-실행-컨텍스트가-무엇인가요

https://developer.mozilla.org/ko/docs/Web/JavaScript/Closures

https://developer.mozilla.org/ko/docs/Web/JavaScript/Memory_management

https://mangkyu.tistory.com/118

'TIL' 카테고리의 다른 글

자바스크립트의 ES6  (0) 2024.08.21
자바스크립트의 this  (0) 2024.08.20
비동기 프로그래밍 (Callback, Promise, Async/Await)  (0) 2024.08.16
웹 프로토콜  (0) 2024.08.15
함수형 프로그래밍 (Function Programming)  (0) 2024.08.14

 

 

 

- JS, 리액트를 사용한 프로젝트 진행 중 막대창으로 인한 불편함이나 웹사이트를 들어가야하는 불편함이 크게 느껴져서 PWA로 만들기로 했다. 

- 막 어려웠던 게 아니긴 한데... PWA 개념도 모르다가 한 번에 적용까지 하려니 삽질을 좀 했다

 

 


PWA란 ?!

Progressive Web App. 쉽게 말해 웹 앱이다. 웹페이지를 그대로 '앱'화해서 방문과 공유를 쉽게 만든다.

이미 만든 웹사이트를 그대로 모바일에서 앱처럼 동작하게 만들 수 있어서 좋다.

이미 트위터, 스타벅스, 핀터레스트 등은 PWA를 사용하고 있다.

 

중요한 점

PWA를 만들기 위해서 중요한 개념인 service-worker (브라우저와 네트워크 중간에 있는 가상 프록시를 의미한다)는 안전한 컨텍스트, 즉 HTTPS 주소에서만 실행된다는 점이다. HTTPS를 가진 주소가 있으면 가장 좋을 것 같고, PWA를 위해 코드를 수정하면서 실험해 보니 localhost에서도 테스트가 가능한 것 같다. 


 

PWA 만드는 법 정리 

1. manifest.json 파일을 정의한다.

가장 맨 아래에 있는 manifest.json 파일.

기존 리액트 프로젝트 생성 시 필요 없는 파일이기 때문에 manifest.json 파일을 삭제해 없는 경우가 많은데, PWA 파일을 만들기 위해서는 반드시 필요하니 다시 manifest.json 파일을 public 파일 안에 생성해 넣어준다. 파일의 내용은 아래의 PWA Builder 에서 쉽게 생성 할 수 있다. PWA Builder는 PWA를 쉽게 적용할 수 있도록 도와주는 도구이니 끄지 말고 한 구석에 계속 켜 놓기를 추천한다. 

 

https://www.pwabuilder.com/

 

여기서 'Enter the URL to your PWA'에 주소를 넣으면 (로컬이든 배포 주소든) 

- manifest.json 파일이 있을 시 보통 아래처럼 내 주소가 얼마나 PWA에 적합한 지를 알려주며 점수를 매겨준다.

 (지금 나의 점수는 보다시피 딱히 높지는 않다..ㅎㅎ;)

- manifest.json 파일이 없을 시 아마 찾을 수 없다며 manifest.json 파일을 수정하거나 추가하라며 알려줄 것이다. 

 

 

 

Edit your Manifest 파일에서 보이는 요소들. 

name, short name, id, description 등 프로젝트에 맞춰서 후루룩 쓴다. 어차피 파일에서 바로바로 수정할 수 있으니까 엄청 신중할 필요는 없다. Settings에서 있는 요소들도 맞춰서 변경해준다. StartURL은 홈 화면, 웹의 시작 주소를 말한 거니까 보통은 / 그대로 놔두면 된다. Language도 알아서 맞춰준다. Display는 화면이 어떤 방식으로 보이느냐인데 보통 standalone 혹은 fullscreen으로 많이 쓰는 것 같다. 나는 위에 도구 막대 빼고 탭은 있는 게 안정적으로 보이는 것 같아서 standalone을 선택했다. 

 

 

그리고 아이콘 만들기가 나오는데... 우리 프로젝트는 로고도 없고 상징적인 아이콘도 아직 없어서 내가 급하게 하나 그렸다;; 나중에 제대로 갈아끼워야지 여기서 하나 그려서 사이즈별로 만들어서 넣으면 favIcon, 모든 기종/화면에서 앱 사용 시 보이는 이미지를 퉁칠 수 있다. 그래서 가급적 예쁘고 귀여울수록 좋은 것 같다 .... 512x512 이상 이미지를 넣으면 알아서 크기별로 만들어주고 파일로 압축해준다. 이 파일들 역시 public/icons/ 파일 안에 모두 넣어주면 된다. ( 꼭 이 주소는 아니여도 된다)

 

이렇게 manifest.json 파일이 완성되면 파일 내용을 넣어주고 index.html에서 manifest.json 파일을 찾을 수 있게 주소도 제대로 적어준다.

 

**

만들어진 아이콘들을 manifest와 index에 제대로 넣어줘야 하는 것 같다!

 

2. offline.html 페이지 만들기

 

루트 아래에 offline.html 페이지를 만들고 바르지 않은 주소로 간 경우 보여 줄 화면을 구현한다. 

<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>인터넷 연결 없음</title>
  </head>
  <body>
    <p>인터넷 연결 없음</p>
  </body>
</html>

 

3. dependency 추가

        "workbox-background-sync": "^5.1.4",
        "workbox-broadcast-update": "^5.1.4",
        "workbox-cacheable-response": "^5.1.4",
        "workbox-core": "^5.1.4",
        "workbox-expiration": "^5.1.4",
        "workbox-google-analytics": "^5.1.4",
        "workbox-navigation-preload": "^5.1.4",
        "workbox-precaching": "^5.1.4",
        "workbox-range-requests": "^5.1.4",
        "workbox-routing": "^5.1.4",
        "workbox-strategies": "^5.1.4",
        "workbox-streams": "^5.1.4"

 

4. service-worker.js 파일 && serviceWorkerRegistration.js 파일 추가

역시 루트 아래에 두 파일을 추가해준다. 

service-worker.js

import { clientsClaim } from 'workbox-core';
import { ExpirationPlugin } from 'workbox-expiration';
import { precacheAndRoute, createHandlerBoundToURL } from 'workbox-precaching';
import { registerRoute } from 'workbox-routing';
import { StaleWhileRevalidate } from 'workbox-strategies';

// 클라이언트 클레임
clientsClaim();

// 프리캐시 및 라우팅 설정
precacheAndRoute(self.__WB_MANIFEST);

const fileExtensionRegexp = new RegExp('/[^/?]+\\.[^/]+$');
registerRoute(
  ({ request, url }) => {
    if (request.mode !== 'navigate') {
      return false;
    }

    if (url.pathname.startsWith('/_')) {
      return false;
    }
    if (url.pathname.match(fileExtensionRegexp)) {
      return false;
    }

    return true;
  },
  createHandlerBoundToURL(process.env.PUBLIC_URL + '/index.html'),
);

const offlineFallbackPage = 'offline.html';

// 이미지 캐싱
registerRoute(
  ({ url }) =>
    url.origin === self.location.origin && url.pathname.endsWith('.png'),
  new StaleWhileRevalidate({
    cacheName: 'images',
    plugins: [new ExpirationPlugin({ maxEntries: 50 })],
  }),
);

// 서비스 워커 업데이트 메시지 처리
self.addEventListener('message', (event) => {
  if (event.data && event.data.type === 'SKIP_WAITING') {
    self.skipWaiting();
  }
});

 

serviceWorkerRegistration.js

 


const isLocalhost = Boolean(
  window.location.hostname === 'localhost' ||
    window.location.hostname === '[::1]' ||
    window.location.hostname.match(
      /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/,
    ),
);

export function register(config) {
  if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
    const publicUrl = new URL(PUBLIC_URL, window.location.href);
    if (publicUrl.origin !== window.location.origin) {
      return;
    }

    window.addEventListener('load', () => {
      const swUrl = `${PUBLIC_URL}/service/service-worker.js`;

      if (isLocalhost) {
        checkValidServiceWorker(swUrl, config);

        navigator.serviceWorker.ready.then(() => {
          console.log(
            'This web app is being served cache-first by a service ' +
              'worker. To learn more, visit https://cra.link/PWA',
          );
        });
      } else {
        registerValidSW(swUrl, config);
      }
    });
  }
}

function registerValidSW(swUrl, config) {
  navigator.serviceWorker
    .register(swUrl)
    .then((registration) => {
      registration.onupdatefound = () => {
        const installingWorker = registration.installing;
        if (installingWorker == null) {
          return;
        }
        installingWorker.onstatechange = () => {
          if (installingWorker.state === 'installed') {
            if (navigator.serviceWorker.controller) {
              console.log(
                'New content is available and will be used when all ' +
                  'tabs for this page are closed. See https://cra.link/PWA.',
              );

              // 성공 콜백 실행
              if (config && config.onUpdate) {
                config.onUpdate(registration);
              }
            } else {
              console.log('Content is cached for offline use.');

              if (config && config.onSuccess) {
                config.onSuccess(registration);
              }
            }
          }
        };
      };
    })
    .catch((error) => {
      console.error('Error during service worker registration:', error);
    });
}

function checkValidServiceWorker(swUrl, config) {
  fetch(swUrl, {
    headers: { 'Service-Worker': 'script' },
  })
    .then((response) => {
      const contentType = response.headers.get('content-type');
      if (
        response.status === 404 ||
        (contentType != null && contentType.indexOf('javascript') === -1)
      ) {
        navigator.serviceWorker.ready.then((registration) => {
          registration.unregister().then(() => {
            window.location.reload();
          });
        });
      } else {
        registerValidSW(swUrl, config);
      }
    })
    .catch(() => {
      console.log(
        'No internet connection found. App is running in offline mode.',
      );
    });
}

export function unregister() {
  if ('serviceWorker' in navigator) {
    navigator.serviceWorker
      .register('/service-worker.js')
      .then((registration) => {
        console.log(
          '서비스 워커가 다음 범위로 등록되었습니다:',
          registration.scope,
        );
      })
      .catch((error) => {
        console.error('서비스 워커 등록에 실패했습니다:', error);
      });
  } else {
    console.log('이 브라우저에서는 서비스 워커를 지원하지 않습니다.');
  }
}

 

5. 계속해서 light house와 PWA builder를 확인한다.

이렇게 깜찍한 앱으로 다운 받을 수 있을 때까지 시도하면 된당

비동기 프로그래밍이란

자바스크립트는 싱글 스레드 언어이기 때문에 한 번에 하나의 작업만을 수행한다.

이를 동기적이라고 한다. 동기 방식은 간단하고 직관적이지만 장기 실행 함수의 경우 응답이 늦어져 전체적인 성능이 저하 된다.

동기적인 프로그래밍의 문제점

: 실행한 동기적 프로그래밍의 결과값이 나오기 전까지는 아무 작업도 시작할 수 없다.

그러면 이를 해결하기 위한 비동기 프로그래밍은 무엇을 해줄 수 있을까

  1. 함수를 호춤함으로써 장기적으로 실행되는 작업을 시작한다.
  2. 이 함수로 작업을 시작하고 즉시 복귀하여 다른 이벤트에 계속 응답할 수 있게 한다.
  3. 작업이 완료되면 결과를 알려준다.

즉, 비동기 함수 실행 시 응답이 오는 것에 상관없이 다른 작업을 이어나가 병렬적으로 작업을 처리할 수 있게 된다. 이는 총 코드 실행 시간을 감소할 수 있게 한다.

비동기 처리의 처리 원리

호출 스택이벤트 루프

  • 비동기 함수의 콜백 함수가 이벤트 루프에 의해 callback queue에 담기고 다시 싱글 스레드인 call stack에 담겨서 콜백 함수가 실행되는 동작 원리

자바스크립트는 싱글 스레드 언어라고 했으면서 어떻게 병렬 처리가 가능한가요

  • 자바 스크립트를 실행하는 Call Stack : 싱글 스레드
  • 서버에게 리소스를 요청하거나 파일 입출력 혹은 타이머 대기 작업을 실행하는 Web APIs : 멀티 스레드

즉, 브라우저가 멀티 스레드이기 때문에 메인 자바스크립트의 싱글 스레드를 차단하지 않고 다른 스레드를 사용하여 Web API의 작업을 처리할 수 있기 때문에 비동기 처리가 가능한 것이다.

비동기 처리의 문제점

  • 만일 그 다음 실행할 작업이 이전에 요청한 작업의 결과가 반드시 필요할 경우 문제가 생긴다.
  • 서버로부터 데이터를 받을 때 비동기 함수의 결과가 동기적으로 실행되는 코드에 영향을 줄 때도 문제가 된다.

작업의 순서를 맞추는 것이 필수 불가결일 경우에 문제가 생긴다.

이를 해결하기 위한 몇 가지 기법 중 가장 대표적인 것은 콜백 함수 기법이다.

콜백 함수

  • 콜백 함수는 자바스크립트의 일급 객체 특성을 이용해 함수의 매개변수에 함수 자체를 넘겨 함수 내에서 매개변수 함수를 실행하는 기법을 말한다.
    • 콜백 함수를 이용함으로써 간접적으로 작업 순서를 끼워 맞출 수 있다.
  • 콜백 함수는 비동기 함수에서 작업 결과를 전달받아 처리하는데 사용되어 작업 순서를 맞출 수 있다.

⇒ 언뜻 문제가 해결되어 보이지만 콜백 함수는 비동기를 순차적으로 처리하기 위한 하나의 조치일 뿐 공식적인 해결 방식은 아니다.

Promise란 무엇인가

  • Promise 객체는 이러한 한계점 극복을 위해 비동기 처리를 위한 전용 객체로서 탄생했다.
  • Promise는 비동기 처리를 위한 전용 객체이다.
    • Promise는 비동기 작업의 성공과 실패를 나눠 그 결과에 따른 코드를 실행할 수 있게 한다.
    ⇒ Promise를 통해 비동기 작업을 쉽고 깔끔하게 연결할 수 있다.
  • const myPromise = new Promise((resolve, reject) => { setTimeout(() => { const success = true; if (success) { resolve("작업 성공!"); } else { reject("작업 실패."); } }, 2000); }); myPromise .then(result => { console.log(result); }) .catch(error => { console.error(error); });

Promise와 Callback

Promise와 Callback의 차이

  • 에러 처리
    • Callback은 단순히 비동기 작업의 결과를 처리하는 데 사용되지만
    • Promise는 비동기 작업의 결과를 완료 / 실패로 나타내어 각 결과에 맞는 코드를 실행할 수 있다.
  • 중첩 문제 해결
    • Callback은 구조가 단순해 중첩이 쉬워 이른바 ~~‘콜백 지옥’~~을 발생시킬 수 있다.
    • Promise는 중첩 문제에서 자유롭고 콜백보다 높은 가독성을 제공한다.
      • Promise 체이닝을 통해 여러 비동기 작업을 간단하게 연결할 수 있으나
      • 작업이 너무 복잡해질 경우 코드가 어려워질 수 있다.
      ⇒ 이 경우 async/await으로 보완이 가능하다.

Async, Await

  • ES8에 해당하는 문법 async / await
  • Callback처럼 Promise에도 Promise Hell이 존재한다. (주로 지나친 then 남용으로 일어난다.)
  • 이를 해결하기 위한 async / await은 프로미스를 기반으로 하지만 마치 동기 코드처럼 쉽게 작성할 수 있게 해준다.

개념

  • async 함수
    • 함수 선언 앞에 async 키워드를 붙이면 해당 함수는 자동으로 Promise를 반환한다.
    • async 함수 내부에서 reuturn 된 값은 자동으로 Promise.resolve()로 감싸져 반환된다.
  • await 키워드
    • await은 async 함수 내부에서만 사용 가능하며, Promise가 해결 될 때까지 함수 실행을 일시 정지한다.
    • await 뒤에 오는 Promise가 해결되면 그 결과값을 반환하고 await은 거부 이유를 throw하여 예외를 발생시킬 수 있다.

예시 코드

async function fetchData() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            const data = "데이터 로드 완료";
            resolve(data);
        }, 2000);
    });
}

async function main() {
    try {
        const result = await fetchData();
        console.log(result);
    } catch (error) {
        console.error("에러 발생:", error);
    }
}

main();

  • 비동기 코드를 동기식 코드처럼 작성할 수 있어 가독성이 좋다.
  • try/catch 구문으로 오류를 직관적이고 일관되게 처리할 수 있다.
  • 여러 개의 Promise를 더 간단하게 작성할 수 있다.

+) 웹 워커

  • 웹 워커는 브라우저 환경에서 메인 스레드와 독립적으로 백그라운드에서 자바스크립트를 실행할 수 있게 하는 비동기 작업의 일환이다.
  • 무거운 작업을 처리하면서도 UI의 변동 사항이 없기 때문에 사용자 경험을 개선할 수 있다.

예시 코드

// main.js (메인 스레드)
const worker = new Worker('worker.js');
worker.postMessage(1000000000);

worker.onmessage = function(event) {
    console.log('결과:', event.data);
    worker.terminate();
};

// worker.js (웹 워커)
self.onmessage = function(event) {
    let result = 0;
    for (let i = 0; i < event.data; i++) {
        result += i;
    }
    self.postMessage(result);
};

장점

  • UI 반응성 유지
  • 성능 향상
  • 독립적인 환경
    • 웹 워커는 독립된 실행 환경에서 동작하므로 메인 스레드와 충돌 없이 작업을 수행할 수 있다.

출처

https://developer.mozilla.org/ko/docs/Learn/JavaScript/Asynchronous/Introducing

https://developer.mozilla.org/ko/docs/Learn/JavaScript/Asynchronous

'TIL' 카테고리의 다른 글

자바스크립트의 this  (0) 2024.08.20
자바스크립트의 타입  (0) 2024.08.19
웹 프로토콜  (0) 2024.08.15
함수형 프로그래밍 (Function Programming)  (0) 2024.08.14
http와 https의 통신 방법 차이  (0) 2024.08.13

웹 프로토콜

: 웹에서 쓰이는 통신 규약. 웹에서 통신할 때 형식을 맞추자는 일종의 약속과 같다.

 

HTTP (Hyper Text Transfer Protocol)

: HTTP는 브라우저가 웹 서버와 통신하기 위해 사용하는 주요 프로토콜

 

- HTTP의 주요 5가지 요청 형식

: GET - 리소스 조회

: POST - 요청 데이터 처리, 주로 등록

: PUT - 리소스 대체, 해당 리로스가 없을 시 생성

: DELETE - 리소스 삭제

 

- HTTP의 특징

 

: 무상태성 - 상태를 유지하지 않는 Stateless 프로토콜. 즉, 서버는 각각의 요청을 별개의 것으로 처리하며 이전 요청의 정보를 저장하지 않음. => 서버의 부하를 줄이고, 클라이언트와 서버 간의 통신을 단순화하여 처리 속도를 향상.

 

: 비연결성 - Connectionless 프로토콜. 요청과 응답이 한 번 이루어지면 연결을 끊음. 서버 부하를 줄일 수 있지만, 새로운 연결을 맺을 시 시간이 추가로 발생할 수 있음.

 

- HTTP 통신 방식

: '요청'과 '응답'. 어떤 데이터를 '요청' 시 요청 받은 데이터로 '응답'.

즉, Request와 Response 구조로 통신한다. 

Request
Response

IP / MAC / ARP / TCP / UDP

- IP (Internet Protocol)

: 각각의 패킷을 IP 주소와 MAC 주소를 통해 상대방에게 전달하는 역할

: 각 노드에게 부여된 주소를 가르킴

 

*

비연결성

비신뢰성

프로그램 구분이 힘듬

 

- MAC (Media Access Control)

: 각 네트워크에 할당된 '고유의 주소'

 

- ARP (Address Resolution Protocol)

: 유동적인 IP 주소를 고유주소인 MAC 주소로 변환하여 목적지를 찾아감

 

- TCP (Transmission Control Protocol)

: 전송 제어 프로토콜

=> 데이터를 안정적으로, 순서대로, 에러없이 교환할 수 있게 전달한다.

 

- UDP (User Datagram Protocol)

: TCP와 대조되는 전송 프로토콜. 데이터 전달에 대한 안정성을 보장하진 않지만, TCP 보다 빠르다. 

 

- DNS (Domain Name Server)

: 숫자로 되어있는 IP 주소를 우리가 기업하기 쉽게 '문자'로 매핑.

 

인터넷 프로토콜 스택의 4계층

* 각 프로토콜이 완전히 별개의 것이 아니다. 

 

 

 


 출처

https://developer.mozilla.org/ko/docs/Web/HTTP/Overview

출처: https://dev.to/navi/why-functional-programming-matters-2o95

함수형 프로그래밍은 무엇인가

: 자료 처리를 수학적 함수의 계산으로 취급하는 프로그래밍 패러다임.

순수 함수와 보조 함수의 조합을 통해 로직 내 존재하는 조건문과 반복문을 제거하여 복잡성을 해결하고 변수의 사용을 억제해 상태 변경을 피하려고 한다. 

 

* 다른 패러다임으로 명령형, 객체 지향 등이 있다. 

함수형 프로그래밍의 특징

- 부수 효과가 발생하지 않는다.

 

* 부수 효과(Side-Effect)란?

: 함수가 만들어진 목적과는 다른 효과, 혹은 부작용

콘솔 또는 파일 I/O || 예외가 발생하여 프로그램 실행이 중단되는 경우 || 데이터가 변경되는 경우
=> 위와 이 변화가 발생하는 작업을 부수 효과가 발생한다고 말한다. 

 

- 순수 함수가 존재한다.

 

* 위에서 언급한 부수 효과가 없는 함수를 순수 함수라고 일컫는다. 

 

- 변경 불가능한 값을 활용한다.

 

* 불변값을 사용하면 병렬성, 동시성 문제를 쉽게 해결할 수 있다.

 또한 값을 예측하게 해주어 신뢰를 보장할 수 있다. 

 

* 원본 값을 바꾸지 않는 것이 중요

 

- 1급 객체가 존재한다.

 

* 함수형 프로그래밍에서 함수 = 일급 객체

 함수를 변수에 할당하고, 인자로 받고, 반환 값으로 활용하는 것이 가능하다. 

일급 객체

: 다른 요소들과 아무런 차별이 없음

 

* 람다(Lambda)와 고차 함수 (Higher Order Function) 

: 람다 = 익명 함수 / 고차 함수 = 다른 함수를 인자로 전달받는 함수 (외부의 조작으로 함수의 인자 조작 불가)

 

고차 함수의 예시 이미지. (.map, .filter, .reduce 등 ..) map으로 아이템을 썰고, reduce로 완성한다.

 

- 참조 투명성이 있다.

 

* 동일한 인자에 대해 항상 동일한 결과를 반환하고 기존 값을 변경되지 않고 유지된다. 

 

함수형 프로그래밍 개념의 순수 함수

: 순수 함수는 오직 입력으로 들어오는 파라미터에만 의존하기 때문에, 

함수의 매개 변수로 들어온 값을 직접 변경하는 일을 피하기만 해도 순수 함수를 만들 수 있다.

독립적인 함수이기 때문에 부수 효과가 발생하지 않다. 

 

순수 함수의 조건

 

1. 같은 입력값이 주어졌을 때, 언제나 같은 결과값을 리턴한다.

 

2. 사이드 이펙트를 만들지 않는다. 

 

OOP와 함수형 프로그래밍의 차이

1. 일급 객체의 차이

 

함수형 프로그래밍의 일급 객체 = 함수 자체

OOP의 일급 객체 = 클래스, 혹은 객체가 일급 객체

 

2. 프로그램

 

함수형 프로그래밍 = 상태값이 없는 함수들의 연속으로 이루어짐

: 값의 연산 & 결과 도출 중심으로 코드 작성이 이루어진다. 

 

OOP = 상호작용하는 객체들의 집합

: 클래스 디자인 & 객체 관계 중심으로 코드 작성이 이루어진다. 

 

결론

함수형 프로그래밍은 최대한 줄이기 위해 노력하는 코드이다.

 

관계를 줄이고, 상태값을 줄이고 최소한의 인풋과 아웃풋을 남겨 순수 함수를 최대한으로 활용한다. 

 

차이를 잘 몰랐었는데 실질적인 개발에는 대부분 객체 지향을 사용했지만 코딩 테스트 문제의 경우 대부분 함수형 프로그래밍을 사용한 것 같았다. 고차 함수를 더 활용해서 효율적인 코드 사용하는 방법을 더 연습해야겠다. 

 

객체 지향과 함수형 프로그래밍을 적절하게 잘 선택하고 조합해 활용할 수 있도록 더 공부해야겠다. 

 


 

출처

https://poiemaweb.com/js-array-higher-order-function

https://itstory1592.tistory.com/120

https://velog.io/@jakeseo_me/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EA%B0%9C%EB%B0%9C%EC%9E%90%EB%9D%BC%EB%A9%B4-%EC%95%8C%EC%95%84%EC%95%BC-%ED%95%A0-33%EA%B0%80%EC%A7%80-%EA%B0%9C%EB%85%90-22-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EA%B3%A0%EC%B0%A8-%ED%95%A8%EC%88%98Higher-Order-Function-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0

https://medium.com/@la.place/higher-order-function-%EC%9D%B4%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80-1c61e0bea79

 

'TIL' 카테고리의 다른 글

비동기 프로그래밍 (Callback, Promise, Async/Await)  (0) 2024.08.16
웹 프로토콜  (0) 2024.08.15
http와 https의 통신 방법 차이  (0) 2024.08.13
브라우저의 렌더링 과정  (0) 2024.08.12
[PB] 7주차 스터디 정리  (0) 2024.08.06

HTTP와 HTTPS의 가장 큰 차이 : 보안

 

HTTP : Hypertext Transfer Protocol - 클라이언트와 서버 간 통신을 위한 통신 규칙 세트, 또는 프로토콜

HTTPS : Hypertext Transfer Protocol Secure - HTTP의 확장, 더 안전한 버전

 

* 브라우저에서는 HTTPS가 아닌 모든 웹 사이트는 안전하지 않은 것으로 표시된다.

 

HTTS 프로토콜의 작동 버전

HTTP는 암호화 되지 않은 데이터를 전송한다. 데이터를 안전하게 만들기 위해 HTTP는 HTTP 요청 및 응답을 SSL 및 TLS 기술에 결합한다. 

HTTPS 웹 사이트는 독립된 인증 기관인 CA(Certificate Authority)에서 SSL/TLS에서 인증서를 획득해야 한다.

SSL : Security Sockets Layer, 보안 소켓 계층

TLS : Transport Layer Security, 전송 계층 보안

SSL 인증서는 암호화 정보를 포함하므로 서버와 웹 브라우저는 암호화 된 데이터나 스크램블된 데이터를 교환할 수 있다. 

 

1. 사용자 브라우저의 주소 표시줄에 https:// URL 형식을 입력하여 HTTPS 웹사이트를 방문한다.

 

2. 브라우저는 서버의 SSL 인증서를 요청하여 사이트의 신뢰성을 검증하려고 시도한다.

 

3. 서버는 퍼블릭 키가 포함된 SSL 인증서를 회신으로 전송한다. 

 

* 비대칭 공개 키 인프라를 사용 - 두 개의 서로 다른 키를 사용하여 두 당사자 간의 통신을 암호화

: 개인 키 _ 웹 사이트 소유자가 관리하며, 비공개로 유지된다. 공개 키로 암호화 된 정보를 해독하는 데 사용.

: 공개 키 _ 안전한 방식으로 서버와 상호 작용하고자 하는 모든 사람이 사용 가능. 공개 키로 암호화 된 정보는 개인 키로만 해독이 가능.

 

4. 웹 사이트의 SSL 인증서는 서버 아이덴티티를 증명한다. 브라우저에서 인증되면, 브라우저가 퍼블릭 키를 사용하여 비밀 세션 키가 포함된 메시지를 암호화하고 전송한다.

 

5. 웹 서버는 개인 키를 사용하여 메시지를 해독하고 세션 키를 검색한다. 그런 다음, 세션 키를 암호화하고 브라우저에 승인 메시지를 전송한다. 

 

6. 이에 브라우저와 웹 서버 모두 동일한 세션 키를 사용하여 메시지를 안전하게 교환하도록 전환한다. 

 

HTTPS를 선택하는 이유

- 보안

: HTTP 메시지는 일반 텍스트여서 권한이 없는 당사자가 인터넷을 통해 쉽게 액세스할 수 있다.

하지만 HTTPS는 모든 데이터를 암호화 된 형태로 전송하고 받기 때문에 권한이 없는 경우 데이터에 접근할 수 없다.

 

- 권위

: 검색 엔진은 더 안전성 있는 HTTPS의 순위를 HTTP 웹 사이트보다 높게 지정한다.

 

- 성능 및 분석

: HTTPS 웹 애플리케이션은 HTTP 애플리케이션보다 로드 속도가 더 빠르다.

HTTPS 는 참조 링크도 더 잘 추적이 가능하다.

 

HTTPS에 관한 정보

- ACM (Amazon Certificate Manager)은 AWs 서비스 및 내부 연결 리소스와 함께 사용할 수 있는 퍼블릭 및 프라이빗 SSL/TLS 인증서를 프로비저닝, 관리 및 배포한다. ACM은 SSL/TLS 인증서를 구매, 업로드 및 갱신하는 시간 소모적인 수동 프로세스를 대신 처리한다. 

 

AWS Certificate Manager

 

인증 관리자 - AWS Certificate Manager - AWS

AWS Certificate Manager(ACM)를 사용하면 AWS 서비스 및 연결된 내부 리소스에 사용할 공인 및 사설 SSL/TLS 인증서를 프로비저닝, 관리 및 배포할 수 있습니다. ACM은 SSL/TLS 인증서를 구매, 업로드 및 갱신

aws.amazon.com

 

- CloudFlare는 2014년 Universal SSL을 출시했으며 SSL 인증서를 무료로 제공한 최초의 기업이다. 손쉽게 HTTPS를 활성화 가능하다.

 

CloudFlare

 

모든 곳을 연결하고, 보호하며, 구축합니다

복잡성과 비용을 줄이면서 직원, 애플리케이션, 네트워크를 어디에서든 더 빠르고 안전하게 만듭니다.

www.cloudflare.com

 

 

'TIL' 카테고리의 다른 글

웹 프로토콜  (0) 2024.08.15
함수형 프로그래밍 (Function Programming)  (0) 2024.08.14
브라우저의 렌더링 과정  (0) 2024.08.12
[PB] 7주차 스터디 정리  (0) 2024.08.06
[PB] 4주차 스터디 정리  (0) 2024.07.21

탐색 (Navigation)

: 웹 페이지를 로딩하는 첫 단계

- URL 전송

- 링크 클릭

- 폼 제출 등의 동작으로 요청 시 발생

=> 탐색까지의 과정을 최소화 하는 것이 목표

 

DNS 조회 (DNS Look Up)

: Domain Name System. 해당 페이지의 자원이 어디에 위치하는 지 찾는 것.

브라우저에서 DNS 조회를 요청한다 

=> 해당 Domain의 서버에 의해서 처리되고, IP 주소로 응답.

=> 일정 기간 동안 캐시되기 때문에 캐시되는 동안 다시 조회 할 경우 캐시에서 IP 주소를 검색하여 후속 요청.

 

TCP HandShake

: 연결을 설정하기 위해 데이터 전송 전 통신하려는 두 주체의 TCP 소켓이 매개변수를 주고 받을 수 있도록 한다.

 

TLS Negotiation

: 보안성있는 연결을 위한 또 다른 핸드셰이크. 통신 암호화에 쓰일 암호를 결정하고, 서버를 확인한다.

ACK 이후 보안성을 위한 왕복 과정을 더 거쳐야 한다.

 

 

응답 (Response)

: 웹 서버로 한 번 연결이 성립되고 나면, 브라우저는 유저 대신 초기 request를 보낸다. 웹 사이트는 대게 HTML 파일을 요청한다. 서버가 요청을 받을 시, 관련 응답 헤더와 함께 HTML의 내용을 응답하게 된다.

혼잡 제어(Congestion Control) / TCP 슬로우 스타트 (TCP Slow Start)

: TCP 패킷은 전송 중에 세그먼트로 분할된다. 서버는 세그먼트를 전송한 후 클라이언트로부터 ACK 패킷 형태로 승인을 받아야 한다. 전송 시간 증가 혹은 과부하를 막기 위해 세그먼트 수의 균형을 맞춰야 한다. 이를 위해 TCP 슬로우 스타트 알고리즘을 사용하여 데이터의 양을 점차적으로 늘리고 부하가 높은 경우 전송되는 데이터의 양을 줄인다. 

 

구문 분석 (Parsing)

: 브라우저가 데이터 청크를 받으면, 구문 분석을 시작한다.

브라우저가 네트워크를 통해 받은 데이터를 DOM이나 CSSOM으로 바꾸는 단계이다. 이는 렌더러가 화면에 페이지를 그리는 데 사용된다.

DOM 트리 구축

HTML을 처리하여 DOM 트리를 만든다. 

- 토큰화와 트리 생성을 포함한다. 

- DOM 트리는 문서의 내용을 설명한다.

CSSOM 구축 (Building the CSSOM)

: CSS를 처리하고 CSSOM 트리를 만드는 것. 브라우저는 CSS 규칙을 이해할 수 있고 작업을 진행할 수 있도록 스타일 맵으로 변환한다. 

CSSOM 트리는 사용자 에이전트의 스타일 시트를 포함한다.

렌더 (Navigation)

: 렌더링 과정에는 스타일, 레이아웃, 페인트 그리고 합성이 포함된다. 

 

CSSOM과 DOM 트리는 구문 분석되는 과정에서 생성되고 렌더 트리로 합성된다.

렌더 트리는 보이는 요소의 레이아웃을 계산한다.

그리고 요소가 화면에 페인트 된다.

 

레이아웃 (Layout)

: 각 노드의 도형 값을 계산하기 위해 레이아웃을 실행하는 것.

처음 노드의 사이즈와 위치가 결정되는 것을 레이아웃,

이후 노두의 크기와 위치를 다시 계산하는 것을 리플로우 라고 부른다. 

상호작용 (Interactivity)

: TTI (Time to Interactive) 는 DNS 조회와 SSL 연결이 이루어지는 첫 요청부터 페이지가 상호작용할 준비가 될 때까지 얼마가 걸리는 지를 측정하는 단위이다. 

 

 

쉽게 정리

Domain 조회 => 실제 서버 연결 => 서버에서 클라이언트로 HTML 파일 전송 => 구문 분석 과정 중 DOM 트리, CSSOM 트리 생성 => 분석 종료 시 두 트리를 합쳐 Render Tree 생성.

근데 만약 JS 포함 시 ? HTML 파싱 중 Script 태그를 만나 JS 실행을 위해 파싱 중단 => 제어 권한을 JS 엔진에게 넘김.

 

 

+ 리액트의 렌더링 과정

: 렌더 단계 + 커밋 단계로 이루어진, 브라우저가 렌더링에 필요한 DOM 트리를 만드는 과정

 

렌더 단계

: 렌더가 트리거되면 DOM 에 그려질 요소들을 파악하는 과정을 거치게 된다.

 

초기 렌더 : render() 메소드의 루트 컴포넌트 호출

리렌더 : 상태 업데이트가 발생한 컴포넌트 호출

커밋 단계

- 렌더 단계의 변경 사항을 실제 DOM에 적용해 사용자에게 보여준다.

 

1. 렌더링 프로세스가 시작

=> 리액트는 루트부터 훑으며 변경 사항이 있는 컴포넌트를 찾는다.

2. 변경사항이 있어 업데이트가 필요한 컴포넌트를 찾으면 클래스 내부의 render() 함수를 실행

=> 결과물 저장

3. 렌더링 결과물은 JSX 문법으로 구성 => JS로 컴파일 되면서 React.createElement()를 호출하는 구문으로 변환하며 JS 객체를 반환.

4. 가상 DOM과 비교해 실제 DOM에 반영하기 위한 모든 변경 사항을 차례로 수집

 

 


 

 

참고

https://developer.mozilla.org/ko/docs/Web/Performance/How_browsers_work

'TIL' 카테고리의 다른 글

웹 프로토콜  (0) 2024.08.15
함수형 프로그래밍 (Function Programming)  (0) 2024.08.14
http와 https의 통신 방법 차이  (0) 2024.08.13
[PB] 7주차 스터디 정리  (0) 2024.08.06
[PB] 4주차 스터디 정리  (0) 2024.07.21

React로 웹사이트 만들기

React Router로 웹사이트 만들기

  • 리액트에서는 모든 것을 컴포넌트로 만든다
    • 웹페이지도 컴포넌트화해서 만드는 것
  • React Router 라이브러리를 통해 쉽게 만들 수 있다.
  • Single Page Application
  • Client-side Rendering
  • Server-side Rendering

리액트 라우터 v6 소개

  • 리액트 라우터
    • 리액트 컴포넌트로 페이지를 나누는 라이브러리
  • Router
    • 리액트 라우터에서 사용하는 데이터를 모두 가지고 있는 역할
    • Context
      • Props를 거치지 않고 데이터를 넘겨 준다
        • 데이터를 넘겨주는 부위 → Context Provider
  • Routes
  • Route
  • Link
    • 리액트 라우터에서 a 태그 대신 사용하는 것

Routes로 페이지 나누기

function Main() {
  return (
    <BrowserRouter>
      <App>
        <Routes>
          <Route path="/" element={<HomePage />} />
          <Route path="courses" element={<CourseListPage />} />
          <Route
            path="courses/react-frontend-development"
            element={<CoursePage />}
          />
          <Route path="wishlist" element={<WishlistPage />} />
        </Routes>
      </App>
    </BrowserRouter>
  );
}

export default Main;
  • Routes 컴포넌트는 여러 개 Route를 포함한다.
  • 위에서부터 차례대로 path와 일치하는 지 검사한다.
  • 일치하는 path를 찾을 시 지정한 element를 실행한다.
    • elemet는 jsx 함수를 지정한다!

Link로 이동하기

    <Link to="/courses">카탈로그</Link>
  • / 를 사용하는 이유 : 절대 경로임을 표시하기 위해서이다.

NavLink로 네비게이션 구현하기

  • 네비게이션에서 사용하는 링크라는 뜻
  • style 속성으로 스타일을 지정해줄 수 있다.
function getLinkStyle({ isActive }) {
  return {
    textDecoration: isActive ? 'underline' : '',
  };
}

 <NavLink style={getLinkStyle} to="/courses">

useParams로 동적인 경로 만들기

  • path로 모든 변수를 지정할 수는 없기 때문에 알아서 변수를 지정해 path를 결정하는 것을 동적인 경로라고 말한다.
<Route path=":courseSlug" element={<CoursePage/>}

없는 페이지 처리하기

 <Route path="*" element={<NotFoundPage />} />

Navigate로 리다이렉트하기

  • 이유가 있어서 페이지를 리다이렉트해야하는 경우
  • 로그인 되어있지 않은 경우 로그인 페이지로 리다이렉트하는 로직 설계 가능
  if (!course) {
    return <Navigate to="/courses" />;
  }
  • Navigate로 편하게 설계 가능

useSearchParams로 쿼리 사용하기

  • 쿼리 스트링
    • 주소에서 추가적인 조건을 넣을 때 사용할 수 있다.
{initKeyword && courses.length === 0 ? (
        <Warn
          className={styles.emptyList}
          title="조건에 맞는 코스가 없어요."
          description="올바른 검색어가 맞는지 다시 한 번 확인해 주세요."
        />
      ) : (
        <div className={styles.courseList}>
          {courses.map((course) => (
            <CourseItem key={course.id} course={course} />
          ))}
        </div>
      )}

react-helmet

 <Helmet>
        <title>Codethat - 코딩이 처음이라면, 코드댓</title>
 </Helmet>
  • head에 덮어쓰기 때문에 helmet 태그
  • 컴포넌트마다 title을 덮어쓸 수 있다.

싱글 페이지 어플리케이션 이해하기

  • 싱글 페이지 어플리케이션이란
    • 하나의 HTML 문서
    • 하지만 자바스크립트로 여러 페이지를 보여줄 수 있다.
  • 클라이언트 사이드 렌더링
    • 웹 브라우저에서 자바스크립트로 HTML 페이지를 만드는 것
      • a 태그 대신 link를 사용한 이유
        • request를 보내지 않고
        • 화면을 렌더링할 수 있다.
  • 서버 사이드 렌더링
    • 서버에서 HTML을 만들고 리스폰스로 보내주는 것
      • 훨씬 빨리 화면을 띄어줄 수 있고 SEO에서 좋은 점수를 받을 수 있다는 장점
  • 정적 사이트 생성
    • 미리 HTML을 만들어서 서버에서 배포하는 것
    • 데이터가 거의 바뀌지 않는다면 매번 새로 만들 필요가 없기 때문에 유용하다.

렌더링을 활용한 리액트 기술 세 가지

  • Next.js
    • 서버 사이드 렌더링을 대신 구현해주는 기술
    • 자바스크립트 파일을 나눠 곧바로 페이지로 사용할 수 있다는 장점
  • Gatsby
    • 리액트 코드를 미리 렌더링해서 프로젝트를 빌드할 때 HTML 파일로 만든다.
    • 정적인 회사 소개 사이트 / 동아리 홈페이지 / 포트폴리오 사이트 같이 정적인 사이트를 만드는 경우 추천
  • React Native
    • 리액트로 작성한 코드를 모바일 앱으로 만들 수 있게 한다.

'TIL' 카테고리의 다른 글

웹 프로토콜  (0) 2024.08.15
함수형 프로그래밍 (Function Programming)  (0) 2024.08.14
http와 https의 통신 방법 차이  (0) 2024.08.13
브라우저의 렌더링 과정  (0) 2024.08.12
[PB] 4주차 스터디 정리  (0) 2024.07.21

+ Recent posts