본문 바로가기
웹 프로그래밍 기초

[HTML] Mark Up literal

by oncerun 2021. 6. 6.
반응형

 

웹 애플리케이션을 만들다 보면 화면의 구조를 동적으로 생성하는 일이 상당히 많은 걸 알 수 있다.

그래서 나는 DOM API를 이용한 다음과 같은 코드로 동적 생성을 했다.

 

예를 들어 ul태그 내부의 li들을 동적으로 생성해야 한다면

const root = document.querySelector('#root');

const ul = doucument.createElement('ul');

for(int i = 0; i < 10; i++){
	const div = createElement('div');
    
    div.innerHTML = `<li>${i}</li>`;
	
	ul.appendChild(div.firstElementChild);
}
root.appendChild(ul);

 

내가 원하는 마크업은 다음과 같았다.

<div id="root">
	<ul>
    <li>0</li>
    <li>1</li>
    <li>2</li>
    <li>3</li>
    <li>4</li>
    <li>5</li>
    <li>6</li>
    <li>7</li>
    ...
   	</ul>
</div>

 

 

이 방식의 문제점은 다음과 같다.

 

  1. 웹 앱은 이렇게 단순한 HTML 구조가 아니다. 지금 상태로 개발자 도구 창을 켜서 티스토리만 보더라도 엄청 복잡한데, 이걸 개발자가 코드를 보고 구조를 한눈에 파악한다는 건 사실상 불가능에 가깝다. 또한 개발자는 이직이 잦은 직업 중 하나로 정확한 인수인계가 아닌 경우 코드를 파악하기 위해 시간이 상당히 들어갈 수 있다.
  2. 불필요한 DOM API를 호출하게 된다. 반복 문안에 div태그를 만드는 API경우는 문자열 HTML을 실제 태그로 만들기 위한 임시 변수이다. 
  3. 만약 li태그도 createElement를 통해 생성하고 appendChild 하는 구조라면 더욱 복잡해진다.

 

이러한 방법은 수많은 불편함을 가지고 예기치 못하는 버그를 만들 수 있기에 프런트엔드 개발자들은 많은 고민을 했을 것이고 그중 자주 사용되는 방법 하나를 소개한다.

 

 동일한 구조를 만든다고 했을 때 다음과 같이 코드를 리팩터링 할 수 있다.

 

const root = document.querySelector('#root');
const rank = [];
rank.push('<ul>');
for(int i = 0; i < 10; i++){
    rank.push(`<li>${i}</li>`);
}
rank.push('</ul>');

root.innerHTML = rank.join('');

 

배열을 활용해 마크업 구조를 상단에서부터 문자열로 추가를 하고 join을 통한 html 문자열을 추가하고자 하는 부모 태그에 삽입하는 방식이다. 

 

이 방식은 이전 방식보다 코드상에서 UI를 파악하는데 더 쉽다는 장점이 있지만 HTML만으로 웹을 만들지는 않는다.

 

사실상 디자인을 추가하는 경우에는 문제가 될 수 있다. 디자인을 추가한다는 것은 코드의 양이 늘어난다는 것이고, 현재는 코드상에서 마크업을 다루고 있기 때문에 코드의 복잡도가 늘어날 수 있다.

 

코드의 양이 늘어나면서 코드의 복잡도도 같이 늘어나게 된다면 좋은 코드라고 볼 수 없다.

 

배열을 활용해 마크업을 만드는 순서는 다음과 같다.

  1. 문자열이 만들어지는 생성시점이 전부 다르다.
  2. 그렇기 때문에 생성되는 시점마다 문자열을 따로 저장해 놓는 배열을 만든다.
  3. 해당되는 시점에 배열에 문자열을 넣는다.
  4. 최종적으로 만들어진 문자열을 마크업 구조로 만들어 요소에 삽입한다.

DOM API를 활용하는 구조보다는 파악하기 쉽지만, 실제는 마크업 자체가 분산되어 있을 수 있기 때문에 양이 많아진다면, 구조를 파악하기 힘들 것이다.

 

그럼 어떻게 해야 할까? 다음은 템플릿을 활용한 방식이다.

 

템플릿은 기초구조를 가지고 해당하는 부분만을 데이터로 변환하는 방식인데, 상당히 여러 분야에서 사용되는 방법이다.

그럼 위의 배열을 활용한 구조를 템플릿으로 변경해보겠다.

 

const root = document.querySelector('#root');
const template = `
		<ul>
        	{template_li}
        </ul>
`;
const rank = [];
for(int i = 0; i < 10; i++){
    rank.push(`<li>${i}</li>`);
}

template = template.replace('{template_li}',rank.join(''));
root.innerHTML = template;

보이는 UI자체는 변하는 게 없지만 UI와 코드는 성격이 다르기 때문에 분리를 하게 되면 좀 더 복잡도가 줄어들어 코드의 내용을 확인하기가 좀더 수월할 수 있습니다.

 

템플릿 내부의 임의의 문자열( {template_li} )이라는 곳에 데이터가 들어갈 것이라는 것을 암시해주고 전체 마크업 구조는 한눈에 파악할 수 있는 방법입니다.

 

 

또한 외부 라이브러리를 사용할 수 있습니다.

https://handlebarsjs.com/

 

Handlebars

 

handlebarsjs.com

 

핸들 바스는  컴파일된 템플릿에 모델을 반영하여 뷰를 구성하는 방식입니다.

 데이터 모델을 한번 뷰에 반영해주고 끝이기 때문에 초기 랜더링 속도면에서 더 유리하지만, 양방향 구조가 아니기 때문에 이미 랜더링 된 뷰의 내용을 바꾸고 해당 내용을 다시 모델에 반영하려면 별도의 작업이 필요합니다.

 

Handlebars가 유리한 경우는 사용자에게 실제 보이는 프로모션 페이지를 예로 들 수 있습니다. 서버에서 데이터를 불러와서 빠르게 화면에 뿌려주기만 할 경우에 유리합니다.

 

반응형

'웹 프로그래밍 기초' 카테고리의 다른 글

주요 웹 서버  (0) 2021.07.06
[CSS3] overflow  (0) 2021.07.05
HTML/CSS 웹 프로그래밍 복습(2)  (0) 2021.05.19
HTML/CSS 웹 프로그래밍 복습(1)  (0) 2021.05.19
Staging website  (0) 2021.04.14

댓글