<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>하루하루 발전하는 개발자와 블로그 </title>
    <link>https://dream-frontend.tistory.com/</link>
    <description>어제보다 성장한 오늘, 이전보다 더 나아진 세상을 지향하는 개발자의 블로그 입니다.</description>
    <language>ko</language>
    <pubDate>Fri, 7 Aug 2026 10:21:27 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>더 멋진 세상을 꿈꾸는 개발자</managingEditor>
    <item>
      <title>[HTTP] 웹브라우저의 요청 흐름</title>
      <link>https://dream-frontend.tistory.com/428</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이전 글에서 프로토콜은 '규약', '규칙'을 의미한다고 이야기 했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇다면 인터넷 프로토콜 스택에는 4계층이 이루어져 있는데 이에 대해 알아보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저, 프롵토콜 스택이란 데이터 통신에 활용되는 프로토콜의 구조에 관한 개념으로 계층화된 구조로 모여있는 프로토콜의 집합이라 생각하면된다. 그래서 우리는 이를 (Protocol Family)라고 부르기도 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 프로토콜은 용도에 따라 4개의 계층으로 이루어져 있다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;792&quot; data-origin-height=&quot;598&quot; width=&quot;506&quot; height=&quot;382&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/PX20j/btrfZrn2MQn/YSzOramCNl37MFzpSWj3K0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/PX20j/btrfZrn2MQn/YSzOramCNl37MFzpSWj3K0/img.png&quot; data-alt=&quot;인터넷 프로토콜 스택 4계층&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/PX20j/btrfZrn2MQn/YSzOramCNl37MFzpSWj3K0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FPX20j%2FbtrfZrn2MQn%2FYSzOramCNl37MFzpSWj3K0%2Fimg.png&quot; data-origin-width=&quot;792&quot; data-origin-height=&quot;598&quot; width=&quot;506&quot; height=&quot;382&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;인터넷 프로토콜 스택 4계층&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;어플리케이션 계층 :&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #ef6f53;&quot;&gt;&lt;b&gt;프로세스간 통신을 위해 설계된 계층&lt;/b&gt;&lt;/span&gt;. 예시) HTTP, FTP, TLS/SSL&lt;/li&gt;
&lt;li&gt;전송 계층(Transport Layer) :&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: #ef6f53;&quot;&gt;송신자와 수신자를 연결하는 서비스에 대한 정보&lt;/span&gt;&lt;/b&gt;를 담는 계층. 예) TCP, UDP&lt;/li&gt;
&lt;li&gt;인터넷 계층 :&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #ef6f53;&quot;&gt;&lt;b&gt;패킷을 목적지로 전송&lt;/b&gt;&lt;b&gt;하기 위한 정보&lt;/b&gt;&lt;/span&gt;를&amp;nbsp; 계층 예) IP&lt;/li&gt;
&lt;li&gt;네트워크 인터페이스 계층 : LAN 드라이버, LAN 장비 등 물리적 전송을 위한 계층&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;737&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bIovuJ/btrfU2C0ytf/LtgQOmEj5W0h6B2Vz7Nn3K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bIovuJ/btrfU2C0ytf/LtgQOmEj5W0h6B2Vz7Nn3K/img.png&quot; data-alt=&quot;출처: 강의 &amp;amp;#39;모든 개발자를 위한 HTTP 웹 기본지식&amp;amp;#39; (김영한) 인프런&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bIovuJ/btrfU2C0ytf/LtgQOmEj5W0h6B2Vz7Nn3K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbIovuJ%2FbtrfU2C0ytf%2FLtgQOmEj5W0h6B2Vz7Nn3K%2Fimg.png&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;737&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처: 강의 '모든 개발자를 위한 HTTP 웹 기본지식' (김영한) 인프런&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;실제 인터넷을 이용해 서로 통신할 때 위와 같이 하나씩 덧씌어져 서버에 보내진다고 생각하면 된다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자, 그러면 이제 출발지와 목적지를 담은 IP를 보완해주는 정보를 담는 TCP, UDP에 대해 알아보자.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. TCP / IP 패킷 정보&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 패킷은 'package' + 'buket'의 합성어로 한 마디로 '수하물 덩어리'라고 생각하면 된다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1190&quot; data-origin-height=&quot;664&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cjpf3v/btrfU2JL3IS/cGBk7xR6svscUzNNSkRjjk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cjpf3v/btrfU2JL3IS/cGBk7xR6svscUzNNSkRjjk/img.png&quot; data-alt=&quot;출처: 강의 &amp;amp;#39;모든 개발자를 위한 HTTP 웹 기본지식&amp;amp;#39; (김영한) 인프런&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cjpf3v/btrfU2JL3IS/cGBk7xR6svscUzNNSkRjjk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcjpf3v%2FbtrfU2JL3IS%2FcGBk7xR6svscUzNNSkRjjk%2Fimg.png&quot; data-origin-width=&quot;1190&quot; data-origin-height=&quot;664&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처: 강의 '모든 개발자를 위한 HTTP 웹 기본지식' (김영한) 인프런&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;TCP&lt;/b&gt;는 Transmission Control Protocol의 약자로 전송 제어 프로토콜이라고 생각하면 된다. 즉, &lt;u&gt;&lt;b&gt;전송을 어떻게 할지를 제어하는 규약&lt;/b&gt;&lt;/u&gt;이다. TCP를 이용하면 IP 만으로 해결이 되지 않았던 '순서', '전송' 제어 등이 가능하다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;TCP의 특징은 아래와 같다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;1. 연결 지향 - TCP 3 way handshake (가상연결)&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; IP는 그저 상대 컴퓨터가 켜져 있는지 없는지 상관없이 그냥 보내기만 한다면, TCP는 이러한 점을 보완하여 대상 컴퓨터와 내가 연결이 되는지를 확인하고 메시지를 보낸다. 즉, 가상연결이 먼저 이루어진 다음에 실제 '전송'을 하는 것이다. 이를 &lt;b&gt;TCP 3 way handshake&lt;/b&gt;라 하는데 이는 실제로 그 연결 단계가 3번이나 이루어지기 때문이며 이에 대한 자세한 내용은 여기서 다루지는 않겠다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;2. 데이터 전달을 보증할 수 있다.&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; IP 같은 경우, 상대 컴퓨터가 꺼져 있어서 전송이 이루어지지 않아도 확인할 방법이 없었다면, TCP는 데이터를 보낸 후 상대 컴퓨터에서 확인 메시지를 받기 때문에 메시지가 누락될 경우, 이를 알 수 있다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;3. 패킷의 순서가 보장된다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 패킷의 순서가 잘못된 경우, 대상 컴퓨터는 TCP에 적힌 메시지와 비교하기 떄문에 순서가 잘못된 것을 인식하여 해당 번호부터 다시 보내라고 클라이언트에 요청하게 된다. 이것이 가능한 이유는 TCP에 전송제어 정보, 순서 정보들이 포함되어 있기 때문이다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, TCP는 신뢰할 수 있는 프로토콜이며 IP를 보완하기에 현재, 대부분 TCP를 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2. UDP의 특징&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;UDP란 User Datagram Protocol의 약자로 사용자 데이터그램 규약이라 생각하면 된다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;이는 사실 '하얀 도화지'와 같다. 기능이 거의 없기 때문이다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;데이터 전달 보증이나 순서 보장이 안된다는 점에서 IP와 거의 비슷하다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;그러나 PORT와 '체크섬' 정보와 기능이 추가된다는 점이 특징적이다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇다면 IP에는 없지만 UDP와 TCP에 있는 port란 무엇인가?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자, 여러분이 평상시에 사용하는 노트북을 생각해보자. '인터넷 동작 방식'에 대한 발제를 하기 위해 노트북을 열었다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇다면 당신은 과연 발제를 준비하기위한 keynote만 켤 것인가?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일단, 한국인의 필수 통신인 '카카오톡'부터 열고 시작하며, 음악도 들으면서 인터넷 검색도 하면서 동시에 가십거리 기사도 보고 있을 수 있다. 이렇듯 우리는 하나의 컴퓨터(하나의 IP)로 게임도 하고 음악도 듣고 있는 등 다양한 일을 한다. 그러면 내 컴퓨터 IP에 여러 패킷이 들어오게 되는데 각각 어떤 패킷인지 구분해 주는 정보가 바로 PORT이다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;더불어 이 메시지에 대해 제대로 맞는지 검증해주는 것이 '체크섬'인 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러면 UDP의 특징은 그저 PORT와 체크섬 정도인 것 같은데 PORT 정보는 TCP도 가지고 있는데 왜 굳이 UDP가 필요할까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;TCP는 3 way handshake 도 해야하기 때문에 은근히 시간이 좀 걸릴 수 있다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터 양이 많다면 속도도 좀 더 느려질 수 밖에 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이럴때, 최적화 하고 싶을 때 TCP는 그대로 두고 UDP에 손을 대어 최적화를 하면 된다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 이 UDP 프로토콜이 최근에 각광을 받고 있다.&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;3. 웹브라우저의 요청 흐름&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자, 그럼 다시 정리를 해보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리가 구글 웹사이트에 접속하려 한다고 생각해보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 그 과정은 아래와 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 사용자가 url을 작성한다. (https://www.google.com:443)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. &lt;a href=&quot;http://www.google.com&quot;&gt;www.google.com&amp;nbsp;&lt;/a&gt; 주소의 DNS를 조회하여 IP주소를 얻는다. https의 port 443은 생략된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 웹브라우저에서 http 요청 메시지를 생성한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. soket 라이브러리를 이용해 TCP/IP(3 way handshake 포함) 연결 후 대상 IP에 데이터(http 메시지)를 전달한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. 이렇게 패킷이 인터넷 망에 딱 던져지면 수 많은 노드를 통해 대상 IP로 전달이 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;6. 대상 서버인 구글서버에 요청패킷이 도착하면 구글 서버는 TCP/IP를 까서 버리고 안에 있는 HTTP 메시지를 해석한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;7. get요청이 담긴 이 메시지에 해당하는 정보를 찾은 후 '응답 메시지'를 만들어 아래와 같이 'HTTP 응답 메시지'를 클라이언트에 보낸다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1228&quot; data-origin-height=&quot;588&quot; width=&quot;720&quot; height=&quot;345&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bjsZxB/btrf0stGePZ/oiPxcTu6tas7FIckDk2buk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bjsZxB/btrf0stGePZ/oiPxcTu6tas7FIckDk2buk/img.png&quot; data-alt=&quot;출처: 강의 &amp;amp;#39;모든 개발자를 위한 HTTP 웹 기본지식&amp;amp;#39; (김영한) 인프런&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bjsZxB/btrf0stGePZ/oiPxcTu6tas7FIckDk2buk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbjsZxB%2Fbtrf0stGePZ%2FoiPxcTu6tas7FIckDk2buk%2Fimg.png&quot; data-origin-width=&quot;1228&quot; data-origin-height=&quot;588&quot; width=&quot;720&quot; height=&quot;345&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처: 강의 '모든 개발자를 위한 HTTP 웹 기본지식' (김영한) 인프런&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;8. 클라이언트는 받은 응답 메시지의 내용을 화면에 보여준다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;출처 : &lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;'모든 개발자를 위한 HTTP 웹 기본 지식' -김영한 (인프런강의)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(&lt;a href=&quot;https://www.inflearn.com/course/http-%EC%9B%B9-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC/dashboard&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.inflearn.com/course/http-%EC%9B%B9-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC/dashboard&lt;/a&gt;)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Study/CS</category>
      <author>더 멋진 세상을 꿈꾸는 개발자</author>
      <guid isPermaLink="true">https://dream-frontend.tistory.com/428</guid>
      <comments>https://dream-frontend.tistory.com/428#entry428comment</comments>
      <pubDate>Sat, 25 Sep 2021 23:25:52 +0900</pubDate>
    </item>
    <item>
      <title>[HTTP] 인터넷 통신에 대하여</title>
      <link>https://dream-frontend.tistory.com/427</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1000&quot; data-origin-height=&quot;667&quot; width=&quot;745&quot; height=&quot;497&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cP4iOa/btrfWcdKH6I/ta8YoNAvLhIqL6G8XgSEQK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cP4iOa/btrfWcdKH6I/ta8YoNAvLhIqL6G8XgSEQK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cP4iOa/btrfWcdKH6I/ta8YoNAvLhIqL6G8XgSEQK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcP4iOa%2FbtrfWcdKH6I%2Fta8YoNAvLhIqL6G8XgSEQK%2Fimg.jpg&quot; data-origin-width=&quot;1000&quot; data-origin-height=&quot;667&quot; width=&quot;745&quot; height=&quot;497&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;중학생때, 한창 영어 배우는 것에 호기심을 가지던 시절&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;영국인 중학생과 이메일 펜팔을 했던 것이 생각난다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물론 내용은 &quot;난 오늘 학교 다녀왔어. 그리고 저녁은 ~을 먹었어. 너는 무엇을 했니?&quot; 뭐 이런 내용이었지만 ㅎㅎ&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 사사로운 이야기 마저 굉장히 설레였던게 생각난다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내가 지구 반대편에 있는 사람과 이렇게 일상적인 이야기를 주고 받을 수 있다니!!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저 멀리 있는 영국인 중학생과 나는 어떻게 이메일을 주고 받을 수 있었을까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인터넷에서 컴퓨터 둘은 어떻게 통신을 하며 텍스트를 주고 받을 수 있는가?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. 인터넷이 통신하는 방법&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자, 일단 간단하게 먼저, 두 개의 컴퓨터가 통신한다고 생각해보자.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여러분이 생각하실 때에는 두 대의 컴퓨터가 서로 어떠한 정보를 주고 받기 위해서 무엇이 필요하다고 생각하는가?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 물리적으로 연결한다. (이더넷 케이블)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 무선으로 연결한다. (wifi, bluetooth)&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데, 우리는 딱 한대의 컴퓨터만 연결해서 사용하지 않는다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;중학생 시절의 나는 영국에 사는 친구, 남아공에 사는 친구, 호주에 사는 친구와도 이메일을 주고 받을 수 있을 것이다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어떻게 그게 가능할까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;네트워크는 단지 두 대의 컴퓨터로 제한되지 않기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리가 원하는 만큼의 컴퓨터를 연결할 수 있다. 그러나 그럴 경우, 엄청나게 많은 케이블이 필요할 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 문제를 해결하기 위해 네트워크의 각 컴퓨터는 라우터라고 하는 특수한 소형 컴퓨터에 연결된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1306&quot; data-origin-height=&quot;1216&quot; width=&quot;515&quot; height=&quot;480&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ToM6H/btrfWMe5ZF1/J6eJ29bIi01wZgFCWY8sCk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ToM6H/btrfWMe5ZF1/J6eJ29bIi01wZgFCWY8sCk/img.png&quot; data-alt=&quot;출처 : mdn 인터넷은 어떻게 동작하는가?&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ToM6H/btrfWMe5ZF1/J6eJ29bIi01wZgFCWY8sCk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FToM6H%2FbtrfWMe5ZF1%2FJ6eJ29bIi01wZgFCWY8sCk%2Fimg.png&quot; data-origin-width=&quot;1306&quot; data-origin-height=&quot;1216&quot; width=&quot;515&quot; height=&quot;480&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : mdn 인터넷은 어떻게 동작하는가?&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자, 이런 그림이 되는 것이다. 우리는 이 라우터를 이용해 총 10대의 컴퓨터와 각 각 통신을 할 수 있게 되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇다면 만약 수백, 수천, 수십억 대의 컴퓨터를 연결하면 어떻게 될까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내가 아프리카 세네갈의 한 프랑스 언어교육원 홈페이지(&lt;a href=&quot;https://ifs.sn/#/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://ifs.sn/#/&lt;/a&gt;)에 들어가고 싶을 수도 있고,&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;미국의 아마존 사이트(&lt;a href=&quot;https://www.amazon.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.amazon.com/&lt;/a&gt;)에 들어가 해외물품을 구입하고 싶을 수도 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;바로 라우터에 라우터를 연결하고- 이런식으로 우리는 무한히 확장 할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1374&quot; data-origin-height=&quot;1194&quot; width=&quot;568&quot; height=&quot;493&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bDED2Q/btrfZqvQxhS/RpcJnkjQO42SSwD9Dufb9k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bDED2Q/btrfZqvQxhS/RpcJnkjQO42SSwD9Dufb9k/img.png&quot; data-alt=&quot;출처 : mdn 인터넷은 어떻게 동작하는가?&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bDED2Q/btrfZqvQxhS/RpcJnkjQO42SSwD9Dufb9k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbDED2Q%2FbtrfZqvQxhS%2FRpcJnkjQO42SSwD9Dufb9k%2Fimg.png&quot; data-origin-width=&quot;1374&quot; data-origin-height=&quot;1194&quot; width=&quot;568&quot; height=&quot;493&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : mdn 인터넷은 어떻게 동작하는가?&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 네트워크를 우리는 우리의 친구, 이웃에 연결할 수는 있어도 아주 먼 다른 지역에 케이블을 연결할 수는 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 문제를 해결하기 위해 네트워크는 이미 잘 갖추어진 전화 시설에 연결된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리는 이 네트워크를 인터넷 서비스 제공업체(Internet Service Provider, ISP)에 연결한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, 우리의 메시지는 &lt;u&gt;&lt;b&gt;ISP 네트워크의 네트워크를 통해 우리가 도달하고자 하는 대상 네트워크로 전달&lt;/b&gt;&lt;/u&gt;이 된다!&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 지역 네트워크에 연결된 컴퓨터와 그 안에 속한 장비들을 통틀어 하나의 '&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;u&gt;&lt;b&gt;노드&lt;/b&gt;&lt;/u&gt;&lt;/span&gt;'라고 칭한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자, 그럼 다시 돌아와서 중학생 시절의 내가 보냈던 이메일은 어떻게 영국에 있는 친구의 메일 계정이 저장된 서버 컴퓨터에 도달해 내 텍스트를 전달할 수 있었을까?&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저 수많은 노드들 중에서 어떻게 특정 서버 컴퓨터를 찾아낼 수 있었을까?&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2. IP주소&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;바로 IP 주소를 이용해서이다.&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1000&quot; data-origin-height=&quot;667&quot; width=&quot;649&quot; height=&quot;433&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Iay8C/btrfVtmQgVu/nMVkJI3bog16YU8WUR4wy0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Iay8C/btrfVtmQgVu/nMVkJI3bog16YU8WUR4wy0/img.jpg&quot; data-alt=&quot;저 맥북, 아이패드 모두 각각 고유한 IP 주소를 가지고 있다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Iay8C/btrfVtmQgVu/nMVkJI3bog16YU8WUR4wy0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FIay8C%2FbtrfVtmQgVu%2FnMVkJI3bog16YU8WUR4wy0%2Fimg.jpg&quot; data-origin-width=&quot;1000&quot; data-origin-height=&quot;667&quot; width=&quot;649&quot; height=&quot;433&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;저 맥북, 아이패드 모두 각각 고유한 IP 주소를 가지고 있다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인터넷이 연결된 모든 기기에는 각각 고유의 IP 주소가 부여된다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 기기가 서로 통신을 주고 받을 때에도 이 IP주소를 이용하는 것이다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;689&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/m3W3R/btrfRnVfqGl/u4WRcKtUL7JPtNpxxFcKv1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/m3W3R/btrfRnVfqGl/u4WRcKtUL7JPtNpxxFcKv1/img.png&quot; data-alt=&quot;출처: 강의 &amp;amp;#39;모든 개발자를 위한 HTTP 웹 기본지식&amp;amp;#39; (김영한) 인프런&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/m3W3R/btrfRnVfqGl/u4WRcKtUL7JPtNpxxFcKv1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fm3W3R%2FbtrfRnVfqGl%2Fu4WRcKtUL7JPtNpxxFcKv1%2Fimg.png&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;689&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처: 강의 '모든 개발자를 위한 HTTP 웹 기본지식' (김영한) 인프런&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런식으로 각 IP주소를 이용해 대상자를 찾아 전달을 해주는데,&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컴퓨터가 서로 통신하기 위해서는 어떤 '규약, 규정'이 있어야 하지 않겠는가?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그것이 바로 '&lt;b&gt;Protocol&lt;/b&gt;'이며 &lt;b&gt;HTTP&lt;/b&gt;는 &lt;u&gt;문서간에 링크를 통해 연결할 수 있는 html을 전송하는 규약, 규칙&lt;/u&gt;을 뜻하는&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;&lt;b&gt;HyperText Transfer Protocol&lt;/b&gt;&lt;/u&gt; 이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;출처 : &lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;'모든 개발자를 위한 HTTP 웹 기본 지식' -김영한 (인프런강의)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(&lt;a href=&quot;https://www.inflearn.com/course/http-%EC%9B%B9-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC/dashboard&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.inflearn.com/course/http-%EC%9B%B9-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC/dashboard&lt;/a&gt;)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인터넷은 어떻게 동작하는가? - mdn&lt;b&gt; (&lt;a href=&quot;https://developer.mozilla.org/ko/docs/Learn/Common_questions/How_does_the_Internet_work&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://developer.mozilla.org/ko/docs/Learn/Common_questions/How_does_the_Internet_work&lt;/a&gt;)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Study/CS</category>
      <author>더 멋진 세상을 꿈꾸는 개발자</author>
      <guid isPermaLink="true">https://dream-frontend.tistory.com/427</guid>
      <comments>https://dream-frontend.tistory.com/427#entry427comment</comments>
      <pubDate>Sat, 25 Sep 2021 22:36:36 +0900</pubDate>
    </item>
    <item>
      <title>가상돔</title>
      <link>https://dream-frontend.tistory.com/426</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리액트는 렌더링 성능을 위해 가상 돔을 활용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;브라우저에서 돔을 변경하는 것은 비교적 오래 걸리는 작업이다. 따라서 빠른 렌더링을 위해서는 돔 변경을 최소화 해야한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 리액트는 메모리에 가상 돔을 올려 놓고 이전과 이후의 가상 돔을 비교해서 변경된 부분만 실제 돔에 반영하는 전략을 채택했다.&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;리액트 요소 이해하기&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JSX문법으로 작성된 코드는 리액트의 createElement 함수로 변경된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리액트가 UI를 표현하기 위해 사용하는 리액트 요소의 구조를 살펴보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1631959022372&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const elementJSX = &amp;lt;a href=&quot;https://shinyeong.com&quot;&amp;gt;click here&amp;lt;/a&amp;gt;
const element = React.createElement(
  'a',
  { href: 'https://shinyeong.com' },
  'click here',
);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;첫줄의 elementJSX코드는 아래의 element 코드로 변경된다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;리액트 요소가 돔 요소로 만들어지는 과정&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하나의 화면을 표현하기 위해 여러 개의 리액트 요소가 트리(tree)구조로 구성된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로그램 화면은 여러 가지 이벤트를 통해서 다양한 모습으로 변화한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하나의 리액트 요소 트리는 시간에 따라 변화하는 화면의 한 순간을 나타낸다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리액트에서 데이터 변경에 의한 화면 업데이트는 '렌더 단계(render phase)와 커밋단계(commit phase)를 거친다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;렌더 단계&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제 돔에 반영할 변경 사항을 파악하는 단계. 변경사항을 파악하기 위해&amp;nbsp;&lt;b&gt;가상 돔&lt;/b&gt;을 이용한다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;커밋 단계&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파악된 변경사항을 실제 돔에 반영하는 단계&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;가상돔&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가상돔은 리액트 요소로부터 만들어진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리액트는 렌더링을 할 때마다 가상돔을 만들고 이전의 가상 돔과 비교한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이는 실제 돔의 변경 사항을 최소화하기 위한 과정이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1173&quot; data-origin-height=&quot;785&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c6BxKb/btrfoli26OJ/Bz3wBaAGKmkkZxD8cepem0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c6BxKb/btrfoli26OJ/Bz3wBaAGKmkkZxD8cepem0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c6BxKb/btrfoli26OJ/Bz3wBaAGKmkkZxD8cepem0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc6BxKb%2Fbtrfoli26OJ%2FBz3wBaAGKmkkZxD8cepem0%2Fimg.png&quot; data-origin-width=&quot;1173&quot; data-origin-height=&quot;785&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리액트의 가상돔 과정은 다음과 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;변경사항이 생기면 &lt;b&gt;ReactDOM.render()가 호출&lt;/b&gt;된다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 과정은 위에서 언급했듯이 &lt;b&gt;변경점을 찾는 과정(렌더 단계)&lt;/b&gt;과 변경점을 &lt;b&gt;실제 UI에 적용하는 과정(커밋단계)&lt;/b&gt;으로 나뉜다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;[변경점을 찾는 작업]&lt;/span&gt;&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;React는 Virtual DOM을 통하여 브라우저 DOM에 전달하기 전에 Reconciliation라는 비교 과정을 선행하기 때문에 UI에 대한 제어를 최소화 시킨다.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Render가 진행 될 때마다, 각 Element들은 key를 부여 받고, 해당 key를 통해 같은 Element라고 인식 되고 비교 된다. (물론, 계층이 달라지게 될 경우는 제외된다. 또, React diff 알고리즘은 필터 관련 기능에 취약하다고 한다. 많은 list를 필터하는 경우, 이것을 기억하고 해결책을 찾아보기로 기약하자.)&lt;/li&gt;
&lt;li&gt;이런 비교 과정을 최소화 시키기 위해&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;background-color: #f6e199; color: #ee2323;&quot;&gt;shouldComponentUpdate(), PureComponent&lt;/span&gt;&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;를 활용한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;코드로 살펴보는 리액트의 가상돔 과정&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음 코드는 할일의 우선순위를 상탯값으로 관리하는 코드다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;할일의 제목과 내용은 부모 컴포넌트가 속성 값으로 내려준다.&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1631959913602&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Todo extends React.Component {
  state = {
    priority: 'high',
  };
  
  onClick = () =&amp;gt; {
    const { priority } = this.state;
    this.setState({ priority: priority === 'high' ? 'low' : 'high' });
  };
  
  render() {
  	const { title, desc } = this.props;
    const { priority } = this.state;
    return (
      &amp;lt;div&amp;gt;
      	&amp;lt;Title title={title} /&amp;gt;
        &amp;lt;p&amp;gt;{desc}&amp;lt;/p&amp;gt;
        &amp;lt;p&amp;gt;{priority === 'high' ? '우선순위 높음' : '우선순위 낮음'}&amp;lt;/p&amp;gt;
        &amp;lt;button onClick={this.onClick}&amp;gt;우선순위 변경&amp;lt;/button&amp;gt;
      &amp;lt;/div&amp;gt;
    );
  }
};

class Title extends React.PureComponent {
  render() {
  	const { title } = this.props;
    return &amp;lt;p style={{ color: 'blue' }}&amp;gt;{title}&amp;lt;/p&amp;gt;
  }
};

ReactDOM.render(
  &amp;lt;Todo title=&quot;리액트 공부하기&quot; desc=&quot;실전 리액트를 열심히 읽는다&quot; /&amp;gt;
  document.getElementById('root'),
);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;버튼을 클릭하면 priority의 상탯값이 변화되고 화면을 다시 그린다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;PureCoponent로 만들어진 Title 컴포넌트는 상탯값이나 속성값이 변경될 때만 render 메서드를 호출한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ReactDOM.render 함수로 전달된 리액트 요소 트리의 구조는 다음과 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1631960082841&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const initialElementTree = {
  type: Todo, 
  props: {
    title: '리액트 공부하기',
    desc: '실전 리액트를 열심히 읽는다',
  },
  // ...
};&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리액트가 initialElementTree를 이용해서 실제 돔을 만드는 과정을 따라가 보자.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 Todo 컴포넌트의 렌더링 결과를 얻기 위해 Todo 컴포넌트의 렌더 함수를 호출한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1631960846789&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// Todo 컴포넌트의 렌더 함수 호출 결과

const elementTree = {
  type: 'div',
  props: {
    children: [
      {
        type: Title,
        props: { title: '리액트 공부하기' },
       //...
      },
      {
        type: 'p',
        props: { children: '리액트 스터디 모임을 갖는다' },
        // ...
      },
      {
        type: 'button',
        props: {
          onClick: function() {
            /* Todo 컴포넌트의 onClick 함수 */
          },
          children: '우선순위 변경',
        },
        //...
       },
     ],
   },
   // ...
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;트리의 루트는 div 태그로 변경된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아직 Title 컴포넌트가 존재하기 때문에 이 트리를 실제 돔으로 만들 수는 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리액트 요소 트리가 실제 돔으로 만들어지기 위해서는 모든 리액트 요소의 type 속성 값이 문자열이어야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이는 type 속성값이 문자열이어야 HTML 태그로 변환할 수 있기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러기 위해서는 모든 컴포넌트의 렌더 함수가 호출되어야 한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1631961284590&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// Title 컴포넌트의 렌더 함수 호출 결과

const elementTree = {
  type: 'div',
  props: {
    children: [
      {
        type: 'p',
        props: {
          children: [
            {
              type: 'p',
              props: {
                style: { color: 'blue' }, 
                children: '리액트 공부하기',
              },
              //...
            },
            {
              type: 'p',
              props: { children: '리액트 스터디 모임을 갖는다' },
              // ...
            },
            {
              type: 'button',
              props: {
                onClick: function() {
                  /* Todo 컴포넌트의 onClick 함수 */
                },
                children: '우선순위 변경',
             },
             //...
           },
         ],
       },
       // ...
      }
    ]
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Title 컴포넌트로 표현됬던 리액트 요소가 p태그로 변경되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 모든 리액트 요소의 type 속성 값이 문자열이므로 실제 돔을 만들 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이와 같이 실제 돔을 만들 수 있는 리액트 요소 트리를 '가상 돔'이라고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가상돔 : 최종 리액트 요소 트리를 만들기 위해 치환되는 컴포넌트의 리액트 요소도 메모리에 유지된다. 메모리에 저장된 컴포넌트의 리액트 요소는 렌더 단계의 효율을 높이는데 사용된다. 가상 돔은 UI에서 변경된 부분을 빨리 찾기 위한 개념이므로 컴포넌트의 리액트 요소도 가상 돔의 일부라고 생각할 수 있다.&amp;nbsp;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최초의 리액트 요소 트리로부터 가상 돔을 만들고 이전 가상 돔과 비교해서 실제 돔에 반영할 내용을 결정하는 단계를 위에서 말했듯이 '렌더단계'라 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리액트는 화면을 업데이트할 때, 이전의 가상 돔과 현재의 가상 돔을 비교해서 변경된 부분만 실제 돔에 반영한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;브라우저에서 실제 돔을 변경하는 작업은 다른 작업에 비해 시간이 오래 걸리기 때문에 꼭 필요한 부분만 변경하는 것이 중요하다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 랜더단계는 ReactDOM.render 함수와 setState 메서드에 의해 시작된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지금까지의 관계를 정리하자면 아래와 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;2304&quot; data-origin-height=&quot;632&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/doTDnQ/btrfqh0RVdt/asx3HkiW4sr0WCBMam5mp1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/doTDnQ/btrfqh0RVdt/asx3HkiW4sr0WCBMam5mp1/img.png&quot; data-alt=&quot;위 코드의 Todolist가 렌더단계와 커밋단계를 거쳐 가상돔을 이용해 렌더링 하는 방법을 이미지화함.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/doTDnQ/btrfqh0RVdt/asx3HkiW4sr0WCBMam5mp1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdoTDnQ%2Fbtrfqh0RVdt%2Fasx3HkiW4sr0WCBMam5mp1%2Fimg.png&quot; data-origin-width=&quot;2304&quot; data-origin-height=&quot;632&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;위 코드의 Todolist가 렌더단계와 커밋단계를 거쳐 가상돔을 이용해 렌더링 하는 방법을 이미지화함.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;지금까지 리액트 요소를 이용해 렌더 단계를 설명했지만, 엄밀히 말하면 리액트 요소는 &lt;b&gt;파이버(fiber)라는 구조체&lt;/b&gt;로 변환된다. 파이버는 리액트 버전 16부터 도입된 구조체 이름이다. 파이버도 리액트 요소와 같이 속성값을 가지며 모든 type 속성값이 문자열이 될 때까지 연산하다는 사실에는 변함이 없다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;참조자료 :&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 실전 리액트 프로그래밍&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- &lt;a href=&quot;https://ryublock.tistory.com/41&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://ryublock.tistory.com/41&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Study/React</category>
      <category>Virtual DOM</category>
      <category>가상돔</category>
      <category>가상돔 동작방식</category>
      <category>리액트</category>
      <author>더 멋진 세상을 꿈꾸는 개발자</author>
      <guid isPermaLink="true">https://dream-frontend.tistory.com/426</guid>
      <comments>https://dream-frontend.tistory.com/426#entry426comment</comments>
      <pubDate>Sat, 18 Sep 2021 18:25:00 +0900</pubDate>
    </item>
    <item>
      <title>브라우저 동작원리</title>
      <link>https://dream-frontend.tistory.com/425</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;크롬 브라우저를 사용한지 아마 어연 10여년이 되는 것 같다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대학생 때, 그저 흔히 사용해왔던 ie 보다 디자인이 더 깔끔하고 직관적인것 같아 맘에 들어 사용하기 시작했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어연 10여년을 사용했음에도 개발자가 되기 전까지는 이 브라우저가 어떠한 원리로 동작하는지 전혀 몰랐다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;직접 배포작업들을 거치면서 웹 브라우저는 어떠한 방식으로 동작할지 살펴보게 되었다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;브라우저의 주요 기능&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;브라우저의 주요 기능은 사용자가 선택한 자원을 서버에 요청하고 브라우저에 표시하는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자원은 보통 HTML 문서이지만 PDF나 이미지 또는 다른 형태일 수 있다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자원의 주소는 URI에 의해 정해진다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;브라우저 기본 구조&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1382&quot; data-origin-height=&quot;1016&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bjIe4U/btrfp14WxP8/Gh7mLLEePD6I9xiAzqX44K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bjIe4U/btrfp14WxP8/Gh7mLLEePD6I9xiAzqX44K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bjIe4U/btrfp14WxP8/Gh7mLLEePD6I9xiAzqX44K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbjIe4U%2Fbtrfp14WxP8%2FGh7mLLEePD6I9xiAzqX44K%2Fimg.png&quot; data-origin-width=&quot;1382&quot; data-origin-height=&quot;1016&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;사용자 인터페이스&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;요청한 페이지를 보여주는 창을 제외한 나머지 모든 부분을 의미한다. 예를 들면, 주소 표시줄이나 즐겨찾기 등을 말한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;브라우저 엔진&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사용자 인터페이스와 렌더링 엔진 사이의 동작을 제어한다. HTML 문서와 기타 자원의 웹 페이지를 사용자의 장치에 상호작용적인 시각 표현으로 변환시키는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;렌더링 엔진&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;요청한 콘텐츠를 표시한다. 예를들어, HTML을 요청하면 HTML과 CSS를 파싱하여 화면에 표시한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파이어폭스, 크롬, 사파리는 두 종류의 렌더링 엔진으로 제작되어 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 파이어폭스 : 게코엔진&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 사파리 : 웹킷&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 크롬 : 블링크&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;통신&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;HTTP 요청과 같은 네트워크 호출에 사용되며 이것은 플랫폼의 독립적인 인터페이스이고 각 플랫폼 하부에서 실행된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;UI 백엔드&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;콤보 박스와 창 같은 기본적인 장치를 그린다. 플랫폼에서 명시하지 않은 일반적인 인터페이스로서, OS 사용자 인터페이스 체계를 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;자바스크립트 해석기&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자바스크립트 코드를 해석하고 실행한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;자료 저장소&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 부분은 자료를 저장하는 계층이다. 쿠키를 저장하는 것과 같이 모든 종류의 자원을 하드 디스크에 저장할 필요가 있다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;HTML5 명세에는 브라우저가 지원하는 '웹 데이터 베이스'가 정의되어 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;렌더링 엔진의 동작과정&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1320&quot; data-origin-height=&quot;408&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lHdWI/btrfpfJp19e/XykIfybES69MxgU2KgyH7k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lHdWI/btrfpfJp19e/XykIfybES69MxgU2KgyH7k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lHdWI/btrfpfJp19e/XykIfybES69MxgU2KgyH7k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlHdWI%2FbtrfpfJp19e%2FXykIfybES69MxgU2KgyH7k%2Fimg.png&quot; data-origin-width=&quot;1320&quot; data-origin-height=&quot;408&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. HTML 마크업을 처리하여 &lt;b&gt;DOM 트리를 생성&lt;/b&gt;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. CSS 마크업을 처리하여 &lt;b&gt;CSSOM 트리를 생성&lt;/b&gt;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. DOM 트리와 CSSOM 트리를 결합하여 &lt;b&gt;렌더링 트리를 생성&lt;/b&gt;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. &lt;b&gt;랜더링 트리 배치&lt;/b&gt; : 각 노드에 대해 화면에서의 정확한 위치와 크기를 계산한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. &lt;b&gt;렌더 트리 그리기&lt;/b&gt; : UI 백엔드에서 렌더링 트리의 각 노드를 가로지르며 렌더링 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #222426;&quot;&gt;이 과정들은&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;b&gt;점진적으로 진행&lt;/b&gt;&lt;span style=&quot;color: #222426;&quot;&gt;된다. 렌더링 엔진은 모든 HTML을 파싱할 때까지 기다리지 않고 배치와 그리기 과정을 시작한다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #222426;&quot;&gt;네트워크로부터 나머지 내용이 전송되기를 기다리는 동시에 받은 내용의 일부를 먼저 화면에 표시한다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222426;&quot;&gt;이는 좀 더 나은 사용자 경험을 위한 것이다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1474&quot; data-origin-height=&quot;740&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cb2hnS/btrfpCElyZm/3AkKuyi4MF4IlggDgNJ0yk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cb2hnS/btrfpCElyZm/3AkKuyi4MF4IlggDgNJ0yk/img.png&quot; data-alt=&quot;웹킷 동작 과정&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cb2hnS/btrfpCElyZm/3AkKuyi4MF4IlggDgNJ0yk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcb2hnS%2FbtrfpCElyZm%2F3AkKuyi4MF4IlggDgNJ0yk%2Fimg.png&quot; data-origin-width=&quot;1474&quot; data-origin-height=&quot;740&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;웹킷 동작 과정&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;DOM의 Re-render&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Element를 추가, 수정, 생성하면서 DOM이 수정되면, Render Tree생성, Layout 생성, 표시가 다시 이루어진다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이는 리소스가 변경될 떄마다 전체 페이지를 갱신 시킨다고 생각하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 문제는 SPA(Single Page Application) 형식이 탄생하고, HTML 파일 규모가 커지고 나서 더 큰 문제로 이어졌다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;636&quot; data-origin-height=&quot;327&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xotHh/btrftmHiQc9/vP0TcBjk4RcjOnCUuwFDX0/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xotHh/btrftmHiQc9/vP0TcBjk4RcjOnCUuwFDX0/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xotHh/btrftmHiQc9/vP0TcBjk4RcjOnCUuwFDX0/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/xotHh/btrftmHiQc9/vP0TcBjk4RcjOnCUuwFDX0/img.gif&quot; data-origin-width=&quot;636&quot; data-origin-height=&quot;327&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DOM을 사용하는 JS Version 에서는 하나의 컴포넌트가 바뀌는데 변하지 않는 요소까지 모두 바뀌는 모습을 볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 외, DOM API가 확장 되면서 문제가 많이 발생했다고 한다.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;출처 : &lt;a href=&quot;https://ryublock.tistory.com/41&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://ryublock.tistory.com/41&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;a href=&quot;https://d2.naver.com/helloworld/59361&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://d2.naver.com/helloworld/59361&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>about front-end</category>
      <author>더 멋진 세상을 꿈꾸는 개발자</author>
      <guid isPermaLink="true">https://dream-frontend.tistory.com/425</guid>
      <comments>https://dream-frontend.tistory.com/425#entry425comment</comments>
      <pubDate>Sat, 18 Sep 2021 18:24:35 +0900</pubDate>
    </item>
    <item>
      <title>자바스크립트란?</title>
      <link>https://dream-frontend.tistory.com/424</link>
      <description>&lt;h1&gt;자바스크립트란?&lt;/h1&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2-1. 자바스크립트의 탄생&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1995년, &lt;u&gt;브라우저에서 동작하는 경량 프로그래밍 언어를 도입&lt;/u&gt;하며 탄생한 것이 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;Brendan Eich가 개발한 자바스크립트&lt;/span&gt;이다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;1600&quot; width=&quot;300&quot; height=&quot;375&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Xu0zo/btrcONuTleC/7SSeI8kqkYXCAGIkiPT2y1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Xu0zo/btrcONuTleC/7SSeI8kqkYXCAGIkiPT2y1/img.jpg&quot; data-alt=&quot;자바스크립트의 아버지, 브랜든 아이크&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Xu0zo/btrcONuTleC/7SSeI8kqkYXCAGIkiPT2y1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FXu0zo%2FbtrcONuTleC%2F7SSeI8kqkYXCAGIkiPT2y1%2Fimg.jpg&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;1600&quot; width=&quot;300&quot; height=&quot;375&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;자바스크립트의 아버지, 브랜든 아이크&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2-2. 자바스크립트의 표준화&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1996년, 넷스케이프 커뮤니케이션즈는 컴퓨터 시스템의 표준을 관리하는 비영리 표준화 기구인 ECMA 인터내셔널에 자바스크립트의 표준화를 요청한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1997년, 표준화된 자바스크립트 초판 사양이 완성되었고 자바스크립트는 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;ECMAScript&lt;/span&gt;로 명명된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2015년, &lt;span style=&quot;background-color: #f6e199;&quot;&gt;ECMAScript 6 (ES6)&lt;/span&gt;는 let/const 키워드, 화살표 함수, 클래스, 모듈 등과 같은 범용 프로그래밍 언어로서 갖춰야 할 기능들을 대거 도입하는 큰 변화가 있었다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2-3. 자바스크립트 성장의 역사&lt;/h2&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2-3-1. &lt;span style=&quot;background-color: #dddddd;&quot;&gt;Ajax&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1999년, 자바스크립트를 이용해 서버와 브라우저가 비동기(asynchronous) 방식으로 데이터를 교환할 수 있는 통신 기능은 Ajax (Asynchronous JavaScript and XML)가 XMLHttpRequest라는 이름으로 등장했다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Ajax의 등장으로 웹페이지에서 변경할 필요가 없는 부분은 다시 렌더링 하지 않고, 서버로부터 필요한 데이터만 전송받아 변경해야하는 부분만 한정적으로 렌더링 하는 것이 가능해졌다. 이로써 웹 브라우저에서도 빠른 성능과 부드러운 화면 전환이 가능해졌다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2-3-2. &lt;span style=&quot;background-color: #dddddd;&quot;&gt;JQuery&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2006년, JQuery의 등장으로 다소 번거롭던 DOM( Document Object Model) 을 더욱 쉽게 제어할 수 있게 되었고 크로스 브라우징 이슈도 어느정도 해결되었다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2-3-3. &lt;span style=&quot;background-color: #dddddd;&quot;&gt;V8 자바스크립트 엔진&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;v8 자바스크립트 엔진의 등장으로 자바스크립트는 데스크톱 앱과 유사한 사용자 경험 UX를 제공할 수 있는 웹 어플리케이션 프로그래밍 언어로 정착하게 되었다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;V8 자바스크립트 엔진으로 촉발된 JS의 발전으로 과거 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;웹 서버에서 수행되던 로직들이 대거 클라이언트(브라우저)로 이동&lt;/span&gt;했고, 이는 웹 앱 개발에서 프론트엔드 영역이 주목받는 계기로 작용했다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2-3-4. &lt;span style=&quot;background-color: #dddddd;&quot;&gt;Node.js&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2009년, 라이언 달이 발표한 Node.js는 구글 V8 자바스크립트 엔진으로 빌드된 자바스크립트 런타임환경이다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Node.js는 브라우저의 자바스크립트 엔진에서만 동작하던 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;자바스크립트를 브라우저 이외의 환경에서도 동작할 수 있도록 자바스크립트 엔진을 브라우저에서 독립시킨 자바스크립트 실행환경&lt;/span&gt;이다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자바스크립트의 동형성은 별도의 언어를 학습하기 위한 시간을 덜 수 있다는 장점이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Node.js는 비동기 I/O를 지원하며 단일 스레드 single thread 이벤트 루프 기반으로 동작함으로써 요청처리 성능이 좋다.&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 60px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style5&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 50%; text-align: center; height: 20px;&quot;&gt;적합&lt;/td&gt;
&lt;td style=&quot;width: 50%; text-align: center; height: 20px;&quot;&gt;부적합&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 40px;&quot;&gt;
&lt;td style=&quot;width: 50%; text-align: center; height: 40px;&quot;&gt;데이터를 실시간으로 처리하기 위해 I/O가 빈번하게 발생하는 &lt;br /&gt;SPA에 적합하다.&lt;/td&gt;
&lt;td style=&quot;width: 50%; text-align: center; height: 40px;&quot;&gt;CPU 사용률이 높은 애플리케이션에는 권장하지 않는다.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2-3-5.&lt;span style=&quot;background-color: #dddddd;&quot;&gt; SPA 프레임워크&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모던 웹 어플리케이션은 데스크톱 앱과 비교해도 손색없는 성능과 사용자 경험을 제공하는 것이 필수가 되었고, 더불어 개발 규모와 복잡도도 상승했다. &lt;br /&gt;복잡해진 개발 과정을 수행하기 위해 많은 패턴과 라이브러리가 출현했지만 변경에 유연하면서 확장하기 쉬운 애플리케이션 아키텍처의 구축을 어렵게 했고, 필연적으로 프레임워크가 등장하게 되었다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 요구에 발맞추어 Component Based Development 방법론을 기반으로 하는 SPA single page application이 대중화되면서 Angular, React, Vue.js, Svelte 등 다양한 SPA 프레임워크, 라이브러리 들이 등장하였따.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;간단히 둘러본 자바스크립트의 배경과 성장 과정이다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;브라우저에서 동작하는 경량 프로그래밍 언어로 시작해, 어플리케이션의 복잡도와 규모가 커지면서 그에 발맞추어 성능과 기능이 빠르게 성장하고 있는 자바스크립트. 나 또한 브라우저 화면에서 유일하게 동작하는 자바스크립트가 매력적이었고 나아가 백엔드 영역에서도 사용할 수 있다는 동형성이 매력도의 정점을 찍게 해주었다. 나중에 리액트에 좀 더 익숙해 질 때 쯤, 노드.js도 공부해 프론트와 백을 다루어 온전히 내가 만든 작은 프로젝트를 만들어 보고 싶다.&amp;nbsp;&lt;br /&gt;앞으로의 성장이 또한 기대되는 언어인 거 같다.&lt;/p&gt;</description>
      <category>Study/JavaScript</category>
      <author>더 멋진 세상을 꿈꾸는 개발자</author>
      <guid isPermaLink="true">https://dream-frontend.tistory.com/424</guid>
      <comments>https://dream-frontend.tistory.com/424#entry424comment</comments>
      <pubDate>Sun, 22 Aug 2021 22:32:36 +0900</pubDate>
    </item>
    <item>
      <title>Loading, Error 컴포넌트 생성하기 - 1. Skeleton Loading</title>
      <link>https://dream-frontend.tistory.com/422</link>
      <description>
            &lt;figure class=&quot;unsupported component-kakaotv&quot; contenteditable=&quot;false&quot; style=&quot;background:#000;margin:16px 0;min-height:72px;padding:10px 16px;display:flex;align-items:center;justify-content:center;text-align:center;box-sizing:border-box;width:100%;max-width:100%;&quot;&gt;
                &lt;p contenteditable=&quot;false&quot; style=&quot;margin:0;color:#8a8a8a;font-size:13px;line-height:1.6;user-select:none;pointer-events:none;&quot;&gt;동영상 서비스가 종료되어 해당 콘텐츠를 재생할 수 없습니다.&lt;/p&gt;
            &lt;/figure&gt;
        
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정말 오랜만에 블로깅을 한다. :)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오늘은 회사에서 로딩, 에러 컴포넌트 티켓을 담당하면서 처음에 생각한 것보다 굉장히 다양한 방법과 내용들이 포함되어 있는 것 같아 좀 더 공부할 겸 글로 남겨본다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 영상과 같이 웹 사이트내에서 로딩이 이루어지는 장면을 본 적 있을 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지난 주 나에게 맡겨진 task 중 하나가 바로 사용자에게 &quot;로딩, 에러&quot;를 안내함으로 사용자 경험이 지루하거나 답답하지 않도록 하는 것이 었다. 잠시 디자이너의 부재로 인해, 디자인과 기획까지 구상해야했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&quot;그래? 그냥, 데이터 로딩이 이루어질 동안 로딩 컴포넌트 보여주면 되겠지!&quot; 이게 처음 나의 단순한 생각이었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러나 로딩 화면을 보여주는데에는 다양한 디자인과 더불어 다양한 방식도 있었다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저, 로딩 화면을 구현하면서 구글링을 통해 처음 접한 개념이 바로 &quot;Skeleton Loaing&quot;방식이었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오늘은 먼저 이 skeleton loading에 대해 알아보자.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;900&quot; data-origin-height=&quot;470&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cuJgs3/btq9jFtxCC3/F1dOLCX2MUddik15EKssQK/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cuJgs3/btq9jFtxCC3/F1dOLCX2MUddik15EKssQK/img.gif&quot; data-alt=&quot;Skeleton loading screen for the usual blog post&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cuJgs3/btq9jFtxCC3/F1dOLCX2MUddik15EKssQK/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/cuJgs3/btq9jFtxCC3/F1dOLCX2MUddik15EKssQK/img.gif&quot; data-origin-width=&quot;900&quot; data-origin-height=&quot;470&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Skeleton loading screen for the usual blog post&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Skeleton Loading&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Skeleton Screen은 어플리케이션의 본질적인 wireframe 이다. 이 wireframe은 어플리케이션이 최종적으로 로드될때까지 대신 구조를 잡아주는 역할을 한다. (위의 이미지와 같이 말이다)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 것은 사용자들이 화면에 어떤 일이 일어나고 있는지 알게 해준다. 그래서 사용자는 어플리케이션이 부팅되고 있고, 컨텐츠가 로딩되고 있다는 것을 이해하게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;skeleton은 &quot;뼈대, 골격&quot; 라는 의미라는 것은 모두 알 것이다. 말 그대로, 어플리케이션의 뼈대와 골격을 미리 보여주는 로딩 방식이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #fdfdfd; color: #000000;&quot;&gt;스켈레톤 화면은 페이지 레이아웃을 모방한 사용자 인터페이스 버전이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;왜 Skeleton Loading Screen을 이용하는가?&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;빈 페이지를 표시하는 대신에 컨텐츠 뼈대를 표시하면 사용자는 어플리케이션의 응답 속도가 더 빠르다는 느낌을 받을 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 뺑글뺑글 돌아가는 로딩 스피너를 보여주는 대신에, 우리는 사용자가 어플리케이션을 시작하고 탐색할 때 진행 중인 상황을 확인할 수 있는 스켈레톤 화면을 표시하곤 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;사용방법&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 css로 해당 부분의 골격만 로딩 구간에서 보여주는 방식으로 구현했었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런게 검색해보니 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;react-loading-skeleton&lt;/span&gt;이라는 라이브러리가 있다는 것을 지금 글을 적으며 발견하였다ㅎㅎ&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1625999110601&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import React from &quot;react&quot;;
import Skeleton from &quot;react-loading-skeleton&quot;;

export default function BlogPost({ title, body, subTitle }) {
  return (
    &amp;lt;div&amp;gt;
      &amp;lt;h1&amp;gt;{title || &amp;lt;Skeleton /&amp;gt;}&amp;lt;/h1&amp;gt;
      &amp;lt;h3&amp;gt;{subTitle || &amp;lt;Skeleton /&amp;gt;}&amp;lt;/h3&amp;gt;

      &amp;lt;p&amp;gt;{body || &amp;lt;Skeleton count={6} /&amp;gt;}&amp;lt;/p&amp;gt;

      &amp;lt;button&amp;gt;
        {body ? &quot;Read more&quot; : &amp;lt;Skeleton height={25} width={100} /&amp;gt;}
      &amp;lt;/button&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자세한 사용방법은 아래 참조 글을 이용해 볼 수 있다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음에는 이 라이브러리를 이용하거나, 좀더 애니메이션을 더 추가한 skeleton방식으로 구현해보고 싶다 ;)&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참조 : &lt;a href=&quot;https://betterprogramming.pub/the-what-why-and-how-of-using-a-skeleton-loading-screen-e68809d7f702&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://betterprogramming.pub/the-what-why-and-how-of-using-a-skeleton-loading-screen-e68809d7f702&lt;/a&gt; (번역함)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Study/React</category>
      <author>더 멋진 세상을 꿈꾸는 개발자</author>
      <guid isPermaLink="true">https://dream-frontend.tistory.com/422</guid>
      <comments>https://dream-frontend.tistory.com/422#entry422comment</comments>
      <pubDate>Sun, 11 Jul 2021 19:27:10 +0900</pubDate>
    </item>
    <item>
      <title>신입 개발자에게 필요한 자세 - 1. 사람 된 마음과 자세 그리고 말</title>
      <link>https://dream-frontend.tistory.com/419</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;547&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ciqGaG/btq3l401bhW/2VdPli3XNfbzR4U0jY2FE1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ciqGaG/btq3l401bhW/2VdPli3XNfbzR4U0jY2FE1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ciqGaG/btq3l401bhW/2VdPli3XNfbzR4U0jY2FE1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FciqGaG%2Fbtq3l401bhW%2F2VdPli3XNfbzR4U0jY2FE1%2Fimg.jpg&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;547&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;신입 개발자가 되어보니, 나는 정말 많은 실수를 저지르고 있고 처음 보는 듯한 모르는 것들은 계속 생겨나 언덕을 오르고 또 오르게 되는 기분이다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;p&gt;실력이 좀 부족한 한 부하직원은 늘 잦은 실수를 하는 중에도 감사와 고마움의 표현을 열심히, 진심을 다해 전했다. 똑같은 실수에 지적을 거듭해도 수정 되기까지 한참이 걸렸고 다른 부서원에 비해 업무능력도 떨어져 상사인 내 입장에서는 고민이었는데, &lt;span style=&quot;color: #333333;&quot;&gt;늘 말 끝에 &quot;더 열심히 해서 선배의 짐을 들어드리겠습니다&quot; &quot;제 부족함을 감싸주셔서 감사합니다&quot; &quot;가르침에 누가 되지 않겠습니다&quot; 하며 마음을 담은 인사를 전하곤 했다. &lt;/span&gt;예쁜 말을 골라서 하니 심하게 야단을 칠 수도 없고, 하나라도 더 가르쳐 주고 싶은 마음이 들었다. 그런데 그렇게 느낀 사람이 나만은 아니었던 듯 하다. 임원진과의 식사 자리에서 우연히 그 후배 이야기가 나왔는데 최고참이 한마디 했다. &quot;그 친구는 어디 가든 잘 살아남을 거야. 누군들 그런 말 듣고 내칠 수 있겠어&quot;&lt;/p&gt;
&lt;p&gt;-예쁘게 말을 하니 좋은 사람들이 왔다- 심희정 지음&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;남에게 도움을 요청해야할 경우도, 나의 실수를 인정해야 하는 경우도 많아진다.&lt;/p&gt;
&lt;p&gt;그럴 때 신입의 마음과 태도 그 자세가 너무 중요하다는 것을 깨닫는다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;물론 처음에는 좌절되어 스스로 낮아지는 마음이 들 수 있다. 하지만, 거기서 끝내면 안된다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;신입은 누구나 그렇다.&amp;nbsp; (물론 아닌 사람도 있겠지만 ^^)&lt;/p&gt;
&lt;p&gt;배우려는 자세, 의지, 태도 그것이 너무나 중요하다.&amp;nbsp;&lt;/p&gt;</description>
      <category>개발일기</category>
      <category>신입 개발자</category>
      <category>신입의 자세</category>
      <author>더 멋진 세상을 꿈꾸는 개발자</author>
      <guid isPermaLink="true">https://dream-frontend.tistory.com/419</guid>
      <comments>https://dream-frontend.tistory.com/419#entry419comment</comments>
      <pubDate>Sat, 24 Apr 2021 11:25:35 +0900</pubDate>
    </item>
    <item>
      <title>[Kelly deli] Kelly가 전하는 목표 성취 방법</title>
      <link>https://dream-frontend.tistory.com/418</link>
      <description>&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. 구체적인 목표를 세워라&lt;/h3&gt;
&lt;p&gt;- 나는 5년 뒤 300억을 현금으로 가지고 있는다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. 구체적인 목표를 간단한 문장으로 만들어 시각화하고 매일 아침 저녁 명상한다.&lt;/h3&gt;
&lt;p&gt;- 구체적인 목표를 이룬 나의 모습을 상상한다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. 구체적 목표를 이루기 위한 방법들을 찾는다.&lt;/h3&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4. 목표를 이루기 위한 도움을 얻기 위해 멘토를 찾아간다.&lt;/h3&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;5. 항상 운동을 하여 뇌의 근육도 키운다.&lt;/h3&gt;
&lt;p&gt;- 일주일의 3번은 유산소운동을 하라.&lt;/p&gt;
&lt;p&gt;- 어떻게 하면 그 시간을 내려고 노력하는가. 그게 중요하다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;6. &quot;내가 할 수 있을까?, 될까 안될까?&quot; 와 같은 생각은 쓸데없는 시간낭비이다.&amp;nbsp;&lt;/h3&gt;
&lt;p&gt;- 목표를 이룬 나의 모습을 생각하며 계속 행동한다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;7. 부자들에게는 항상 '끈기'가 있다.&lt;/h3&gt;
&lt;p&gt;- 하루의 10분만 100일간 해보아라. (운동, 독서 등)&lt;/p&gt;
&lt;p&gt;- 10분에서 &quot;복리&quot;가 생겨 3시간도 할 수 있게 되는 것이다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;8. 롤모델의 &quot;습관&quot;을 내 것으로 만든다.&lt;/h3&gt;
&lt;p&gt;- 처음에는 롤모델의 습관을 100일간 모방하다보면 나의 것으로 만들 수 있다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Study/공부방법</category>
      <category>kelly</category>
      <category>kelly목표</category>
      <author>더 멋진 세상을 꿈꾸는 개발자</author>
      <guid isPermaLink="true">https://dream-frontend.tistory.com/418</guid>
      <comments>https://dream-frontend.tistory.com/418#entry418comment</comments>
      <pubDate>Sat, 27 Mar 2021 16:55:29 +0900</pubDate>
    </item>
    <item>
      <title>20.09.07:: TIL (react-native webview)</title>
      <link>https://dream-frontend.tistory.com/414</link>
      <description>&lt;p&gt;&lt;a href=&quot;https://github.com/react-native-community/react-native-webview/blob/master/docs/Getting-Started.md&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;github.com/react-native-community/react-native-webview/blob/master/docs/Getting-Started.md&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;오늘의 한 일&lt;/h2&gt;
&lt;hr style=&quot;border: none; font-size: 0px; line-height: 0; height: 20px; margin: 20px auto; background: url('https://t1.daumcdn.net/keditor/dist/0.4.0/image/divider-line.svg') 0px -140px / 200px 200px; cursor: pointer !important; color: #333333; font-family: 'Apple SD Gothic Neo', 'Malgun Gothic', '맑은 고딕', Dotum, 돋움, 'Noto Sans KR', 'Nanum Gothic', Lato, Helvetica, sans-serif; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;ul data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;react-native webview 활용&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;새롭게 배운 것&lt;/h2&gt;
&lt;hr style=&quot;border: none; font-size: 0px; line-height: 0; height: 20px; margin: 20px auto; background: url('https://t1.daumcdn.net/keditor/dist/0.4.0/image/divider-line.svg') 0px -140px / 200px 200px; cursor: pointer !important; color: #333333; font-family: 'Apple SD Gothic Neo', 'Malgun Gothic', '맑은 고딕', Dotum, 돋움, 'Noto Sans KR', 'Nanum Gothic', Lato, Helvetica, sans-serif; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;ul data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;WebView란?!&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;-&amp;gt; &lt;b&gt;&lt;u&gt;어플리케이션 화면상에 내가 띄우고 싶은 웹페이지를 어플리케이션 안에서 보여주는 프레임을 말한다. 즉, link로 연결하지 않고 바로 내 어플 안에서 페이지를 보여줄 수 있다.&lt;/u&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;react -natived에서 사용할 수 있는 React-native webview 라이브러리가 있다.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;react-native webview -reborn 라이브러리도 있는데, 이 버전 라이브러리를 깔아서 사용했더니 계속해서 모듈 에러가 났다. 구글링해도 이와 같은 에러가 별로 없었다. 라이브러리 레파지토리를 보니 업데이트된지 2-3년은 된 것 같았다. 라이브러리를 설치하기 전에는 항상 최신까지 관리가 되고 있는 라이브러리인지 확인하고 설치를 해야겠다. 결국 힘들게 힘들게 uninstall로 다운받았던 라이브러리를 삭제하고 react-native webview 라이브러리를 설치해서 사용했다. :) 설치했더니 아주 잘 되었음!!&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;736&quot; data-origin-height=&quot;1522&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kAO3t/btqIkviK3o1/lrNuTLoPEDT00zSWyIqlFK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kAO3t/btqIkviK3o1/lrNuTLoPEDT00zSWyIqlFK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kAO3t/btqIkviK3o1/lrNuTLoPEDT00zSWyIqlFK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkAO3t%2FbtqIkviK3o1%2FlrNuTLoPEDT00zSWyIqlFK%2Fimg.png&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;736&quot; data-origin-height=&quot;1522&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;기업협업&lt;/h2&gt;
&lt;hr style=&quot;border: none; font-size: 0px; line-height: 0; height: 20px; margin: 20px auto; background: url('https://t1.daumcdn.net/keditor/dist/0.4.0/image/divider-line.svg') 0px -140px / 200px 200px; cursor: pointer !important; color: #333333; font-family: 'Apple SD Gothic Neo', 'Malgun Gothic', '맑은 고딕', Dotum, 돋움, 'Noto Sans KR', 'Nanum Gothic', Lato, Helvetica, sans-serif; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p&gt;기업협업을 하면서 맨 땅에 헤딩하며 스스로 하는 방법들을 많이 배우고 있는 것 같다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;내가 현재 인턴쉽을 하고 있는 회사에는 '네이티브' 사수가 없다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;그래서 홀로 찾고 검색하고 에러핸들링 하는 시간을 많이 쏟았다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;예전에는 대표님께서 '이거 해봐~~' 주시면&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&quot;나 모르는데.. 할 수 있을까? 어떻게 하지?&quot; 하는 생각이 앞섰는데,&amp;nbsp;&lt;/p&gt;
&lt;p&gt;한달 정도 구글링하고, 에러핸들링 하면서 해보니,&amp;nbsp;&lt;/p&gt;
&lt;p&gt;검색하면 왠만한건 다 나오더라...&amp;nbsp; &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;물론, native 생태계가 좁아서 고생은 좀 해야하는 것 같다.... ㅎㅎ&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;내가 찾은 라이브러리를 활용해서 생각했던 기능을 눈으로 직접 보이게 구현하니 너무 재밌다:)&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Study/TIL</category>
      <category>react native web view</category>
      <category>Til</category>
      <category>Wecode</category>
      <category>위코드</category>
      <author>더 멋진 세상을 꿈꾸는 개발자</author>
      <guid isPermaLink="true">https://dream-frontend.tistory.com/414</guid>
      <comments>https://dream-frontend.tistory.com/414#entry414comment</comments>
      <pubDate>Mon, 7 Sep 2020 18:17:03 +0900</pubDate>
    </item>
    <item>
      <title>20.08.29:: TIL</title>
      <link>https://dream-frontend.tistory.com/411</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;오늘의 한 일&lt;/h2&gt;
&lt;hr style=&quot;border: none; font-size: 0px; line-height: 0; height: 20px; margin: 20px auto; background: url('https://t1.daumcdn.net/keditor/dist/0.4.0/image/divider-line.svg') 0px -140px / 200px 200px; cursor: pointer !important; color: #333333; font-family: 'Apple SD Gothic Neo', 'Malgun Gothic', '맑은 고딕', Dotum, 돋움, 'Noto Sans KR', 'Nanum Gothic', Lato, Helvetica, sans-serif; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;ul data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;React Native xcode 여는 방법 (이걸 몰라서... 5시간을 날림...)&lt;/li&gt;
&lt;li&gt;RN app testfligt 에 upload&lt;/li&gt;
&lt;li&gt;touchbleOpacity -&amp;gt; hitSlop이용&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;새롭게 배운 것&lt;/h2&gt;
&lt;hr style=&quot;border: none; font-size: 0px; line-height: 0; height: 20px; margin: 20px auto; background: url('https://t1.daumcdn.net/keditor/dist/0.4.0/image/divider-line.svg') 0px -140px / 200px 200px; cursor: pointer !important; color: #333333; font-family: 'Apple SD Gothic Neo', 'Malgun Gothic', '맑은 고딕', Dotum, 돋움, 'Noto Sans KR', 'Nanum Gothic', Lato, Helvetica, sans-serif; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;ul data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;HitSlop - 어플을 만들다 보면 터치하는 영역이 좀 더 확장되어야 터치가 이루어진다는 걸 알게 될 것이다. 딱 아이콘 에만 onPress 함수를 걸었더니 진짜 아이콘만 터치해야 함수가 작동했다. 아이콘을 넘어가는 다른 부분에는 다른 click 실행이 이루어졌다. 그래서 touchble opacity 태그를 활용해서 hitslop을 걸어주니 그 만큼 touchable 영역이 확장되었다.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;React native cli 버전은 xcode 열 때&amp;nbsp; &quot;.xcworkspace&quot;로 xcode를 열어야 한다. 그래야 xcode가 어떤걸 여는지 안다. 그냥 작성한 폴더 자체를 xcode로 열려고 하면 'could not open file'이 뜬다. (내가 이 오류로 4-5시간을 날림...ㅋㅋㅋ)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;기업협업&lt;/h2&gt;
&lt;hr style=&quot;border: none; font-size: 0px; line-height: 0; height: 20px; margin: 20px auto; background: url('https://t1.daumcdn.net/keditor/dist/0.4.0/image/divider-line.svg') 0px -140px / 200px 200px; cursor: pointer !important; color: #333333; font-family: 'Apple SD Gothic Neo', 'Malgun Gothic', '맑은 고딕', Dotum, 돋움, 'Noto Sans KR', 'Nanum Gothic', Lato, Helvetica, sans-serif; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Study/TIL</category>
      <author>더 멋진 세상을 꿈꾸는 개발자</author>
      <guid isPermaLink="true">https://dream-frontend.tistory.com/411</guid>
      <comments>https://dream-frontend.tistory.com/411#entry411comment</comments>
      <pubDate>Sat, 29 Aug 2020 16:56:53 +0900</pubDate>
    </item>
  </channel>
</rss>