highligh.js 서버측 렌더링

내 이 세상 도처에서 쉴 곳을 찾아보았으나, 마침내 찾아낸, 컴퓨터가 있는 구석방보다 나은 곳은 없더라.

highligh.js 서버측 렌더링

블로그 글에 포함된 코드를 하이라이팅 하기 위해 highlight.js를 사용한다. highlight.js 역시 별도 JavaScript 파일을 로딩한 다음 페이지에 포함된 코드를 찾아 렌더링하는 식이라 페이지를 로드할 때마다 매번 다시 렌더링하는 비효율이 발생한다. MathJax 만큼 느리진 않지만, 가끔씩 네트워크 속도가 느린 환경에서 코드 블록이 울컥 하는 현상을 볼 수 있다. MathJax 서버측 렌더링에서 했던 것처럼 코드도 사이트를 생성할 때 한꺼번에 렌더링해두면 좋을 것 같다.

예상대로 highlight.js를 위한 CLI 도구가 있다. highlight.js-cli를 설치하면 hljs 명령으로 HTML 파일에 포함된 코드를 렌더링할 수 있다.

$ hljs --help
Usage:
  hljs [OPTIONS] [ARGS]
...

MathJax 서버측 렌더링에서 작성한 셸 스크립트에서 hljs도 함께 실행하도록 수정하면 될 것 같다.

...
  else
    hljs < $src | mjpage --format svg --dollars true > $target
  fi
...

hljs를 실행해 코드를 렌더링하고 그 결과를 mjpage로 다시 넘겨 수식을 렌더링한다. 느려터진 mjpagehljs까지 함께 실행시키니 HTML 페이지를 생성하는 속도가 더 느려졌다. 그러나 렌더링을 마친 페이지는 JavaScript 파일을 따로 로드해 실행할 필요가 없다. 그냥 로딩한 HTML을 그대로 보여주기만 하면 된다.

업데이트

며칠 후 블로그를 보다가 몇몇 페이지가 왕짱 깨진 것을 발견했다. 블로그에서 <canvas>와 같은 식으로 HTML 코드를 쓴 부분이 진짜 HTML 태그로 인식되어 페이지가 엉뚱하게 표현되는 문제였다. hljs에 뭔가 문제가 있는 게 분명했다. HTML 파일을 hljs로 렌더링하면서 HTML이 어떻게 바뀌는지 확인해보니, 소스 코드 하이라이트가 필요하지 않은 부분까지 hljs가 수정하는 것이 눈에 띄었다.

해당 부분을 수정하고 블로그 포스트가 모두 제대로 표시되는지 다시 확인했다. HTML 태그로 인한 문제는 사라졌지만 일부 소스 코드가 제대로 렌더링되지 않는 문제가 있었다. 마크다운으로 코드블록을 작성할 때 보통 언어를 지정하는데 이게 hljs에서 제대로 인식되지 않는 문제였다. 버그를 수정해 원작자에게 PR을 보냈고, 원작자가 마스터에 병합해 주었다.

내가 수정한 hljs를 이용해 다시 블로그를 생성하고 모든 페이지를 다시 확인했다. 예전에 Hexo를 쓰던 때의 악몽이 되살아나는 듯 했다. 그때도 Hexo나 node.js를 업데이트하고 나면 블로그가 깨지는 일이 잦았다. Hugo로 이사하고 나서는 그런 문제가 없었는데, 괜히 사이트 최적화 한다고 삽질하다가 쓸데없이 일을 만든게 아닌가 싶다. MathJax의 경우는 서버쪽 렌더링 효과가 크게 눈에 띄었지만 highlight.js의 경우는 체감 효과가 크지 않았고 잡일만 생겼다.

node.js 기반 도구는 너무 신뢰하지 말하야 겠다. 이미 highlight.js 서버측 렌더링 작업을 끝냈으니 넘어가지만, 다시 문제가 생기면 이 부분은 걷어내야겠다.

참고