Lilyrs

IEInternals: HEAD 태그를 올바르게 작성하기

글을 시작하며

오늘 문서는 낡고 낡은 우리의 웹 브라우저, Internet Explorer에 대한 이야기이다. 한때 윈도우 설치하면 기본으로 제공되는 웹 브라우저로써 정보화 사회로 나가는 과정에서 큰 디딤돌이 되어 준 웹 브라우저로, 이후 ActiveX 문제와 브라우저 성능 문제, 독점 문제 등으로 이어지며 웹표준과 대체 브라우저들의 출현으로 점점 자리를 잃다가 어느덧 2022년 지원 종료[1]를 앞둔 물건이다.

올해 작성하는 이 글을 끝으로 더이상 IE에 대한 글을 작성할 일이 없길 기원하면서, 지금은 폐쇄되어서 Archive.org 의 Wayback Machine을 통해서만 확인할 수 있는 글 하나를 소개하여 드리고자 한다. 이 글은 2011년 7월 18일(18 Jul 2011)에 EricLaw 라는 사용자가 MSDN Blogs에 IEInternals (Internet Explorer의 심층적 부분을 다루는 카테고리)에 게재한 글이다.

Best Practice: Get your HEAD in order (올바른 작성 습관: HEAD 내부를 바른 순서로 작성하자)
아카이브: https://web.archive.org/web/20150208090135/http://blogs.msdn.com/b/ieinternals/archive/2011/07/18/optimal-html-head-ordering-to-avoid-parser-restarts-redownloads-and-improve-performance.aspx
원문: http://blogs.msdn.com/b/ieinternals/archive/2011/07/18/optimal-html-head-ordering-to-avoid-parser-restarts-redownloads-and-improve-performance.aspx

완전히 이 글을 번역하는 건 원 저자나 혹은 MS의 동의가 필요하다고 생각되어, 간접적으로 이 글의 내용을 소개하며 중요한 부분은 직접 인용하려고 한다. 비록 IE의 이야기이긴 하지만 현대의 브라우저에서도 HEAD 태그를 올바르게 작성함은 매우 중요하기에 같이 살펴보자.

HEAD 내부를 바른 순서로 작성하자

먼저 가장 올바른 구조와 순서를 우선 제시하면 아래와 같다고 한다. DOCTYPE 선언은 기본, HEAD 내부를 작성시 반드시 컨텐츠 타입과 인코딩을 우선 선언하고[2] 그 바로 아래에 Internet Explorer의 전매특허, 호환성 모드 관련 설정값을 작성해야한다. 그 이후에 BASE[3] 를 작성하고 이후에 웹 페이지 제목이나 기타 스타일시트, 스크립트 블럭을 배치하는 구조로 이어진다.

1
2
3
4
5
6
7
<doctype>
<html>
<head>
<meta http-equiv content-type charset>
<meta http-equiv x-ua-compatible>
<base>
<title, favicon, comments, script blocks, etc>

가장 먼저 나타난 인코딩 속성 선언이 HEAD 초반에 발견되지 않으면 인코딩 자동 감지를 시도하고 안될 경우 기본 인코딩으로 렌더링을 시도하는데, 도중에 인코딩 선언부가 발견되어 렌더링을 다시 처음부터 하게 된다고 한다.

IE의 개발자 콘솔에서 확인 가능한 메시지는 아래와 같다.

HTML 1112: Codepage restart from windows-1252 to utf-8

두번째로 X-UA-Compatible 속성 선언이 나중에 나타나게 되면 문서 구조에 맞는 파서를 사용하기 위해 지금까지 렌더링될 결과를 버리고 다시 알맞는 문서 구조로 렌더링을 시작한다.

IE의 개발자 콘솔에서 확인 가능한 메시지는 아래와 같다.

HTML 1113: Document mode restart from IE9 Standards to Quirks

세번째로 나타난 BASE 태그 또한, 기본적으로 브라우저는 현재 페이지 경로를 기준으로 모든 상대 경로를 처리하게 되는데 이 태그가 나중에 나타날 경우 script, css, favicon 등을 불러오는 과정에서 쓰인 상대 경로를 다시 처리해야하므로 렌더링이 초기화되는 문제가 발생되어 느려진다.

IE 9의 Lookahead Pre-parser

당시(2011년) IE의 렌더링 엔진은 HEAD 내부가 올바르게 작성되지 않으면 HTML 파서(Parser)가 호환성 처리를 위한 기능을 활성화하며 렌더링을 다시 시작하거나, 페이지 렌더링에 필요한 리소스 우선순위 파악에 실패해 해당 리소스가 받아질 때까지 파싱(Parsing)을 멈추고 기다려야하는 문제가 생긴다.

웹 페이지 하나를 온전하게 표시하기 위해서는 지금(2021년)도 그렇지만 많은 리소스가 필요하다. HTML을 파싱하면서 추출해낸 스타일시트, 스크립트, 이미지 등 다양한 리소스를 같은 서버 혹은 다른 서버로부터 주소를 사용해 불러오는 과정이 절대적으로 필요하고 스크립트의 경우 해당 스크립트의 실행 시점을 미룰 수 없는 경우에는 반드시 실행해야만 파싱을 진행할 수 있다.

이 문제를 계속 안고 간다면 페이지가 완전히 렌더링 되려면 상당한 시간이 소요될 것이기에, 당시 IE의 경우엔 파서를 이중으로 운영하는 전략을 취했다고 한다.

한 발 앞을 보는(Lookahead), 미리 돌리는 파싱(Pre-parser).

메인 파서(Main parser)[4]와 선작업 파서(Pre-parser) 2개로, 만약 메인 파서에서 중대 문제를 발견해서 다시 파싱을 할 때 버려질 시간과 자원 낭비의 위험성을 도박에 맡기더라도[5] 대부분의 경우 올바르게 문서가 작성될거라 생각하고 선작업 파서를 통해 메인 파서보다 앞서나가서 리소스를 처리하는 전략을 택한다. 이것이 the Lookahead Pre-parser 컨셉이라고 한다.

HEAD 내부에 선언되는 인코딩 선언, 문서 모드 선언, BASE 선언이 잘못되면 메인 파서가 작업을 다시 시작해야함은 물론이거니와 선작업 파서가 앞서 해둔 작업이 아무 소용없게 되므로 렌더링 성능과 소요시간에 굉장한 손해를 보게 된다.

문서 구조 변경에 따른 렌더링 재시작은 MS에서도 골치 아팠는지, 각주2번을 보니 이런 내용이 있었다.

Internet Explorer 10 PPB2[6] introduced a new architecture where a versioning pre-scan occurs before the parsers begin their work; the X-UA-Compatible META tag must appear in the first 4kb of the markup or it will be ignored.

이후 IE 10 플랫폼 프리뷰 베타[7]에서는 결국 문서 구조로 인한 문제를 극복하기 위해, HTML 문서 중 첫 4kB를 읽어와 X-UA-Compatible 속성 선언이 있는지 검사한 다음에 문서모드를 결정하고 파서를 시작하는 형태로 개선이 이루어진 것 같다. 이 글은 IE 9가 현역으로 뛰던 시절의 글이므로 이 개선사항과는 무관한 것 같다.

맺음말과 사족

이 글에서는 결과적으로 HTML 문서 상의 HEAD/META 태그보다 더욱 높은 우선순위를 갖는 HTTP 응답 헤더를 사용하여 페이지 인코딩과 렌더링 모드 선언을 위한 IE 전용 헤더를 보내주어 렌더링이 초기화되어 다시 시작되는 현상을 예방하는 쪽으로 조치를 취하는 쪽을 권하고 있다.

물론 이건 당시 웹 브라우저인 IE 9가 ‘우리 웹 브라우저는 이 순서로 처리하니까 이렇게 작성해라’ 라는 부분도 좀 있는 것 같다. 실제로 이렇게 해야 빨라지는 건 IE 내부 구조상 자명한 사실이기도 하다.

현대의 웹 브라우저는 호환성 모드 IE 전용 META 태그는 살피지 않을 것이고, 더욱 다양한 알고리즘과 나아진 컴퓨팅 파워로 최적의 렌더링 속도를 보여주려 노력하기에 지금에 와선 이런 글이 있구나 정도만 아는 것도 좋을 것 같고 여전히 IE를 지원해야하는 웹 서비스를 만드는 분들에게는 도움이 될 문서가 되지 않을까 생각한다.

MSDN Blogs에 IEInternals에는 더 유용한 글들도 많이 있었던 것 같은데, 2021년 초까지는 인터넷으로 읽을 수 있었던 글들을 더이상 읽을 수 없게 된 것 같다. 확인하려면 Web Archive Wayback Machine 서비스를 이용하는 수 밖에 없는 것 같다.

작년에 IE로 사용해야하는 사내의 노후 서비스의 로딩 성능을 개선하기 위해 튜닝하던 도중에 어떤 이유로 HEAD 내 태그 순서를 살펴보게 되었고 그때 확인했던 글을 오늘 다시 보려고 했더니 사라져서 급히 거의 번역 및 재가공에 가까운 수준으로 글을 옮겨 블로그에 보관해두고자 한다.



  1. 1.IE Mode on Microsoft Edge와 LTSC 버전의 윈도우 10에 대하여 장기 지원이 이어지긴 한다. IE 11 데스크탑 앱 종료에 따른 FAQ
  2. 2.지금은 meta charset=UTF-8 이 올바를 것이다.
  3. 3.MDN: The Document Base URL Element 웹페이지 내부의 리소스 경로나 웹 링크가 상대 경로일 때 어느 경로에서 시작하게 해줄지 정할 수 있다.
  4. 4.실제 본문에서도 main parser란 용어를 사용하고 있다.
  5. 5.원문에서 speculative 로 언급하고 있다.
  6. 6.PPB가 무엇의 약자인지 확인하기 힘들다. 위키피디아의 Internet Explorer 10 글을 살펴보면 아마도 'Platform Preview Beta'로 추정된다.
  7. 7.6번 각주를 참고 바란다.