728x90

과거에 next.js의 튜토리얼을 진행하면서 얕게 streaming에 대해 학습한 적이 있습니다. 그 당시에 깊게 이해하지 못한 부분에 대해서 다시 한번 정리하고자 포스팅을 작성하게 되었습니다.

 

전통적인 SSR의 단점

SSR은 서버에서 완성된 HTML을 클라이언트에 전송해줍니다. SSR이 진행되는 과정은 아래와 같습니다.

1. 먼저, 특정 페이지에 필요한 모든 데이터가 서버에서 가져와집니다.
2. 그런 다음, 서버에서 해당 페이지의 HTML을 렌더링합니다.
3. 이후, 페이지의 HTML, CSS, 그리고 JavaScript가 클라이언트로 전송됩니다.
4. 전송된 HTML과 CSS를 사용하여 비상호작용 UI가 화면에 표시됩니다.
5. 마지막으로, React가 UI를 하이드레이션(hydration) 하여 상호작용할 수 있도록 만듭니다.

그렇기에 한 페이지 내에서도 모든 구역이 동시에 작업이 완료되진 않습니다. 하지만 우린 완성된 HTML을 받기 때문에, 하나라도 오래 걸리는 작업이 생기면 HTML을 받지 못하는 문제점을 겪게 됩니다.

출처 : https://nextjs.org/docs/app/building-your-application/routing/loading-ui-and-streaming#what-is-streaming

 

 

이를 보완해주는 것이 Next.js의 Streaming 기능입니다.

 

Streaming이란?

Next.js에서는 Streaming을 아래와 같이 정의합니다

Streaming 데이터를 전송하는 기술로, 하나의 라우트를 더 작은 "청크(chunks)"로 분할하여 서버에서 클라이언트로 준비되는 대로 점진적으로 스트리밍할 수 있도록 합니다.
Streaming is a data transfer technique that allows you to break down a route into smaller "chunks" and progressively stream them from the server to the client as they become ready.

 

 

그 결과  Time To First Byte (TTFB) , First Contentful Paint (FCP) ,Time to Interactive (TTI) 를 향상 시킬 수 있습니다.

 

상호작용 시작 시간  |  Lighthouse  |  Chrome for Developers

Lighthouse의 상호작용 시작 시간 측정항목과 이 측정항목을 측정하고 최적화하는 방법을 알아보세요.

developer.chrome.com

 

Streaming 사용방법

Streaming은 크게 2가지의 경우로 사용법이 구분됩니다.

1. 페이지단위로 사용하기

2. 컴퍼넌트단위로 사용하기

 

1. 페이지 단위로 사용하기

export default function Loading() {
  // You can add any UI inside Loading, including a Skeleton.
  return <LoadingSkeleton />
}

 

Lodaing.tsx 파일은 React Suspense를 기반으로 하는 Next.js의 특별한 파일로, 페이지 콘텐츠가 로드되는 동안 대신 표시할 Fallback UI를 생성할 수 있도록 해줍니다. 보통 Layout.tsx에 위치합니다.

 

2. 컴퍼넌트 단위로 사용하기

import { Suspense } from 'react'
import { PostFeed, Weather } from './Components'
 
export default function Posts() {
  return (
    <section>
      <Suspense fallback={<p>Loading feed...</p>}>
        <PostFeed />
      </Suspense>
      <Suspense fallback={<p>Loading weather...</p>}>
        <Weather />
      </Suspense>
    </section>
  )
}

 

이 경우에는 react에서 제공하는 Suspense를 활용하여 Streaming을 사용할 수 있습니다.

 

 

 

참고 링크

 

https://nextjs.org/docs/app/building-your-application/routing/loading-ui-and-streaming#what-is-streaming

 

Routing: Loading UI and Streaming | Next.js

Built on top of Suspense, Loading UI allows you to create a fallback for specific route segments, and automatically stream content as it becomes ready.

nextjs.org

https://nextjs.org/learn/dashboard-app/streaming

 

App Router: Streaming | Next.js

Improve your application's loading experience with streaming and loading skeletons.

nextjs.org

 

 

 

 

728x90

3d 오브젝트를 만드는데는 여러 프로그램이 있습니다. 이중에서 오픈소스 기반 무료인 blender를 통해서 원하는 오브젝트를 만들고, 최종적으로 gltf 혹은 glb파일을 만들어서 웹에 애니메이션 효과를 주고자 배우기 시작하게 되었습니다.

 

 

 

3d viewport  : 왼쪽 오브젝트들이 존재하는 격자가 존재하는 공간으로, 3d 오브젝트를 시각적으로 보여주는 공간

Outliner : 우측 상단에  Camera cube등이 표시된 공간이며  존재하는 3d오브젝트에 대한 개요를 보여줌

Property Editor : 우측 하단의 각각의 오브젝트 클릭시 적용할 수 있는 editor 및 옵션들이 나오는 영역

 

 Viewport 화면 전환

마우스 휠 : 화면 확대/축소

마우스 휠 + 이동  :  Viewport 화면 각도 제어
Shift + 마우스 휠  + 이동 : Viewport 화면 xyz축 제어

Number pad 1~9 :  특정 xyz축 각도에 대해서 이동

 

 

Object 이동 회전  크기  변형

이동 : G . 회전 : R , 크기 : S , 변형 : T

좌측 버튼을 클릭 시 원하는 기능 선택 가능 가능함. 이때 N을 누를 경우 object의 세부 정보 확인 가능

G가 적용된 상태에서 x,y,z를 누르면 각각 x,y,z축에 대한 기능 적용 가능

초기화는 Alt+ 각각의 단축키 (ex : alt+g 는 이동 초기화)

여러 Object  클릭하기

드래그를 통해 클릭하기 or  shift하고 각각 클릭하기

 

Object  생성하기

상단 add를 통해서 오브젝트를 추가할 수 있습니다. 단축키로는 Shift + a 로 생성할 수 있습니다

이때 신규 오브젝트는  Cursor(분홍 동그라미)의 위치에 생성됩니다. 이떄 cursor는 Shitt + S로 오리진으로 이동시킬 수 있습니다.

 

Snap 기능

G로 오브젝트 이동중에 G + B를 누르면 스냅 기능이 적용되며 다른 오브젝트에 붙일 때 사용할 수 있다.

 

 

Shading

Shading : 오브젝트에 색깔과 재질을 입히는 작업

상단 shading 탭을 클릭하여 작업 가능함

6시 하단의 하나하나의 창을  node라고 하며, 새로 추가한 오브젝트의 경우에는 클릭 시 new 버튼을 통해 추가할 수 있다.

 

basic color : 색 조정

metallic : 금속 느낌 (0~1)

Roughness : 표면 거칠기와 반사조절

 

마우스 올리고 백스페이스 누를 경우 기본값으로 초기화됨

이때 오브젝트끼리 동일한 material을 공유할 수 있음

 

Shading 탭에서 상단을 보면 위측에 4개의 버튼을 확인할 수 있습니다

각각의 버튼을 통해서 Viewport에 보이는 화면을 다르게 할 수 있습니다.

좌측에서 우측으로 갈 수록 실제 화면과 유사해집니다. 대신 컴퓨터 리소스를 많이 사용하게 됩니다.

728x90

React, Vue , Angular 는 보통 프론트엔드 UI 프레임워크로 묶여서 자주 언급됩니다. 사실 처음 개발을 시작할 때, 유저 수가 가장 많은 React를 선택했고 React기반의 RN 이나 Next.js를 사용해봤지만 아직 다른 UI프레임워크를 경험한 적이 없습니다. 그래서 React 다음으로 유저수가 많은 Vue의 공식문서를 통해 학습하고 간단한 TODOLIST를 만들며 느낀점을 공유하고자 합니다.

 

VUE 에 대해 전해 들은 장점

VUE가 쉽다는 얘기를 평소에 많이 들었습니다. 면접을 갔을 때도 생산성에 대한 질문도 많이 받았고, VUE를 쓰는 기업이라면 VUE의 생산성에 대해서 긍정적인 얘기를 합니다.  또한 React와 다른 양방향 바인딩에 대한 얘기도 많이합니다. 

https://www.youtube.com/watch?v=-tVaahsXpwk&list=PLfLgtT94nNq3Br68sEe26jkOqCPK_8UQ-&index=1

 

또한 Vue를 쓰다 React를 쓰는 경우 리렌더링을 잡기 어렵다는 얘기도 많이 들었습니다.

 

하지만 React를 쓰는 입장에서 사실 생산성이란 익숙함에서 더욱 기인하지 않을까?라는 생각이 들었고, 굳이 Vue에 대해 학습할 필요성을 느끼기 보단, React를 더욱 잘 쓰는 방법이 제 관심사였습니다.

하지만 최근 들어 Vue에 대해서 경험하고자 간단하게 Todolist를 작성하면서 학습하게 되었습니다.

 

 

Vue와 React의 비교

1. 진입점

진입점의 경우에는 비슷하다고 느꼈습니다.

// react의 main.tsx

import { createRoot } from 'react-dom/client'
import './index.css'
import App from './App.tsx'

createRoot(document.getElementById('root')!).render(
    <App />
)

 

// vue의 main.ts

import { createApp } from 'vue';
import './style.css';
import App from './App.vue';

createApp(App).mount('#app');

 

 함수명이 Root와 app이 다르고 render냐 mount냐 다르지만 결국 함수들이 선언적으로 되어있고, 의도하는 바는 동일해 보입니다.

 

2.  SFC와 JSX(TSX)

Vue의 경우에는 SFC라는 .vue로 파일이 구성되어 있고, React의 경우 컴퍼넌트를 jsx 혹은 tsx에서 사용합니다.

 

//App.vue

<script lang="ts">
import { defineComponent } from 'vue';
import TodoApp from './components/TodoApp.vue';

export default defineComponent({
  components: {
    TodoApp,
  },
});
</script>

<template>
  <div id="app">
    <h1>Todo List</h1>
    <TodoApp />
  </div>
</template>

<style>
#app {
  font-family: Arial, sans-serif;
  text-align: center;
  margin: 20px;
}
</style>

 

// App.tsx
import TodoApp from "./components/TodoApp";

function App() {
  return (
    <div>
      <h1>Todo List</h1>
      <TodoApp />
    </div>
  );
}

 

SFC는 Single-File Components 의 약자로  html, css, js를 하나의 컴퍼넌트에서 관리하는 Vue의 파일형식입니다.

template에서 html , script 에서 js , style에서 css를 다룹니다. 물론 별도의 module을 import하는 방식으로 css와 js를 관심사 분리할 수도 있습니다. 하지만  Vue측의 입장은 "관심사항의 분리가 파일 유형의 분리와 동일한 것이 아니다는 관점으로 바라보는 것이 중요하다"입니다. 하나의  컴퍼넌트가 명확하게 관심사가 분리가 되어있다면 , 굳이 css나 js를 따로 분리하기보다 응집되는 것 또한 매력적일 수 있기 때문입니다.

이때 style의 경우에는  scoped 태그를  적용함으로서 module.css 역할을 할 수 있게 할 수 있습니다.

 

3. 상태 관리

vue의 경우에는 v-model을 통한 양방향 바인딩을 지원합니다.

아래는 vue로 만든 간단한 todolist 입니다.

<script lang="ts">
import { defineComponent, ref } from 'vue';

// Todo 타입 정의
interface Todo {
  id: number;
  text: string;
  completed: boolean;
}

export default defineComponent({
  name: 'TodoApp',
  setup() {
    // 상태 정의
    const newTodo = ref<string>(''); // 입력 필드 상태
    const todos = ref<Todo[]>([]); // 투두리스트 배열

    // 할 일 추가
    const addTodo = () => {
      if (newTodo.value.trim() === '') return;
      todos.value.push({
        id: Date.now(), // 고유 ID 생성
        text: newTodo.value.trim(),
        completed: false,
      });
      newTodo.value = '';
    };

    // 할 일 삭제
    const removeTodo = (index: number) => {
      todos.value.splice(index, 1);
    };

    // 할 일 완료/미완료 토글
    const toggleComplete = (index: number) => {
      todos.value[index].completed = !todos.value[index].completed;
    };

    return {
      newTodo,
      todos,
      addTodo,
      removeTodo,
      toggleComplete,
    };
  },
});
</script>

<template>
  <div>
    <div class="input-container">
      <input
        type="text"
        v-model="newTodo"
        placeholder="할 일을 입력하세요"
        @keyup.enter="addTodo"
      />
      <button @click="addTodo">추가</button>
    </div>
    <ul>
      <li
        v-for="(todo, index) in todos"
        :key="todo.id"
        :class="{ completed: todo.completed }"
      >
        <span @click="toggleComplete(index)">{{ todo.text }}</span>
        <button @click="removeTodo(index)">삭제</button>
      </li>
    </ul>
  </div>
</template>

 

vue의 경우에는 ref나 reactive등을 활용하여 상태관리를 할 수 있습니다. 

이때 v-model을 활용한 양방향 바인딩을 통해서 손쉽게 이벤트 핸들러 및 상태관리를 할 수 있습니다.

 

 

Vue를 사용하며 느낀점

vue를 사용하며 느낀점은 만약 바닐라 자바스크립트까지만 사용한 시점에서 새로운 프레임워크를 배운다면 vue가 react보다 사용이 쉽다고 느껴졌습니다. 컴퍼넌트의 경우에 매번 리랜더링되는 react와 다르게 Vue의 SFC파일은 변경된 상태에 대해서만 감지하여 최적화 측면에서도 수월한 점이 존재하다고 느꼈습니다. 

 

하지만 사용 유저가 많다는 커뮤니티적인 장점도 존재하고, 익숙함이 존재하는 시점에서 제게는 React가 더 쉽게 느껴졌습니다. Vue만의 독특한 문법들도 많이 존재하였습니다. 새로 배우는 입장에서 외울게 많다는 게 비용으로 느껴졌고, 좀 더 javascript 답게 코드를 작성할 수 있는 것은 React라는 느낌을 받았습니다. 

또한 오픈소스의 양적 측면에서도 React가 유리하다고 느꼈습니다.

 

다만 React와 Vue의 공식문서를 읽으면서 css의 중첩을 막기 위해 module이나 css-in-js를 사용하여 지역단위로  css를 적용하는 방식이나  사이드 이펙트를 감지하기 위해서 watcher 혹은 useEffect를 사용하는 방식이 결국 프레임워크는 도구나 사용법의 차이지 도달하는 방향은 유사하다는 느낌을 받았습니다.

 

 

 

 

 

+ Recent posts