<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>91DAEHUN's WEBLOG</title>
        <link>https://velog.io/</link>
        <description>웹퍼블리셔</description>
        <lastBuildDate>Wed, 19 Feb 2025 01:59:54 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <copyright>Copyright (C) 2019. 91DAEHUN's WEBLOG. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/dkim-91" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[css 단위 em, rem]]></title>
            <link>https://velog.io/@dkim-91/css-%EB%8B%A8%EC%9C%84-rem-em</link>
            <guid>https://velog.io/@dkim-91/css-%EB%8B%A8%EC%9C%84-rem-em</guid>
            <pubDate>Wed, 19 Feb 2025 01:59:54 GMT</pubDate>
            <description><![CDATA[<h1 style="font-size:32px">em, rem 이란?</h1>

<blockquote>
<p>css의 상대단위로서 어떠한 기준에따라 값이 상대적으로 변하는 폰트 단위이다.
그 기준이 em은 부모값에 따라 적용되며, rem은 root 즉 html의 값에 따라 적용된다.</p>
</blockquote>
<h2 style="font-size:24px">em</h2>

<pre><code class="language-css">.parent{
    font-size:20px;
}
.child{
    font-size:0.5em; // 10px로 적용된다.
}</code></pre>
<h2 style="font-size:24px">rem</h2>

<pre><code class="language-css">.parent{
    font-size:20px;
}
.child{
    font-size:0.5rem; 
    // *html의 기본값은 16px이다. 따라서 16px의 0.5인 8px이 적용된다
}</code></pre>
<p>😄 rem, em을 알아보았는데 컴포넌트 단위로 쪼개서 사용할 경우 부모요소가 바뀌는 케이스가 무수히 많다. 그래서 em을 사용할 경우 폰트사이즈가 부모요소에 따라 바뀔수 있고, em은 폰트사이즈를  직관적으로 알기 어렵다. rem은 root html에따라 폰트사이즈를 직관적으로 알 수 있고, 컴포넌트 단위로 쪼개더라도 폰트사이즈에 별다른 이슈는 발생하지 않는다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[아이폰 Safari에서 css vh 오류]]></title>
            <link>https://velog.io/@dkim-91/%EC%95%84%EC%9D%B4%ED%8F%B0-Safari%EC%97%90%EC%84%9C-vh-%EC%98%A4%EB%A5%98</link>
            <guid>https://velog.io/@dkim-91/%EC%95%84%EC%9D%B4%ED%8F%B0-Safari%EC%97%90%EC%84%9C-vh-%EC%98%A4%EB%A5%98</guid>
            <pubDate>Tue, 18 Feb 2025 05:24:07 GMT</pubDate>
            <description><![CDATA[<h1 style="font-size:32px">1. vh값이 적용되지않음</h1>

<blockquote>
<p>아이폰 Safari에서는 노치화면과 url바 등으로 힌해 vh값이 제대로 적용되지않는다. 해당 부분까지 포함하여 계산하는것으로 예상됨</p>
</blockquote>
<p>🚨 <em>vh는 vh = viewport height 라는 의미로 화면에 보여지는 viewport에 맞춰 그에따른 비율로 설정된다. 화면의 높이가 1000px이라 가정해보면 1vh는 10px이 된다.</em></p>
<h1 style="font-size:32px">2-1. js로 적용해보기</h1>

<blockquote>
<p>js를 활용하여 window innerHeight값을 활용해 해당 값을 기준으로 하여 vh값을 재설정하여 변수로 저장한다.</p>
</blockquote>
<pre><code class="language-javascript">/*
--vh라는 값으로 html태그에 --vh값을 설정해준다 
(윈도우 innerHeight값을 기준으로 1vh를 px값으로 --vh에 저장) 
*/
function setVhProperty(){
  let vh = window.innerHeight * 0.01;
  document.documentElement.style.setProperty(&#39;--vh&#39;, vh + &#39;px&#39;);   
}

//실행부
setVhProperty();

//윈도우 resize시마다 실행(viewport가 바뀌기때문에)
window.addEventListener(&#39;resize&#39;, function () {
  setVhProperty();
});</code></pre>
<p>😀 이제 css에서 --vh값을 활용하여 vh값을 설정해준다.</p>
<pre><code class="language-css">.100vh{
    height: calc(var(--vh, 1vh) * 100);
}</code></pre>
<h1 style="font-size:32px">2-2. css로 적용해보기</h1>

<blockquote>
<p>-webkit-fill-available 속성 사용하기
뷰포트의 사용 가능한 만큼 높이값을 설정해준다.</p>
</blockquote>
<pre><code class="language-css">.100vh{
    height: -webkit-fill-available;
}</code></pre>
<p>🚨 <em>해당 속성은 꽉채울 경우에만 사용할 수 있을것 같고, webkit 기반만 적용이 가능하기에 ios일경우에만 사용하도록 분기해주는게 좋을 것 같다.</em></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Github 사용해보기]]></title>
            <link>https://velog.io/@dkim-91/Github-%EC%82%AC%EC%9A%A9%ED%95%B4%EB%B3%B4%EA%B8%B0</link>
            <guid>https://velog.io/@dkim-91/Github-%EC%82%AC%EC%9A%A9%ED%95%B4%EB%B3%B4%EA%B8%B0</guid>
            <pubDate>Tue, 18 Feb 2025 04:34:18 GMT</pubDate>
            <description><![CDATA[<h1 style="font-size:32px">1. github 시작하기</h1>

<blockquote>
<p>분산 버전 관리 시스템인 git저장소 호스팅을 지원하는 웹 서비스. 
원격 저장소 역할 및 다른사람들과 협업을 가능해게 해준다. </p>
</blockquote>
<pre><code>git init //git 저장소 만들기 
git branch -M main 
// git은 기본 브랜치 이름이 main이어야함. 
경우에따라 기본 브랜치가 master로 설정되어있을 수 있기때문에 main으로 변경해준다.</code></pre><h1 style="font-size:32px">2. github 원격저장소에 올리기</h1>

<blockquote>
<p>로컬 → 원격으로 업로드 해보기</p>
</blockquote>
<pre><code>git push -u https://github.com/user/prj~~ main
// main브랜치를 해당 원격저장소 주소에 올리라는 의미</code></pre><p>-u 옵션은 해당 원격저장소 주소를 기억해두라는 의미로 한번 실행후에 git push만 입력해도 push됨. </p>
<h1 style="font-size:32px">3. github 각종 명령어</h1>

<pre><code>git remote add origin https://github.com/user/prj~~  
// 해당주소를 origin 변수명으로 저장해 사용할수 있음 
// git push -u origin main 2번에 나온 push명령을 간소화할수있음 

git remote -v //변수목록 살펴보기

git clone https://github.com/user/prj~~ //해당주소의 소스 내려받기</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[Git 사용해보기]]></title>
            <link>https://velog.io/@dkim-91/Git-%EC%82%AC%EC%9A%A9%ED%95%B4%EB%B3%B4%EA%B8%B0</link>
            <guid>https://velog.io/@dkim-91/Git-%EC%82%AC%EC%9A%A9%ED%95%B4%EB%B3%B4%EA%B8%B0</guid>
            <pubDate>Thu, 16 Jan 2025 01:58:56 GMT</pubDate>
            <description><![CDATA[<h1 style="font-size:32px">1. git 시작하기</h1>

<blockquote>
<p>git을 누가 사용하고있는지 구분하기위해 PC의 Terminal에 진입해서 유저이름 세팅을 해줍니다.</p>
</blockquote>
<pre><code>git config --global user.email &quot;이메일&quot;
git config --global user.name &quot;사용자&quot;</code></pre><p>이후 프로젝트 root경로에 진입, git init 명령어를 통해 git을 시작합니다.</p>
<h1 style="font-size:32px">2. add / commit</h1>

<blockquote>
<p>이제 git을 시작했으니, 저장소(repository)에 파일을 저장하는 명령어를 실행해봅니다.</p>
</blockquote>
<pre><code>git status //git의 현재 상태를 확인합니다.
git add 파일명 //해당 파일을 stage area에 등록합니다.
git add . //전체 파일을 stage area에 등록합니다.
git commit -m &quot;메세지&quot; //stage area에 등록된 파일들을 repository에 저장합니다.</code></pre><blockquote>
<p>git은 add를 통해 stage area에 커밋대상들을 임시로 등록해둡니다. 이후 확실하게 repository에 저장할 파일들을 commit 명령어를 통해 저장합니다.</p>
</blockquote>
<h1 style="font-size:32px">3. branch 활용하기</h1>

<blockquote>
<p>이제 repository에 저장하는 방법을 익혔는데 우리가 프로젝트 진행중에 또다른 사이드프로젝트를 진행하게 된다면.. 현재코드와 사이드프로젝트간 충돌이 발생할수도 있고 복잡해집니다. 이럴때 사용할 수 있는 프로젝트의 복사본을 만들어주는 branch에대해 활용해봅시다.</p>
</blockquote>
<pre><code>git branch 브랜치이름 //브랜치 생성(보통 기본 branch명은 main 또는 master
git switch 브랜치이름 //해당 브랜치로 이동</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[Swiper 활용 - 반응형, display:none 이슈]]></title>
            <link>https://velog.io/@dkim-91/Swiper-%ED%99%9C%EC%9A%A9-%EB%B0%98%EC%9D%91%ED%98%95-displaynone-%EC%9D%B4%EC%8A%88</link>
            <guid>https://velog.io/@dkim-91/Swiper-%ED%99%9C%EC%9A%A9-%EB%B0%98%EC%9D%91%ED%98%95-displaynone-%EC%9D%B4%EC%8A%88</guid>
            <pubDate>Fri, 11 Mar 2022 09:32:00 GMT</pubDate>
            <description><![CDATA[<h1 id="intro">Intro</h1>
<p>swiper를 적용하여 반응형 코딩을 하던 중 반응형 기준에 맞춰 swiperPerView를 3,6,9씩 보여주는 UI를 만들던 중 브라우저창 전체화면 시 swiper가 일부 깨지는 현상이 발견되었다.</p>
<h2 id="첫번째-시도">첫번째 시도</h2>
<p>윈도우 리사이즈시 swiper.update() 메서드를 실행하면 해결할 수 있을 것 같았다. 리사이즈 마지막 발생시점(?)에  swiper.update() 메서드를 실행해보았으나 결과는 실패였다. 원인불명인데 update() 메서드의 버그로 유추해본다.</p>
<pre><code class="language-javascript">var swiper;
$(function){
    swiper = new Swiper(&quot;.swiper-container&quot;,{
        slidesPerView:9,
          loop:true,
          breakpoints:{
            720:{
              slidesPerView:3
            },
            900:{
              slidesPerView:3
            },
            1180:{
              slidesPerView:3
            },
        }
    });

      var resizeCheck; // 리사이즈 END체크
      $(window).resize(function(){
        if(resizeCheck){ //계속 리사이즈중이면 clear
            clearTimeout(resizeCheck); 
        };

          //0.5초이상 리사이즈 지속하지않으면 실행
          resizeCheck = setTimeout(function(){
            console.log(&quot;resizeEnd&quot;);
              swiper.update(); //스와이퍼 업데이트
        },500);
    });
}</code></pre>
<h2 id="두번째-시도">두번째 시도</h2>
<p>일전에 탭메뉴로 탭1 일반컨텐츠, 탭2 스와이퍼 컨텐츠를 구현한 경험이 있었다. 그 당시 탭2가 display:&quot;none&quot; 되어있어서 탭1로 진입후 탭2 클릭시 스와이퍼가 제대로 동작하지않은 경험이 있다. 그당시 사용했던 방법은
스와이퍼에 observer, observeParents 매개변수로 각각 true값을 넣어서 해결했던 방법이다. swiper API에 따르면 아래와 같은내용이다.</p>
<blockquote>
<p><strong>observer : true</strong>
Swiper는 스타일을 변경(예: 숨기기/표시)하거나 하위 요소를 수정(예: 슬라이드 추가/제거)할 때마다 업데이트(재초기화)됩니다.</p>
</blockquote>
<blockquote>
<p><strong>observeParents : true</strong>
Swiper 부모요소의 변화에따라 업데이트(재초기화)됩니다.</p>
</blockquote>
<p>위의 매개변수를 추가함으로써 브라우저창 전체화면 시 swiper가 일부 깨지는 현상도 해결되었다.</p>
<p>참고자료: <a href="https://swiperjs.com/swiper-api">https://swiperjs.com/swiper-api</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Gulp 시작하기]]></title>
            <link>https://velog.io/@dkim-91/Gulp-%EC%82%AC%EC%9A%A9%EB%B2%95-%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@dkim-91/Gulp-%EC%82%AC%EC%9A%A9%EB%B2%95-%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Mon, 03 Jan 2022 08:22:53 GMT</pubDate>
            <description><![CDATA[<h1 id="intro">Intro</h1>
<p>나는 gulp를 회사에서 처음 접하게 되었는데 주로 퍼블본 scss를 css로 변환 및 통합, babel을 통한 js의 변환 등에 사용하였는데, gulp 설치부터 플러그인 활용법에 대해 다시한번 정리해보고자 한다.</p>
<h2 id="gulp란">Gulp란?</h2>
<p>nodejs와 npm 기반의 task-runner이다. 웹 개발 시 필요한 최적화, 유닛 테스트 등 반복되는 task들을 자동화 하기위해 사용된다. 다양한 플러그인들을 활용해 scss를 css로 변환하거나 IE에서 호환이되지않는 es6를 es5로 변환시켜주는 등 최적화에도 효율적으로 사용되곤 한다.</p>
<h2 id="gulp-시작하기">Gulp 시작하기</h2>
<h3 id="gulp-설치">Gulp 설치</h3>
<blockquote>
<p>npm install --save-dev gulp
gulp -version</p>
</blockquote>
<p>gulp 설치 후 gulp version을 체크하여 설치가 완료되었는지 확인한다.</p>
<p>CLI version: 2.3.0
Local version: 4.0.2</p>
<p>위와같이 출력되면 설치완료</p>
<h3 id="gulpfilejs-생성">gulpfile.js 생성</h3>
<p>gulpfile.js는 gulp task를 정의하는 파일이다.
프로젝트 root경로에 &quot;gulpfile.js&quot; 파일을 생성한다.</p>
<h3 id="task-선언-및-수행">task 선언 및 수행</h3>
<p>gulpfile.js를 생성후 gulp가 수행할 task를 해당 파일에 Javascript로 선언해준다.</p>
<h4 id="task-선언">task 선언</h4>
<pre><code class="language-javascript">function defaultTask(cb) {
    cb();
}

exports.default = defaultTask</code></pre>
<h4 id="task-수행">task 수행</h4>
<p>exports.default로 하였기에 명령어는 아래와같다.</p>
<blockquote>
<p><strong>gulp default</strong>  <em>또는</em>  <strong>gulp</strong> </p>
</blockquote>
<p>gulp task 수행시 대략 이렇게 이해하면 편할것 같다.
exports.실행명령어 = 함수;</p>
<blockquote>
<p>ex) 
&quot;test&quot;로 export할 경우
exports.test = defaultTask
수행 명령어: <strong>gulp test</strong></p>
</blockquote>
<h3 id="api-파헤쳐보기">API 파헤쳐보기</h3>
<h4 id="src">•src</h4>
<p>gulp가 파일을 읽기위해 사용되는 메소드이다. stream을 리턴한다.</p>
<p>아래와같이 src란 변수로 선언해서 사용할수 있다.</p>
<pre><code class="language-javascript">const { src } = require( &#39;gulp&#39; ) ;   
</code></pre>
<blockquote>
<p>src(globs, [options])</p>
</blockquote>
<p>globs는 문자열 또는 배열 type이고, 읽어들일 파일(들)을 해당 타입에 맞게 입력하면 된다.
options는 다양하게 있지만 필요에따라 찾아보면 될 것 같다. 활용예제는 dest에서 같이 다루겠다.</p>
<h4 id="watch">•watch</h4>
<p>gulp가 파일을 감시하기 위해 사용되는 메소드이다. 변경이 발생하면 glob을 보고 작업을 실행한다. 예를들면, scss를 바라보고 변경이 감지되면 css로 변환하는 watch task를 만들어 사용할 수 있다.</p>
<pre><code class="language-javascript">const { watch } = require(&#39;gulp&#39;);

watch([&#39;input/*.js&#39;, &#39;!input/something.js&#39;], function(cb) {
  // body omitted
  cb();
});
</code></pre>
<p>위 코드를 보면 gulp의 watch대상은 input폴더 하위의 js중 something.js를 제외한 모든 js파일이 된다. (* string의 !가 있으면 해당 파일 제외됨)
이와 같이 응용할 수 있겠다.</p>
<h4 id="dest">•dest</h4>
<p>쉽게 표현하면 파일을 작성(?)하는 역할을 한다.
예를 들면, scss 파일들을 src로 읽어서 css로 변환(scss→css 변환은 다음장에서 다루겠다.) 한후, 변환된 css들을 통합하여 하나의 파일로 만든뒤, 내가 원하는 위치(directory)에 파일을 위치시킬때 사용될수 있다. 주로 프로젝트에서 통합된 css를 include하기 때문에 gulp활용 시dest는 빠질수 없는 요소이다.  </p>
<blockquote>
<p>dest(directory, [options])</p>
</blockquote>
<p>directory에 파일을 작성하고자 하는 경로를 입력하면 된다. </p>
<pre><code class="language-javascript">const { src, dest } = require(&#39;gulp&#39;);

function copy() {
  return src(&#39;input/*.js&#39;)
    .pipe(dest(&#39;output/&#39;));
}

exports.copy = copy;</code></pre>
<p>위 코드를 보면 input폴더 하위의 모든 js파일을 읽어들여 output폴더 하위에 작성하게 된다.</p>
<p>series, parallel 등도 많이 쓰게되었지만 퍼블리싱에서 가장 많이쓰이고 필수적인 src,watch,dest만 정리를 해보았다. 다른 써보지못한 API에 대해서도 여유가있으면 더 공부해볼만 할것같다. 많이 알수록 간편해지고, &quot;이런게 있었네?&quot;와 같은 소득을 얻게 될수도 있게될테니 말이다. </p>
<p>참고: <a href="https://gulpjs.com/docs/en/api/concepts">https://gulpjs.com/docs/en/api/concepts</a></p>
<h3 id="다음-장에서">다음 장에서</h3>
<p>gulp의 설치부터 task작성, 여러가지 API활용을 정리해보았는데 다음장에서는 scss를 css로 컴파일, es6 JS를 es5로 컴파일 등을 해보며 gulp에서 많이쓰이는 플러그인들을 알아볼 예정이다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[scroll시 브라우저 렌더링 오류 개선]]></title>
            <link>https://velog.io/@dkim-91/scroll%EC%8B%9C-%EB%B8%8C%EB%9D%BC%EC%9A%B0%EC%A0%80-%EB%A0%8C%EB%8D%94%EB%A7%81-%EC%98%A4%EB%A5%98-%EA%B0%9C%EC%84%A0</link>
            <guid>https://velog.io/@dkim-91/scroll%EC%8B%9C-%EB%B8%8C%EB%9D%BC%EC%9A%B0%EC%A0%80-%EB%A0%8C%EB%8D%94%EB%A7%81-%EC%98%A4%EB%A5%98-%EA%B0%9C%EC%84%A0</guid>
            <pubDate>Sun, 26 Dec 2021 13:55:10 GMT</pubDate>
            <description><![CDATA[<h1 id="오류-분석">오류 분석</h1>
<p>안드로이드 일부 기기에서 스크롤을 빠르게했을시 브라우저의 렌더링 오류인지 레이아웃이 깨지는 현상이 발생되었다..
<img src="https://images.velog.io/images/dkim-91/post/31fca843-a611-42e4-af14-c4760e3c923b/%EC%98%A4%EB%A5%98%EB%B6%84%EC%84%9D.gif" alt=""></p>
<p>Before에 컨텐츠 내용이 잘 나왔다면, 사용자가 스크롤을 아주 빠르게 이동했을시 After 화면 처럼 컨텐츠의 일부 텍스트, 이미지 등이 렌더링 되지 않았다. </p>
<h1 id="원인-파악">원인 파악</h1>
<p>해당 페이지는 컨텐츠 클릭시 해당 컨텐츠의 scrollTop으로 이동하는 스크롤 이벤트가 걸려있었고, 또한 이동시 jquery animate를 사용중이다. </p>
<p>우선은 가장 의심되는 원인으로는 <strong>&quot;브라우저 렌더링(?), 페인팅(?)이 느리다&quot;</strong> 였다.
스크롤시에 브라우저가 화면을 다시그리는데 스크롤 속도에 대비해 브라우저 페인팅이 느려서 해당 현상이 나타난 것으로 보였다.</p>
<h1 id="해결-방법">해결 방법</h1>
<blockquote>
<p>transform:translate3d(0, 0, 0)</p>
</blockquote>
<p>결론적으로 css의 핵(hack)이라고 불려지는 
transform:translate3d(0,0,0)을 사용하여 해결할 수 있었다. 0,0,0값을 준것은 변형이 필요없기 때문이다.</p>
<p>조금 더 자세히 구글링 해보니 translate3d는 GPU 가속을 사용하는 요소로서 기본적으로 브라우저 렌더링시에는 CPU를 사용하는데 <strong>GPU가 이에 개입하여 렌더링을 빠르게 할수있게 돕는다</strong>고 한다. 그래서 해당영역의 가장 부모인 overflow가 적용되어있는 컨텐츠에 적용하였다.</p>
<blockquote>
<p> will-change: transform;</p>
</blockquote>
<p>추가적으로 stack overflow를 헤매다가 발견한 will-change속성인데 예상되는 변화의 종류에 관한 힌트를 브라우저에 제공하여 브라우저 렌더링에 대비할수 있게 해주는 속성이다. 미리 대비할수 잇기에 기존에 핵으로 사용했던 translate3d보다 최적화면에서는 더 나을수 있다고 한다. 
하지만 일부 Safari, IE등 지원이 되지않아, 이번엔 사용할 수 없었다.</p>
<h1 id="마치며">마치며</h1>
<p>이전부터 핵으로 들어봤었던 transform: translate3d(0,0,0)과 같은 코드는 &quot;이렇게 하니까 잘되네&quot; 라며 쉽게 넘어가곤 했던 코드중 하나였던 것 같다.
이번에 수정을하며 오류원인, 해결된이유 등에 대해 조금더 디테일하게 찾아봐야 더 발전할 수 있을거 같다고 느꼈다.</p>
<p>참고) <a href="https://developers.google.com/web/fundamentals/performance/rendering/simplify-paint-complexity-and-reduce-paint-areas?hl=ko">https://developers.google.com/web/fundamentals/performance/rendering/simplify-paint-complexity-and-reduce-paint-areas?hl=ko</a></p>
<p><a href="https://developer.mozilla.org/ko/docs/Web/CSS/will-change">https://developer.mozilla.org/ko/docs/Web/CSS/will-change</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[웹 렌더링 속도 개선]]></title>
            <link>https://velog.io/@dkim-91/%EC%9B%B9-%EB%A0%8C%EB%8D%94%EB%A7%81-%EC%86%8D%EB%8F%84-%EA%B0%9C%EC%84%A0</link>
            <guid>https://velog.io/@dkim-91/%EC%9B%B9-%EB%A0%8C%EB%8D%94%EB%A7%81-%EC%86%8D%EB%8F%84-%EA%B0%9C%EC%84%A0</guid>
            <pubDate>Tue, 30 Nov 2021 13:04:55 GMT</pubDate>
            <description><![CDATA[<h1 id="웹-브라우저의-동작">웹 브라우저의 동작</h1>
<p>브라우저 ⇒ 도메인서버와 통신하여 호스트의 IP를 찾음.
이후 브라우저는 해당 호스트IP서버와의 TCP 연결을 생성, 이제 브라우저는 IP서버와의 리소스 요청및 다운로드를 진행한다.
리소스에는 HTML,CSS,IMAGE,JS,Font 등.. 리소스를 다운로드하면서 페이지를 그리는 과정을 렌더링 이라고한다.
<br></p>
<h1 id="렌더링-과정">렌더링 과정</h1>
 <ol>
  <li>HTML구문 분석을 진행하면서 DOM트리 생성</li>
  <li>HTML구문 분석 중 CSS링크가 발견되면 CSS구문 분석을 진행하여 CSSOM 트리생성 (HTML과 별도의 스레드로 동작함)</li>
  <li>DOM+CSSOM ⇒ 렌더 트리 생성</li>
  <li>렌더트리를 통해 노드들의 위치 정보가 계산됨. 브라우저의 왼쪽위부터 오른쪽 아래 순으로 진행</li>
  <li>브라우저창에 표현하는 페인트 단계</li>
</ol>

<p>JS의 경우 DOM,CSSOM을 동적으로 변경 가능해서 렌더링 도중 JS에 의해 변경이 발생하면 3~5번 과정을 재수행한다. 따라서, 렌더링 과정에서 최대한 JS의 개입 없이 최적화가 필요하다. 그러나 대다수의 JS는 렌더링에 관여하여 이를 잘 구분하여 분리해야 한다..
<br></p>
<hr>

<h1 id="dom-최적화">DOM 최적화</h1>
<h2 id="html의-구문분석은-관대하다">HTML의 구문분석은 관대하다.</h2>
<p>HTML 구문분석 과정에 작은 오류가 발생하면 브라우저가 알아서 처리하는 경우가 있다. ( ex:일부 태그를 닫지 않는 케이스 )  그러나 이런 케이스가 많아질 경우 브라우저가 처리하면서 많은 메모리와 CPU를 소모할 수 있고 이는 렌더링 시간에 어느 정도 관여할 수 있다는 점이다.  오류 최소화가 필요한 부분이다.</p>
<h2 id="과도한-html-태그-중첩-사용은-피하자">과도한 HTML 태그 중첩 사용은 피하자.</h2>
<p>위의 렌더링 과정에서 JS가 동적 변경을 발생시키면 3<del>5번 과정을 되풀이한다고 언급한 내용이 있다. 3</del>5번 과정을 되풀이 할때 HTML태그가 많다면 이것 또한 렌더링 지연의 원인이 될 것이다.</p>
<p>Atomic 디자인패턴으로 퍼블리싱 한 경험이 있는데 atom단위, module단위로 분리하는 과정에서 지나치게 태그를 많이 감싸서 활용하다보니 결과물을 보았을 때 생각보다 많고 불필요한 태그 중첩을 사용한 경험이 있다. 나중에 개발 데이터가 입혀진 후에는 수정이 많이 어려울 것으로 생각된다.</p>
<h1 id="css-최적화">CSS 최적화</h1>
<h3 id="css를-분리하자">CSS를 분리하자</h3>
<p>CSS를 통으로 말아서 사용하면 브라우저의 첫 화면과 관련없는 (뒤에 숨어있는 페이지 등) 리소스가 있을 수 있어, 렌더링 속도 지연에 영향을 준다. 해당 페이지에 필요한 CSS를 분리하면 좋다는 말이다. 그러나 이게 맘처럼 쉽지는 않을 것 같다. 어떻게 분리해야 좋을지는 좀 더 고민이 필요해보인다.</p>
<p>또 다른 방법으로는 당장 필요하지 않는 CSS를 지연 로드 시키는것이다. 예를 들면 <code>&lt;link data-href=&quot;css파일&quot;/&gt;</code> 로 태그 작성 후 js onload이벤트를 통해 페이지가 로드되면 &quot;data-href &quot; 값 이용해 파일을 연결한다. 이 또한 CSS 파일 분리를 잘 해 두어야 할 수 있는 방법이다. </p>
<p><em>어떻게 CSS를 효율적으로 분리할 수 있을지가 중요한 것 같다.</em></p>
<h1 id="js-최적화">JS 최적화</h1>
<h3 id="async-defer-속성을-이용">async, defer 속성을 이용</h3>
<p>위에 언급한 듯이 JS는 렌더링 지연에 영향을 주는 부분이 있다. 따라서 HTML 구문 분석 과정에 꼭 필요한 JS와 그렇지 않은 JS를 구분할 필요가 있다.</p>
<p>async, defer 속성이 이를 도와줄 수 있다. async 속성은 HTML 구문 분석과 동시에 실행하고, defer 는 JS를 미리 다운 받아 놓은 뒤 HTML 구문 분석이 완료된 후 실행한다.</p>
<p>그 외에 onload event를 활용하는 방법이 있다.</p>
<p><em>CSS와 마찬가지로 JS 분리가 관건이다.</em></p>
]]></description>
        </item>
    </channel>
</rss>