<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Hain-tain.log</title>
        <link>https://velog.io/</link>
        <description></description>
        <lastBuildDate>Sun, 20 Oct 2024 12:59:22 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>Hain-tain.log</title>
            <url>https://velog.velcdn.com/images/hain-tain/profile/bafdefbf-a679-447b-b2cb-8470707cb7f9/social_profile.jpeg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. Hain-tain.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/hain-tain" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[쉽게 보는 이벤트 전파와 이벤트 위임 (이벤트 캡쳐링, 이벤트 버블링)]]></title>
            <link>https://velog.io/@hain-tain/%EC%89%BD%EA%B2%8C-%EB%B3%B4%EB%8A%94-%EC%9D%B4%EB%B2%A4%ED%8A%B8-%EC%A0%84%ED%8C%8C%EC%99%80-%EC%9D%B4%EB%B2%A4%ED%8A%B8-%EC%9C%84%EC%9E%84-%EC%9D%B4%EB%B2%A4%ED%8A%B8-%EC%BA%A1%EC%B3%90%EB%A7%81-%EC%9D%B4%EB%B2%A4%ED%8A%B8-%EB%B2%84%EB%B8%94%EB%A7%81</link>
            <guid>https://velog.io/@hain-tain/%EC%89%BD%EA%B2%8C-%EB%B3%B4%EB%8A%94-%EC%9D%B4%EB%B2%A4%ED%8A%B8-%EC%A0%84%ED%8C%8C%EC%99%80-%EC%9D%B4%EB%B2%A4%ED%8A%B8-%EC%9C%84%EC%9E%84-%EC%9D%B4%EB%B2%A4%ED%8A%B8-%EC%BA%A1%EC%B3%90%EB%A7%81-%EC%9D%B4%EB%B2%A4%ED%8A%B8-%EB%B2%84%EB%B8%94%EB%A7%81</guid>
            <pubDate>Sun, 20 Oct 2024 12:59:22 GMT</pubDate>
            <description><![CDATA[<h2 id="🤔-왜-알아야-할까">🤔 왜 알아야 할까?</h2>
<p>요즘 웹 생태계에서는 <strong>사용자와의 상호작용</strong>이 무척 중요합니다. 개발자는 <strong><code>이벤트</code></strong>를 활용하여 사용자의 동작을 확인하고 제어할 수 있습니다.</p>
<p>즉, 사용자와 직접적으로 소통하는 UI를 만드는 프론트엔드 개발자라면, 이벤트에 대해 알고 적절하게 활용할 줄 알아야 합니다.</p>
<p>오늘은 이러한 <strong>이벤트의 동작 방식</strong>인 <strong><code>이벤트 전파</code></strong>와 이벤트의 동작 방식을 활용하여 <strong>이벤트를 현명하게 처리하는 방법</strong>인 <strong><code>이벤트 위임</code></strong>에 대해 알아봅시다! </p>
<h2 id="✌️-이벤트-전파-이벤트는-v-모양으로-흐른다">✌️ 이벤트 전파, 이벤트는 V 모양으로 흐른다!</h2>
<blockquote>
<p>✔️ <strong>이벤트 전파</strong></p>
<p>이벤트 전파는 특정 이벤트가 발생한 요소에서 상위 또는 하위 요소로 전달되는 과정을 의미합니다. 이벤트 전달, 이벤트 흐름이라고 불리기도 합니다.</p>
</blockquote>
<p>즉, 이벤트 객체는 단순히 <em>띵동-</em> 하고 발생한 요소에만 생겼다가 사라지는 것이 아니라, 상위, 하위 요소로 흐릅니다. 그리고 이 흐름의 방향은 <strong>V 모양으로 흐릅니다.</strong></p>
<p>이벤트 전파는 전파 방향 및 도달 여부에 따라 총 3단계(캡쳐링 단계 - 타겟 단계 - 버블링 단계)로 이루어져 있습니다. 이벤트가 발생하면, 아래 3단계가 차례대로 일어납니다.</p>
<p>1) 최상단 요소로부터 전달되어 내려져왔다가, <em>(캡처링 단계)</em>
2) 이벤트가 실제로 발생한 요소에 도달하고, <em>(타겟 단계)</em>
3) 다시 최상단 요소로 전달되어 올라갑니다. <em>(버블링 단계)</em></p>
<p>그림과 예시를 통해 살펴볼까요? <code>ul</code> 안의 <code>li</code> 요소가 클릭되었다고 생각해봅시다.</p>
<p><img src="https://velog.velcdn.com/images/hain-tain/post/63882a41-e545-497c-bd3e-4e447947e29b/image.jpg" alt=""></p>
<h3 id="캡쳐링-단계">캡쳐링 단계</h3>
<ul>
<li>이벤트가 최상위 요소에서 실제 발생한 요소까지 위에서 아래로 전달되는 단계!</li>
<li>이 단계에서는 브라우저의 최상위 객체인 <code>window</code>부터 실제 클릭된 요소인 <code>li</code>까지 이벤트 객체가 전달됩니다.</li>
<li>캡쳐(capture)의 뜻은 &#39;잡다, 포착하다&#39; 라고 합니다. 실제 이벤트가 발생한 요소까지 포착해 내려가는 과정이라고 생각하면 쉽게 기억할 수 있을거에요!</li>
</ul>
<h3 id="타겟-단계">타겟 단계</h3>
<ul>
<li>이벤트가 실제 이벤트가 발생한 요소(타겟 요소)에 도달하는 단계!</li>
<li>이때, 타겟 요소에 등록된 이벤트 핸들러가 있다면 이벤트 핸들러가 호출 ➡️ 실행됩니다. 만약 <code>li</code>에 이벤트 핸들러가 등록되어있다면 타겟 단계에서 이벤트 핸들러가 실행되었을 겁니다.</li>
</ul>
<h3 id="버블링-단계">버블링 단계</h3>
<ul>
<li>이벤트가 타겟 요소에서 최상위 요소까지 아래에서 위로 전달되는 단계!</li>
<li>이 단계에서는 타겟 요소인 <code>li</code>에서 브라우저의 최상위 객체인 <code>window</code>까지 이벤트 객체가 전달됩니다.</li>
<li>버블(bubble)의 뜻은 &#39;거품&#39;인데요, 이벤트가 거품이 위로 뜨는 것처럼 아래에서 위로 떠로으는 과정이라고 생각하면 쉽게 기억할 수 있을거에요!</li>
</ul>
<h2 id="😁-이벤트-위임으로-이벤트를-현명하게-처리해보자">😁 이벤트 위임으로 이벤트를 현명하게 처리해보자!</h2>
<blockquote>
<p>✔️ <strong>이벤트 위임</strong></p>
<p>이벤트 위임이란 부모 요소에 이벤트 핸들러를 붙여서 자식 요소에서 발생하는 이벤트를 처리하는 방법을 말합니다. 이렇게 이벤트를 부모에게 위임한다고 하여 <code>이벤트 위임</code>이라고 부릅니다. (+이러한 이벤트 위임이 가능한 이유는 이벤트가 전파되기 때문입니다.)</p>
</blockquote>
<p>보통은 각 요소에 직접 이벤트 핸들러를 붙여야 하지만, 자식 요소에 동일한 이벤트 핸들러가 필요한 경우 <strong>부모 요소에 이벤트 핸들러를 하나만 붙여 효과적으로 이벤트를 처리할 수 있습니다.</strong></p>
<p>예를 들어, 여기 과일 리스트가 있습니다. 그리고 각 <code>li</code>요소를 클릭하면 클릭한 과일을 alret로 띄워주고 싶어요. 그렇다면 아래와 같이 나태낼 수 있습니다.</p>
<pre><code class="language-jsx">import React from &#39;react&#39;;

const FruitList = () =&gt; {
    const fruits = [
        { name: &#39;딸기🍓&#39; },
        { name: &#39;바나나🍌&#39; },
        { name: &#39;수박🍉&#39; },
        { name: &#39;포도🍇&#39; }
    ];

    const handleClick = (fruit) =&gt; {
        alert(`클릭한 과일은 ${fruit}입니다.`);
    };

    return (
        &lt;ul id=&quot;fruitList&quot;&gt;
            {fruits.map((fruit, index) =&gt; (
                &lt;li key={index} onClick={() =&gt; handleClick(fruit.name)}&gt; //각 요소에서 이벤트 처리
                    {fruit.name}
                &lt;/li&gt;
            ))}
        &lt;/ul&gt;
    );
};

export default FruitList;
</code></pre>
<p>지금 위 코드는 각각의 <code>li</code>요소에 이벤트 핸들러를 부착했어요. li가 총 4개이니, 4개의 이벤트 핸들러를 생성하였다고 볼 수 있습니다.</p>
<p>각 <code>li</code>요소에 클릭 이벤트를 따로 붙이는 대신, 부모 요소(<code>ul</code>)에 클릭 이벤트를 붙이면 어떨까요? (이벤트 전파 덕분에 부모 요소(<code>ul</code>)가 자식 요소(<code>li</code>)에서 발생하는 클릭 이벤트를 감지할 수 있겠죠?)</p>
<pre><code class="language-jsx">import React from &#39;react&#39;;

const FruitList = () =&gt; {
    const fruits = [
        { name: &#39;딸기🍓&#39; },
        { name: &#39;바나나🍌&#39; },
        { name: &#39;수박🍉&#39; },
        { name: &#39;포도🍇&#39; }
    ];

    const handleClick = (event) =&gt; {
        const fruitName = event.target.textContent;
        alert(`클릭한 과일은 ${fruitName}입니다.`);
    };

    return (
        &lt;ul id=&quot;fruitList&quot; onClick={handleClick}&gt; //부모가 이벤트 처리
            {fruits.map((fruit, index) =&gt; (
                &lt;li key={index}&gt;
                    {fruit.name}
                &lt;/li&gt;
            ))}
        &lt;/ul&gt;
    );
};

export default FruitList;
</code></pre>
<p>이렇게 하면 코드가 더 간단해지고, 새로운 요소가 추가될 때마다 따로 이벤트를 추가할 필요가 없습니다. 또한 이벤트 핸들러 1개만 생성되므로 메모리 측면에서도 효율적입니다. </p>
<p>즉, 우리는 이벤트 위임을 통해 이벤트를 더 현명하게 처리할 수 있습니다!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[쉽게 알아보는 CSR과 SSR]]></title>
            <link>https://velog.io/@hain-tain/%EC%89%BD%EA%B2%8C-%EC%95%8C%EC%95%84%EB%B3%B4%EB%8A%94-CSR%EA%B3%BC-SSR</link>
            <guid>https://velog.io/@hain-tain/%EC%89%BD%EA%B2%8C-%EC%95%8C%EC%95%84%EB%B3%B4%EB%8A%94-CSR%EA%B3%BC-SSR</guid>
            <pubDate>Tue, 08 Oct 2024 00:59:17 GMT</pubDate>
            <description><![CDATA[<p>CSR과 SSR은 뭘까요?</p>
<p>먼저 이 두 개념은 <strong><code>누가 HTML을 완성할 것인가?</code></strong> 라는 질문의 대답이라고 할 수 있습니다. 즉, 이 두 개념은 브라우저에서 렌더링하기 위해 필요한 뼈대를 완성하는 방식입니다.</p>
<ul>
<li><strong><code>브라우저(클라이언트)에서 완성할게!</code></strong>  ➡ <strong><code>CSR</code></strong></li>
<li><strong><code>서버에서 완성해서 보낼게!</code></strong>  ➡ <strong><code>SSR</code></strong></li>
</ul>
<blockquote>
<p>+ 브라우저 렌더링 과정이 궁금하다면? 
<a href="https://velog.io/@hain-tain/%EC%89%BD%EA%B2%8C-%EB%B3%B4%EB%8A%94-%EB%A0%8C%EB%8D%94%EB%A7%81-%EA%B3%BC%EC%A0%95">쉽게 보는 렌더링 과정</a></p>
</blockquote>
<h2 id="csr-client-side-rendering">CSR (Client Side Rendering)</h2>
<p>서버로부터 <code>빈 HTML파일 + DOM을 추가하는 JS 파일</code>을 받아, 브라우저가 동적으로 요소들을 추가하여 화면을 완성하는 방식입니다.</p>
<p><img src="https://velog.velcdn.com/images/hain-tain/post/b6f3bd7a-c2d9-4807-ac3e-021f78ef2116/image.JPG" alt=""></p>
<p>일반적으로 별도의 클라이언트 서버 없이 리액트 등을 사용하여 개발했다면 CSR 방식으로 렌더링하고 있을 확률이 큽니다. </p>
<h2 id="ssr-server-side-rendering">SSR (Server Side Rendering)</h2>
<p>서버에서 <code>HTML</code>을 완성해서 보내주면, 브라우저가 이를 그대로 화면에 그리는 방식입니다. </p>
<p><img src="https://velog.velcdn.com/images/hain-tain/post/d78182f8-c79b-4939-bc4e-598f72097ba1/image.JPG" alt=""></p>
<p>서버에서 이미 <code>HTML</code>을 완성하여 보내주기 때문에 초기 로딩 속도가 빠르다는 장점이 있습니다. 또한 이미 <code>HTML</code>이 채워져있기 때문에 SEO에 유리하다는 장점이 있습니다.</p>
<p>그러나 초기 렌더링에서 보여주는 화면은 신기루 같은 것입니다. 그저 화면만 보일 뿐 어떠한 상호작용(<em>클릭을 하면 어떤 일이 일어난다</em>)도 불가능합니다. 상호작용과 관련한 로직은 여전히 브라우저에서 JS 파일을 파싱하여 넣어주기 때문입니다.</p>
<p>즉, 초기 렌더링이 빠르더라도 상호작용은 그만큼 빨리 가능해지지 않을 수도 있습니다. <em>(그래도 개인적으로 유저가 로딩을 오래 보는 것 보다는 콘텐츠를 보고 있는 것이 UX적으로 좋다고 생각합니다. )</em></p>
<h2 id="유니버셜-렌더링-universal-rendering">유니버셜 렌더링 (Universal rendering)</h2>
<p>유니버셜 렌더링이란 앞서 설명한 <code>CSR</code> 과 <code>SSR</code>를 혼합하여 사용하는 방식입니다.</p>
<h2 id="마치며">마치며</h2>
<p>위 개념들은 렌더링의 방식일 뿐 언제나 더 좋은 방법은 없습니다.
각자의 상황에 맞춰 더 좋은 방식을 채택해봅시다!</p>
<hr>
<p>💌 함께 읽어보길 추천드려요</p>
<ul>
<li><a href="https://velog.io/@hain-tain/%EC%89%BD%EA%B2%8C-%EB%B3%B4%EB%8A%94-%EB%A0%8C%EB%8D%94%EB%A7%81-%EA%B3%BC%EC%A0%95">쉽게 보는 렌더링 과정</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[쉽게 보는 렌더링 과정]]></title>
            <link>https://velog.io/@hain-tain/%EC%89%BD%EA%B2%8C-%EB%B3%B4%EB%8A%94-%EB%A0%8C%EB%8D%94%EB%A7%81-%EA%B3%BC%EC%A0%95</link>
            <guid>https://velog.io/@hain-tain/%EC%89%BD%EA%B2%8C-%EB%B3%B4%EB%8A%94-%EB%A0%8C%EB%8D%94%EB%A7%81-%EA%B3%BC%EC%A0%95</guid>
            <pubDate>Sun, 06 Oct 2024 13:00:14 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/hain-tain/post/c6cdfbf4-5818-41a4-892c-a0af4cad105c/image.png" alt=""></p>
<p>렌더링이란 데이터를 눈에 보이는 형태로 변환하는 것을 뜻한다.</p>
<p>지금부터 <strong>내가 만든 웹페이지가 사용자의 눈에 보이기까지의 과정</strong>을 살펴보도록 하자!</p>
<blockquote>
<p>🚨 <em>저만의 언어로 설명하기 위해 생략과 재구조화가 이루어진 글임을 참고해주세요</em></p>
</blockquote>
<h2 id="start">START</h2>
<p>주소창에 <code>https://velog.io/@hain-tain/posts</code> 를 입력하고 엔터를 누르거나, <code>헤인의 벨로그 바로가기</code>를 클릭하면, 탐색이 시작된다. </p>
<h2 id="1-탐색">1. 탐색</h2>
<p>탐색이란 말 그대로, 해당 페이지를 보여주기 위해 필요한 자원들이 어디에 있는지 찾는 것이다. 만약 <code>https://example.com</code>를 탐색한다면 HTML 페이지는 IP 주소가 <code>93.184.216.34</code>인 서버에 위치하고 있다. 이처럼 내가 어떤 서버에 요청을 보내야 하는지 찾는 과정이 탐색 과정이다!</p>
<h2 id="2-요청을-위한-연결">2. 요청을 위한 연결</h2>
<p>이제 우리는 어떤 IP주소로 요청을 보내야 하는지 알아냈다! 그러나 바로 요청을 보낼 순 없다. 요청을 위한 연결 과정이 필요하다!!</p>
<h3 id="2-1-tcp-핸드셰이크">2-1. TCP 핸드셰이크</h3>
<p>두 컴퓨터 간 TCP 세션을 협상하고 시작하기 위해서 TCP가 3개의 메세지를 전달하는 과정을 말한다.</p>
<h3 id="2-2-tls-협상">2-2. TLS 협상</h3>
<p>HTTPS를 이용한 보안성있는 연결을 위해서 통신 암호화에 쓰일 암호를 결정하고, 서버를 확인하고, 실제 데이터 전송 전에 안전한 연결이 이루어지도록 하는 과정이다.</p>
<p><img src="https://velog.velcdn.com/images/hain-tain/post/7f0f1024-e566-4ef8-8db6-ef53311ccd04/image.png" alt=""></p>
<p>이 모든 왕복이 끝나면 드디어 브라우저는 <strong>요청을 할 수 있다!!</strong></p>
<h2 id="3-요청과-응답">3. 요청과 응답</h2>
<p>연결이 성립되면, 브라우저는 초기 <code>HTTP GET request</code>를 보내 HTML 파일을 요청한다. 서버는 요청을 받으면 관련 응답 헤더와 함께 HTML을 응답으로 준다. 이외에 필요한 css, js 도 함께 응답으로 준다.</p>
<h2 id="4-파싱과-렌더">4. 파싱과 렌더</h2>
<p>받은 HTML, css, js 파일을 분석하여 우리가 눈으로 볼 수 있는 웹페이지로 구성하는 단계이다. 이를 중요 렌더링 경로 (Critical Rendering Path)라고 부른다.</p>
<p>4-1. DOM 트리 생성</p>
<p>가장 먼저 HTML을 분석하여 DOM 트리를 만든다. DOM이란 Document Object Model의 약자로, HTML요소를 JavaScript Object처럼 조작할 수 있는 Model로 만드는 과정이다. HTML 태그와 1대 1 관계로 노드가 생성된다. 이때 트리는 다른 태그간의 관계와 계층을 반영한다. 예를 들어 다른 태그에 감싸져 있는 태그는 자식 노드입니다.</p>
<p>4-2. CSSOM 트리 생성</p>
<p>다음으로는 스타일 시트(css)를 분석하여 CSSOM 트리를 만든다.(이는 DOM처럼 트리구조를 가지지만 DOM과 별도의 문서이다.) 브라우저는 CSS에 있는 각각의 규칙을 읽고, 트리 노드를 만든다. 이때 CSS 선택기에 기반해서 부모 노드, 자식 노드, 형제 관계의 노드를 만들어진다.</p>
<p>4-3. Render 트리 생성
생성된 DOM과 CSSOM 트리를 합해 Render 트리를 만든다. 렌더 트리는 오직 보여지는 콘텐츠만 포함한다. 만약 요소에 <code>display: none</code> 이 적용되어 있다면, 해당 요소는 포함되지 않는다. 또한 일반적으로 헤드 섹션은 보여지는 정보를 포함하고 있지 않으므로 렌더트리 안에 포함되지 않는다.</p>
<p>4-4. 레이아웃
레이아웃 단계는 요소들이 페이지에서 배치되는 위치와 방법, 각 요소의 너비와 높이 그리고 서로 관련된 위치를 결정하는 단계이다.</p>
<p>4-5. 페인트
브라우저는 레이아웃 단계에서 계산된 각 박스를 실제 화면의 픽셀로 변환한다. 텍스트, 색깔, 경계, 그림자 및 버튼이나 이미지 같은 대체 요소를 포함하여 모든 요소의 시각적인 부분을 실제 화면에 그리는 단계이다.</p>
<p>이러한 단계를 거쳐서 우리 눈에 이 사이트가 보이는 것이다!</p>
]]></description>
        </item>
    </channel>
</rss>