본문 바로가기

개발공부/기술면접준비

[HTML] <link>요소가 <head>요소 내에 위치하는 이유와 <script>요소가 <body>가 끝나기 직전의 위치에 존재하는 이유

일반적으로 css를 불러오기 위해서 <link>요소를 <head>요소의 자식 요소로 하고,
JavaScript를 불러오기 위해 <script>요소를 <body>요소가 끝나기 직전에 위치시키는 이유에 대해서 알아보자.

1. HTML문서의 <link>요소는 왜 <head>요소 내에 배치될까?

<link>요소는 CSS 스타일 시트와 같은 외부 리소스를 HTML 문서에 포함하는 데 사용된다.
이것은 몇가지 중요한 이유로 HTML 문서의 <head>요소 내에 배치된다.

  • 1. 관심사 분리 : 웹 개발의 기본 원칙 중 하나는 관심사 분리이다.
    HTML은 웹페이지의 구조와 콘텐츠를 정의하는데 사용되는 반면, CSS는 해당 콘텐츠의 스타일을 지정하는데 사용된다.
    HTML문서의 <head>섹션에 <link>요소를 배치하면 구조/내용(<body>내)이 스타일(<head>내)과 분리되어 유지된다.
    코드를 관리하고 유지하기가 더 쉽다.

Q. 왜 HTML문서의 <head>섹션에 <link>요소를 배치하면 구조/내용(<body>내)이 스타일(<head>내)과 분리되어 유지될까?

  • 논리적 분리 : HTML은 웹 페이지의 구조와 콘텐츠를 나타내기 위해 설계된 반면 CSS(Cascading Style Sheets)는 해당 콘텐츠의 표현과 스타일을 정의하는 데 사용된다.
    <head>섹션에 <link>요소를 배치하면 스타일 시트를 포함한 문서와 메타 데이터를 실제 콘텐츠와 논리적으로 분리할 수 있다.
    이러한 분리를 통해 어느 부분이 무엇을 담당하는지 명확하게 하여 코드의 구성과 가독성이 향상된다.
  • 가독성 및 유지 관리성 : 문서의 별도 섹션에 구조/내용 및 스타일을 유지하면 코드를 더 읽기 쉽고 유지 관리하기 쉽게 만든다.
    개발자는 <body>내의 HTML콘텐츠를 탐색할 필요 없이 <head>섹션에서 CSS스타일을 쉽게 찾고 편집할 수 있다.
    이러한 분리를 통해 개발자 간의 문제 해결, 업데이트 및 공동 작업이 단순화 된다.
  • 재사용성 : 콘텐츠에서 스타일을 분리하면 웹사이트 내 여러 페이지에서 스타일을 재사용할 수 있다.
    <head>에 연결된 중앙 집중식 스타일시트에 스타일이 정의되면 해당 스타일이 전체 사이트에 일관되게 적용될 수 있다.
    이는 균일하고 응집력 있는 시각적 디자인을 촉진한다.
  • 성능 : <head>섹션에 <link>요소를 배치하면 브라우저가 콘텐츠를 렌더링하기 전에 스타일시트를 미리 로드하고 적용할 수 있다.
    이렇게 하면 사용자가 스타일이 지정된 콘텐츠를 더 빨리 볼 수 있으므로 웹 페이지의 인지된 로딩속도가 향상될 수 있다.
    스타일이 <body>섹션 내에 배치된 경우, 콘텐츠가 로드될 때 스타일이 구문 분석되고 적용되어 잠재적으로 UX가 덜 원활해진다.
  • 모듈성 : 개발자는 <head>에 연결된 CSS파일로 스타일을 분리하여 재사용 가능한 모듈식 스타일 시트를 만들 수 있다.
    하나의 CSS파일에 적용된 변경 사항이 여러 페이지의 스타일에 영향을 미치고 사이트 전체에서 일관성을 유지할 수 있으므로 이 모듈성을 사용하면 스타일을 더 쉽게 관리할 수 있다.

정리하자면, HTML문서의 <head>섹션에 <link>요소를 배치하는 것은 문제 분리 원칙을 준수하고 코드 가독성과 유지 관리성을 향상시키며 코드 재사용을 촉진하고 성능을 최적화하기 때문에 모범 사례가 된다.
구조/컨텐츠 및 스타일의 이러한 분리는 웹 개발의 기본 개념이며 잘 구조화되고 유지 관리 가능하며 효율적인 웹 사이트를 구축하기 위한 모범 사례로 간주된다.

  • 2. 사전 로드 : 브라우저가 <head>섹션에서 <link>요소를 발견하면 HTML콘텐츠를 렌더링하기 전에 연결된 CSS파일을 사전 로드하기 시작한다.
    이를 통해 브라우저는 콘텐츠가 로드되자마자 스타일을 적용할 수 있어 더욱 원활하고 빠른 UX를 제공할 수 있다.

Q. 왜 브라우저가 <head>섹션에서 <link>요소를 발견하면 HTML콘텐츠를 렌더링하기 전에 연결된 CSS파일을 사전 로드하기 시작할까?

  • 성능 최적화 : 구문 분석 프로세스 초기에 CSS파일을 미리 로드하면 브라우저가 HTML구문 분석과 동시에 스타일 시트를 가져올 수 있다.
    이러한 병렬 로딩은 페이지 로딩 속도를 크게 향상시킬 수 있다.
    브라우저가 <body>섹션에 도달하고 콘텐츠 렌더링을 시작할 때 스타일이 이미 사용가능하도록 보장하여 페이지가 스타일 없이 일시적으로 나타나는 '스타일 없는 컨텐츠 플래시(Flash Of Unstyled Content/FOUC)'가능성을 줄인다.
  • 렌더링 효율성 : 브라우저는 렌더링 되는 HTML콘텐츠에 스타일을 효율적으로 적용할 수 있다.
    브라우저가 이미 CSS파일을 미리 로드한 경우 스타일시트를 가져오기 위해 렌더링을 일시 중지할 필요가 없으므로 렌더링 프로세스가 더 부드럽고 빨라진다.
  • 인식된 속도 : 사용자는 스타일이 지정된 콘텐츠를 더 빨리 볼수록 웹 페이지가 더 빠르게 로드되는 것으로 인식한다.
    CSS를 미리 로드하면 브라우저에서 스타일을 빠르게 적용할 수 있으므로 전체 페이지 로드가 아직 완료되지 않은 경우에도 페이지의 반응성이 향상된다.
  • 렌더링 블록 방지 : 브라우저가 <body> 또는 HTML문서의 다른곳에서 <link>요소를 만날때까지 기다려야한다면 CSS파일이 다운로드 되기를 기다리는 동안 잠재적으로 렌더링을 차단할 수 있다.
    이러한 차단 동작으로 인해 최적화되지 않은 UX로 이어질 수 있다.
  • 캐싱 : CSS파일을 미리 로드하면 브라우저는 스타일시트를 캐시할 수 있다.
    사용자가 동일한 CSS파일을 참조하는 동일한 사이트의 다른 페이지를 방문하면 브라우저는 캐시된 버전을 사용할 수 있으므로 로드 시간을 더욱 향상시키고 서버 요청을 줄일 수 있다.

정리하자면, <head>섹션에서 <link>요소를 만나 CSS파일을 미리 로드하는것은 성능 최적화 전략이다.
브라우저가 HTML콘텐츠를 렌더링하기 시작할 때 스타일을 쉽게 사용할 수 있도록 하여 로드 시간이 빨라지고 렌더링이 원활하며 UX가 개선된다.

  • 3. 우선 순위 : <head>섹션에 <link>요소를 배치하면 스타일 로드 및 적용 측면에서 더 높은 우선순위가 부여된다.
    이렇게 하면 스타일이 전체 페이지에 일관되게 적용되어 CSS가 나중에 문서에 로드될 때 발생할 수 있는 깜빡임이나 일관되지 않은 스타일이 방지된다.
  • 4. 구성 : CSS파일을 포함한 모든 외부 리소스를 <head>섹션에 유지하면 문서 구조를 구성하는 데 도움이 된다.
    개발자가 이러한 리소스를 더 쉽게 찾고 관리할 수 있도록 <head>에 모든 meta data와 외부 참조를 배치하는 것이 일관적인 관행이다.
// HTML문서의 <head>섹션에서 외부 CSS스타일 시트를 링크하기 위해 <link>요소가 일반적으로 사용되는 방법의 예
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>My Web Page</title>
    <link rel="stylesheet" type="text/css" href="styles.css">
</head>
<body>
    <!-- 웹페이지의 콘텐츠 -->
</body>
</html>

위 예제 코드에서 <link>요소는 HTML콘텐츠에 로드되고 적용되는 'style.css'라는 외부 CSS파일을 참조한다.
<head>섹션에서 관심 사항과 배치를 분리하면 전체 페이지에 걸쳐 스타일이 일관되고 효율적으로 적용된다.

2. 자바스크립트를 불러오기 위한 <script>요소가 <body>가 끝나기 직전의 위치에 왜 존재할까?

HTML문서의 <body>섹션 끝에 </body>태그 바로 앞에 <script>요소를 배치하는 일반적인 방법은 다음과 같은 몇가지 중요한 이유로 수행된다.

  • 1. 개선된 페이지 로드 : <body>의 끝에 <script>요소를 배치하면 브라우저가 자바스크립트 코드를 처리하고 실행하기 전에 HTML콘텐츠를 먼저 로드하고 렌더링할 수 있다.
    이는 사용자가 콘텐츠를 더 빨리 보고 상호 작용할 수 있기 때문에 더 빠른 페이지로드로 이어진다. <head>섹션에 자바스크립트를 배치하면 브라우저가 자바스크립트를 다운로드하고 처리하는 동안 페이지 렌더링을 지연시킬 수 있다.
  • 2. 파싱 효율성 : 브라우저는 HTML을 위에서 아래로 파싱한다.
    브라우저가 <head>에 있는 <script>요소를 발견하면 종종 스크립트를 다운로드하고 실행하기 위해 HTML문서의 파싱을 일시 중지해야 한다. <body>의 끝에 <script>를 배치함으로써 대부분의 HTML콘텐츠가 이미 파싱되어 표시되었기 때문에 이러한 잠재적인 파싱 중단을 최소화한다.
  • 3. 렌더링 차단 감소 : <body>끝에 <script>를 배치하면 렌더링 차단의 가능성이 줄어든다.
    <head>에 자바스크립트를 로드하면 <script>가 완전히 다운로드되어 실행될때까지 페이지 렌더링을 차단할 수 있다. <body>끝으로 <script>를 이동하면 <script>위의 내용이 중단 없이 렌더링되어 보다 원활한 UX를 제공할 수 있다.
  • 4. DOM요소의 가용성 : <body>끝에 <script>를 배치하면 모든 HTML요소를 조작할 수 있다.
    자바스크립트 코드는 종종 DOM(Document Object Model)요소와 상호 작용하여 조작한다. <script>가 실행될 때쯤이면 HTML내용이 완전히 로드되고 DOM이 준비되므로 DOM요소가 존재하기 전에 액세스하려고 시도하는 것과 관련된 문제를 방지한다.
  • 5. 병렬 다운로드 : <body>끝에 <script>를 배치하면 리소스를 병렬로 다운로드할 수 있다.
    브라우저는 <script>를 포함한 여러 리소스를 동시에 다운로드할 수 있으므로 전체 페이지 로드 시간이 더 빨라질 수 있다.

하지만 <head>섹션에 <script>요소를 포함해야 하는 경우가 있다.
다음의 예시들을 살펴보자

  • 렌더링을 시작하기 전에 필수 콘텐츠를 로드하거나 기타 중요한 작업을 수행하기 위해 스크립트가 필요한 경우
  • 메타데이터 또는 구성목적으로 스크립트를 사용하려는 경우
  • 최적의 성능을 유지하면서 스크립트 실행 타이밍을 제어하기 위해 async 또는 defer와 같은 속성을 사용하여 스크립트가 실행되는 시기와 방법을 제어하는 경우

정리하자면, 닫는 </body>태그 바로 앞에 <script>요소를 배치하는 것은 페이지 로딩을 최적화하고, 렌더링 효율성을 향상시키며, 콘텐츠가 중단 없이 빠르게 표시되도록 하여 UX를 향상시키는 일박적인 관행이다.
그러나 스크립트 배치는 특정 사용 사례 및 성능 고려 사항에 따라 달라질 수 있다.


최종 정리

  1. <head>내에 <link> 요소를 배치하는 이유: <link> 요소는 CSS 스타일시트와 같은 외부 리소스를 포함하는 데 사용됩니다. 스타일 정보(<head>)에서 페이지의 구조/내용(<body>)을 분리하기 위해 <head> 섹션에 배치됩니다. 이러한 관심사 분리는 코드를 체계적으로 유지하고 가독성을 향상시키며 스타일이 효율적으로 적용되도록 보장합니다.
  2. </body> 전에 <script> 요소를 배치하는 이유: 닫는 </body> 태그 바로 앞에 <script> 요소를 배치하면 페이지 로딩이 최적화됩니다. 이를 통해 JavaScript 실행 전에 HTML 콘텐츠를 렌더링할 수 있으므로 인식되는 로드 시간이 향상됩니다. 또한 이 배치는 JavaScript가 상호 작용할 수 있는 DOM을 완벽하게 사용할 수 있도록 보장하여 DOM 요소가 존재하기 전에 DOM 요소에 액세스할 때 발생할 수 있는 문제를 줄이고 렌더링 차단 동작을 최소화합니다.

요약하자면, 이러한 방법은 웹 페이지의 로딩 및 렌더링을 최적화하고, 코드 구성을 향상시키며, 콘텐츠를 빠르고 원활하게 표시하여 사용자 경험을 향상시키는 데 사용됩니다.