책임감 있는 반응형 디자인 #5. 책임감 있게 전달하기

Seo·2020년 7월 29일
0

목록 보기
5/8

목차

  1. 서문
  2. 책임감 있는 디자인
  3. 지속성 있는 감지 방법
  4. 성능 고려하기
  5. 책임감 있게 전달하기

5. 책임감 있게 전달하기

웹사이트를 구성하는 파일들이 준비되었다면, 책임감 있게 전달하는 방법을 알아보자.

5.1 HTML 전달하기

HTML이 차지하는 용량은 상대저으로 매우 작다. 그러나 각 문장마다 네트워크를 통해 요청해야 할 asset들이 있을 수 있기 때문에 잘 전달해야 한다.

5.1.1 모바일 중심 컨텐츠

가장 바람직한 것은 어떤 디바이스에 사용하는지 상관없이 핵심 콘텐츠와 기능만 전달 하는 것이다. 그러나 페이지나 화면 제약 사항 때문에 콘텐츠 중 일부가 희생될 수 밖에 없다.
따라서 콘텐츠에서 따로 빼놓을 수 없는 부분과 이런 내용을 전달하고 나중에 전달해도 되는 부분을 미리 분류해 놓는 것이 좋다. 이렇게 전달하는 기법을 lazy loading(지연로딩)이라고 한다.

5.1.2 체감 성능 향상을 위해 콘텐츠 지연 로딩하기

가장 핵심적인 콘텐츠를 우선적으로 전달하도록 페이지를 구성하면 초기 페이지 로딩 속도를 훨씬 빠르게 할 수 있다.
그리고 부가적인 콘텐츠는 사용자에게 핵심 페이지를 전달한 뒤 자바스크립트를 통해 제공하면 된다.

조건부 로딩 구현하기

HTML5 데이터 속성을 이용해 처리한다.
(데이터 속성 : data-로 시작해 뒤에는 data-foo처럼 원하는 명칭을 붙일 수 있는 확장 가능형 속성)

<a href="/sports" data-after="/sports/homepage-well">Sports</a>
$("[data-after]").ajaxInclude();

이 기법을 적용함으로써 HTTP 요청은 좀 늘어나지만 첫 페이지에 대한 렌더링이 끝나고 사용할 수 있는 상태가 된 뒤에 추가로 이루어진다.

5.1.3 일부 중단점에 대해서만 로딩하기

미디어 쿼리에 대해서도 에이잭스-인클루드 를 통해 원하는 미디어 쿼리 값을 가져올 수 있다.

<a herf="/sports" data-after="/sports/homepage-well"
   data-media="(min-width: 35rem)">Sports</a>

5.1.4 반응형 소스 순서

소스 순서로 인해 특정한 레이아웃을 제공하기가 힘들어질 때가 있다.

다양한 디바이스에 마크업을 다르게 제공하기 위해서 디바이스 감지 기능을 사용하거나, 콘텐츠를 표시 및 숨기도록 페이지의 각 부분마다 마크업을 반복해서 작성하는 일이 없도록 만드는 것이다.

레이아웃에 제약이 발생할 때는 어펜트어라운드로

필요한 마크업은 있지만 원하는 레이아웃을 표시하기에 적합하지 않은 지점에 있다면 자바스크립트를 통해 HTML상의 위치를 변경할 수 있다.

data-set 속성값은 그 값이 콘텐츠가 속할 수 있는 부모 요소를 지정하고, 그 콘텐츠가 속할 부모 요소의 초깃값도 이와 동일한 속성값으로 지정하면 된다.

5.2 CSS 전달하기

페이지 렌더링하는데 걸리는 시간은 asset의 영향을 많이 받는데, 그중에서도 특히 CSS 요청에 가장 크게 영향을 받는다.

CSS로 인해 발생하는 오버헤드를 최대한 줄여서 체감 성능을 향상시키는 방식으로 CSS를 전달해야 한다.

5.2.1 모든 것은 Head에 있다

초기 페이지 레이아웃에 필요한 스타일은 모두 페이지의 head에서 참조해야 한다. 그렇지 않으면 페이지를 로드하는 동안 FOUC(Flash Of Unstyled Content: 외부의 CSS가 불러오기 전에 잠시 스타일이 적용되지 않은 웹 페이지가 나타나는 현상이다)가 발생할 수 있다.

외부 스타일 참조방식은 흔히 방식이 있다.

방법 A : 거대한 스타일시트 하나에 인라인 미디어 쿼리 담기

<head>
  <link href="all.css" rel="stylesheet">
</head>
body{
  background-color: #eee;
}

@media (min-width: 35rem){
  뷰포트 폭이 35rem(~560px)보다 큰 뷰포트에 대한 스타일
}

@media (min-width: 55rem){
  뷰포트 폭이 55rem(~880px)보다 큰 뷰포트에 대한 스타일
}
  • 장점 : CSS 한 파일만 불러오기 때문에 HTTP 블로킹이 요청 하나에서만 발생
  • 단점 : 현재 페이지에서 사용하지 않을 스타일까지 가져오게 함으로써 페이지 로딩 시간과 데이터 사용량이 필요 이상으로 소모된다

방법 B : 미디어 관련 파일을 별도로 분리하기

반응형 CSS 로딩을 위한 두 번째 방법은 특정 미디어의 스타일을 별도 파일로 분리해서 각각을 따로 요청하는 것이다.
linkmedia 속성을 추가하여 적용.

<head>
  <link href="shared.css" rel="stylesheet">
  <link href="medium.css" media="(min-width: 35rem)" rel="stylesheet">
  <link href="large.css" media="(min-width: 55rem)" rel="stylesheet">
</head>
  • 장점 : 최신 브라우저는 link media 속성에 지정된 조건이 현재 브라우징 환경에 적용 가능한지 여부를 확인한다. 그래서 스타일시트 요청에 대한 우선순위를 높일지 아닐지를 결정한다. 그리고 당장 적용할 수 있는 스타일시트에 대해서만 페이지 렌더링을 시작한다.
  • 단점 :
    1) 미디어 조건에 맞지 않는 미디어 쿼리를 대상으로 하는 스타일시트를 무시할 것 같지만 실제로는 그렇지 않다. 속성이 일치하는 상관없이 HTML 문서에서 참조하는 모든 스타일시트를 무조건 요청한다.
    2) 이전과 같은 스타일들을 로드하기 위해 블로킹이 발생하는 HTTP요청을 2개나 추가한다.

(그냥 방법 A를 사용하는 것이 나을 수도 있다.)

방법 C : 모두 인라인 방식으로 작성

html 문서에 style 관련한 코드를 인라인 방식으로 모두 작성한다.

  • 장점 : 전송 시 내용을 더 많이 압축할 수 있다. 그리고 모두 한꺼번에 로딩할 수 있기 때문에 처음 사이트를 방문할 때의 로딩 속도가 빨라진다.
  • 단점 : html 내에서 지정한 스타일을 별도로 캐시에 저장하지 않기 때문에 나중에 같은 페이지를 다시 방문해 로드할 때 이전에 사용했던 스타일시트를 다시 로드해야 한다.

5.2.2 어느 방식이 가장 좋을까?

어려운 질문이다.

결론적으로 '더 좋은 방법은 얼마든지 찾을 수 있다.' 어쩌면 B와 C를 혼합한 하이브리드 방식이 최선일 수도 있다.

하이브리드 방식의 등장

체감 성능 향상과 관련해 많은 호응을 얻고 있는 기법으로, 서버와 주고받는 최초의 네트워크 왕복 과정에서 14킬로바이트 정도의 데이터만 서버와 브라우저가 주고받도록 최적화하는 것이 있다.

여기서는 초기 뷰를 렌더링하는 데 꼭 필요한 CSS만 HTML에 작성하고, 나머지는 논블로킹 방식으로 로드하도록 권장하고 있다.
단 이런 방식으로 구성하기는 쉽지 않다.

  • 북마크릿 : 모든 페이지에서 핵심적인 스타일을 추출하는 북마크릿(https://paul.kinlan.me/detecting-critical-above-the-fold-css/)
    핵심 원리는 간단하다. 핵심적인 CSS란 CSS 규칙 중에서도 페이지 상단 부분을 렌더링하는데 필요한 CSS 규칙을 말한다.

다소 큰 뷰포트 크기에서는 이런 북마크릿을 실행해 반응형 레이아웃의 많은 중단점을 렌더링하는데 필요한 스타일을 골라낸다.

  • Grunt-CriticalCSS : https://github.com/filamentgroup/grunt-criticalcss/
    코드베이스가 방대할 경우 자동화가 필요하다. 이 도구는 모든 템플릿에서 핵심적인 CSS를 자동으로 추출해 인라인 방식으로 추가할 파일에 사용한다.

  • loadCSS : https://github.com/filamentgroup/loadCSS
    사이트 전체에 필요한 CSS는 논블로킹 방식으로 최대한 빨리 로딩해야 한다. 이 때 사용하는 자바스크립트 함수. CSS 파일을 비동기식으로 불러오기 때문에 페이지 렌더링이 블로킹되지 않는다.

어떤 방식으로 CSS를 전달하는지에 관계없이 CSS를 최대한 간결하게 작성하고, 가능하면 우선순위에 따라 순차적으로 처리해 반복되는 부분을 최소화하는 것이 중요하다.

5.3 이미지 전달하기

파일 크기 중 가장 머리 아프게 만드는 요소는 이미지다.
이미지 요청이 블로킹으로 처리되지 않지만 성능에 영향을 미친다는 점은 변함이 없다. 이런 문제 중 상당수는 순전히 이미지 크기 때문에 발생한다.

5.3.1 백그라운드 이미지

미디어 쿼리를 통해 백그라운드 이미지를 책임감 있게 로드하느느 과정이 생각보다 굉장히 간단하다.
대부분 동일한 요소에 두 개의 background-image규칙이 적용되어 표시될 때 마지막으로 참조한 이미지를 가져온다. 이는 미디어 쿼리에도 마찬가지이다.

HD 화면의 백그라운드 이미지 업그레이드하기

min-resolution 미디어 쿼리 사용

.foo{
  background: url(foo.jpg);
}

@meida (min-resolution: 1440dpi){
  .foo{
    background: url(foo-large.jpg);
    background-size: 50px 50px;
  }
}

인라인 데이터 URI

또 다른 옵션으로 데이터 URI가 있다. 외부 참조를 넣을 자리에 이미지 데이터를 문자열로 표현해 직접 집어넣어 이 asset에 대한 요청을 서버로 보내지 않게 할 수 있다.

data:[<MIME-type>][;charset=<encoding>][;base64],<data>
background: url("data:image/png;base65, ......");

외부 참조 asset에 비해 성능을 크게 향상시킬 수 있다. 하지만 파일 데이터를 코드 안에 넣기 때문에 필요할 때만 다운로드받을 수 있게 만들 수 없다.
또한 데이터 URI를 남용하면 일부 모바일 디바이스에서 문제가 발생하기도 한다.
따라서 데이터 URI는 모든 디바이스와 중단점에 공통적으로 적용되는 asset에서만 사용하는 것이 좋다.

5.3.2 책임감 있는 반응형 포그라운드 이미지

모든 img 요소가 컨테이너의 폭을 100퍼센트 차지하도록 표현할 수 있다.

img { mas-width: 100%; }

그러나 이는 디바이스에서 표현할 수 있는 것보다 훨씬 많은 데이터를 로드해야 하는 경우가 발생한다.

이런 문제는 대체로 디바이스에 맞게 이미지 크기를 다양한 버전으로 제공하는 기능이 HTML에 없기 때문에 발생한다.
다행히 이런 작업을 잘 처리하는 도구를 활용하면 된다.

압축 이미지

JPEG 이미지를 품질이 훨씬 떨어져 보이는 두 배의 크기로 저장한 다음 좀더 깔끔하게 표현하도록 이미지를 축소하는 작업은 브라우저에게 맡긴다.
단점은 상당한 처리 능력과 메모리가 필요하다.

HTML을 위한 반응형 이미지

picture 요소와 그 요소의 속성인 srcset, sizes, media, type 등을 사용할 수 있다.

picture 요소

표준 규격에 따르면 "picture 요소는 한 개 이상의 CSS 미디어 쿼리에 의해 소스 콘텐츠가 결정되는 이미지 컨테이너" 라고 한다.

<picture>
    <source media="(min-width: 45rem)" srcset="large.jpg">
    <source media="(min-width: 18rem)" srcset="med.jpg">
    <img srcset="small.jpg" alt="...">
</picture>

srcset?

srcset src 거의 비슷해 보이는데 차이점은 무엇인가?
srcset으로 이미지 소스 후보를 지정하면 브라우저는 이를 일종의 제안 사항으로 간주한다.
브라우저는 srcset 크기를 참고해 현재 뷰포트 크기나 화면 해상도에 가장 적합한 이미지를 선택한다.

<picture>
  <source media="(min-width: 45rem)" srcset="large.jpg 45rem, large-2x.jpg 90rem">
  <source media="(min-width: 18rem)" srcset="med.jpg 18rem, med-2x.jpg 36rem">
  <img srcset="small.jpg 8rem, small-2x.jpg 16rem" alt="...">
</picture>

srcset은 아직 모든 브라우저에서 네이티브로 지원되지 않는다. 이런 브라우저에서 처리할 수 있는 한 가지 방법은 img alt에 지정된 텍스트를 대시 표시하는 방법이다.
하지만 여러가지 이유로 오버헤드만 증가시키는 단점이 있다. 현재로서는 폴리필 기법이 그나마 나은 대안이므로 이것에 대해 잠시 살펴보자.

sizes 속성 사용하기

로직은 3항 연사자와 비슷하게 동작함

<img srcset="..." sizes="(max-width: 30rem) 100%, 50%" alt="...">
  • 100% : 뷰포트 폭이 30rem 이하일 경우
  • 50% : 뷰포트 폭이 30rem 보다 넓을 경우

실제로는 해당 폭 만큼 이미지에 적용되지 않는다. 원래 의도한 이미지 크기에 최대한 맞추라는 힌드만 제공할 뿐이다.

다양한 종류의 이미지에 picture 사용하기

type 속성 : picture 안에 담긴 source 요소마다 파일 포맷을 가리키는 속성

ex:
1) svg : image/svg+xml
2) WebP: image/webp

최신 HTML 반응형 이미지 사용하기

아직 picture 요소를 지원하지 않는 브라우저에서 사용할 수 있는 폴리필 기법 중하나로 픽처필이라는 것이 있다.

5.4 픽셀 버리기

비트맵 이미지는 다양한 해상도와 크기에 대해 융통성 있게 대처하기에는 적합하지 않다.
다행히 최근 브라우저에서는 이런 확장 기능을 제공하는 벡터포맷을 대부분 지원하고 있다. 지금부터 벡터 기반 이미지로 구현하기 위한 방법에 대해 살펴 본다.

5.4.1 아이콘 폰트

아이콘 폰트를 사용하여 확장형 이미지를 제공할 수도 있다.

하지만 아이콘 폰트를 지원하지 않는 브라우저에서 오류가 발생하면 보기 안 좋기 때문에 주의해서 사용해야 한다.

  • @font-face 기능을 으용해 폰트 파일을 로드
  • font-family 값을 "Icons"로 지정하고, 나중에 HTML에서 요소 스타일을 적용할 때 여기서 지정한 값으로 다시 참조한다.
@font-face{
  font-family: "Icons";
  src: url("icons.woff");
  font-weight: normal;
  font-style: normal;
}

.icon-star:befor{
  font-family: "Icons";
  content: "★ ";

5.4.2 아이콘 폰트 기법 보완하기

간혹 @font-face를 지원하지 않는 브라우저에서는 예상치 못한 방식으로 오류가 발생하기도 한다.
이런 이유로 인해 아이콘 폰트 오류를 방지하기 위해 기능 테스트 코드도 함께 제공해야 한다.

여러가지 수행방법이 있는데 간략히 요약하면
테스트를 위해 html 요소에 supports-fontface라는 클래스를 추가하면 셀렉터에서 걸러낼 수 있다.

색깔을 표현 못하는 등 제약 사항이 존재한다.
다행히 아이콘이 아닌 다른 방식으로 벡터 그래픽을 사용하거나 여러 색상을 표현하는 몇 가지 방법이 있다.

5.4.3 SVG 사용하기

Scalable Vector Graphics: SVG(가변 벡터 도형 처리)

SVG를 img로 제공하기

SVG를 img 요소로 제공하면 로고와 같은 포그라운드 이미지를 간편하게 추가할 수 있다.

HTML로 SVG 제공하기

HTML 문서에 SVG 마크업을 페이지 본문 원하는 곳에 붙여 넣기만 하면 된다.
이렇게 함으로써 강력한 효과를 가질 수 있다.

직접 넣는 이러한 방식은 2가지 큰 단점이 있다.
1. SVG 그래픽을 하나의 독립적인 asset처럼 캐쉬에 저장하는 기능이 제한된다.
2. SVG를 지원하지 않는 브라우저에도 마크업을 보내서 불필요한 오버헤드가 발생할 수 있다.

SVG를 object로 제공하기

object 요소로 제공하면 HTML에 SVG를 내장할 때의 장점을 그대로 유지하면서 SVG 파일을 개싱에 저장하는 기능을 개선할 수 있다.

<object data="star.svg" type="image/svg+xml">
  폴백 콘텐츠를 여기에 적는다
</object>

SVG를 백그라운드 이미지로 제공하기

.star{
  background: url(star.svg);
}

이런식으로 SVG 백그라운드를 내장할 수 있다면 SVG 백그라운드만으로 구성된 스타일시트를 만들 수 있다.

여러 개의 비트맵 이미지를 하나로 합치기 위해 사용하던 CSS 스프라이트 기법의 장점과 유사한 효과를 벡터 그래픽에서도 얻을 수 있다.

5.5 폰트 전달하기

폰트-로딩 동작의 다양성 때문에 웹 폰트를 책임감 있게 제공하는데 몇 가지 어려운 문제가 있다.
<link>로 폰트 스타일을 직접 참조하는 경우 다른 블로킹 CSS 요청과 마찬가지로 잠재적인 실패 요인이 발생할 수 있다. 뿐만 아니라 FOUT(Flash Of Unstyled Text: 스타일 없는 Text가 보이는 현상)와 같은 문제게 끊임없이 시달리게 된다.

5.5.1 FOU의 후예

FOUT는 커스텀 웹 폰트를 완전히 로딩하기 전에 HTML 페이지가 화면에 표시될 때 발생한다. 몇몇 브라우저에만 나타나기 때문에 버그로 보아야 하는지 브라우저 기능으로 봐야 하는지 논쟁을 불러일으키기도 한다.(저자는 브라우저 기능으로 보는 입장)

파이어폭스, 오페라 등 몇몇 브라우저에서는 웹 폰트 전체가 로딩될 때까지 기다리지 않고 페이지를 로딩한다. 폴백 폰트가 보이고 로딩이 완료된 뒤 다시 렌더링 되면서 웹 폰트가 적용된 글자가 보이게 된다.

크롬이나 사파리, 인터넷 익스플로러와 같은 브라우저에서는 FOUT 현상을 피하기 위해 페이지를 렌더링할 때 커스텀 폰트 로드가 완료될 때까지 보이지 않는 텍스트로 페이지를 표시한다.(이런 경우를 FOIT(Flash Of Invisible Text)라고 한다.)
이런 브라우저에서 문제는 커스텀 폰트를 로딩이 완료될 때까지 보이지 않는다는 것이다.(저자: 인터넷 세상에서 30초면 지질학의 한 연대기와 맞먹는다)

5.5.2 FOIT보다는 FOUT

대부분 페이지의 HTML<head>에서 참조하는 CSS에서 커스텀 폰트를 로드할 때 발생한다.

이런 점을 보면 폰트를 참조하는 CSS 파일을 자바스크립트를 통해 비동기식으로 로딩해 FOIT대신 FOUT 방식으로 작동하게 할 수 있다.

font-face 정의와 함께 하나의 CSS 파일에 모두 넣는 방법을 권장한다.

<head>
 ...
  loadCSS("fonts.css");
 ...
</head>

5.6 자바스크립트 전달하기

자바스크립트는 이미지 다음으로 큰 용량을 차지한다.
그리고 심각한 성능 저하를 초래하는 요소를 가지고 있다.
자바스크립트를 요청하고 파싱하는 동안 페이지 렌더링이 블로킹 된다. 자바스크립트 파일이 많을 수록 사용자가 웹사이트를 사용할 수 있는 상태에 이르기까지 걸리는 시간은 길어진다.

'자바스크립트를 사용할 수 없는 사용자는 없다'라는 말은 틀렸다. 모든 사용자는 자바스크립트를 사용할 수 없다. 자바스크립트를 다운로드하는 동안에는.
-제이크 아치볼드-

5.6.1 핵심은 보여주는 데 있다.

자바스크립트 자체만으로 무겁게 나타나는 것은 아니다. 다양한 비표준 구현 사이에서 이리저리 휘둘리느라 같은 내용을 제각각으로 작성하고, 복잡도와 파일 크기가 늘어남으로써 상황이 더욱 나빠진다는 점이다.

JS는 최후의 수단이다.

가능하면 무겁고 복잡한 작업은 네이티브 HTML과 CSS에게 최대한 맡기고 자바스크립트는 최후의 수단으로 아껴두는 것이 좋다.

라이브러리가 정말 필요한지 검토하기

제이쿼리와 같은 DOM 라이브러리는 CSS 셀렉터를 통해 HTML 요소를 탐색하고, 이동 및 조작하는 방법을 제공한다. 이런 라이브러리는 WORE(Write-Once-Run-Everywhere) 메소드를 제공했기 때문에 한 기능을 다양한 브라우저에서 동시에 지원하기 힘들던 시절에 특히 인기가 많았다.

최근 브라우저에서 급격히 기능이 향상되면서 상당수의 라이브러리는 더 이상 필요하지 않게 되었다.
querySelectorAll 메소드와 같은 것들이 있다.

간단한 DOM 프레임워크 고려하기

구조가 복잡한 사이트를 제작할 때는 자바스크립트 프레임워크를 사용하는 것이 유리할 때가 많다.
무겁지 않으면서도 비슷한 기능을 제공하는 가벼운 DOM 프레임워크도 많이 있다.

커스텀 제이쿼리 빌드하기

굳이 제이쿼리를 사용해야 한다면 사용해도 좋다. 제이쿼리를 더 작게 만들면 된다.

5.6.2 자바스크립트 로딩을 위한 옵션

외부 파일을 참조하는 모든 script 요소는 해당 파일의 로딩 및 실행이 완료될 때까지 그 뒤에 나오는 콘텐츠에 대한 렌더링을 블로킹 한다. 이런 불필요한 블로킹 동작은 스크립트 로딩 방식을 변경함으로써 줄이거나 완전히 제거할 수 있다.

앞에서부터 가져오기

<head>
  ...
  <script src="myscript.js"></script>
  ...
</head>

브라우저에서는 myscript.js를 완전히 가져온 다음 바로 실행시킨다.
이 경우는 페이지 소스 초반에 참조한 asset이 페이지 로딩 프로세스에서 브라우저 파서에 먼저 노출되기 때문에 최대한 빨리 가져올 수 있다는 것이다.
그러나 이 방식은 스크립트를 요청하거나 실행해야할지를 결정하기 위한 조건을 지정할 방법이 없다.
그리고 모두 완료될 때까지 페이지 렌더링을 지연시킨다.

head에 직접 작성하기

네트워크 지연을 피하기 위해 페이지의 <head>에 직접 작성하는 방법이 있다.
HTML이 파싱되는 즉시 실행할 수 있다. 따라서 외부에서 파일을 가져오는 동안 기다릴 필요가 없다.

다만 페이지에 직접 넣은 스크립트는 개별 파일 형태로 캐시에 저장할 수 없으므로 페이지를 다시 불러올 때마다 스크립트도 새로 다운로드 된다.

그러면 언제 사용하면 좋을까?
자바스크립트 중에서도(심이나 폴리필처럼) 반드시 <head>에 넣어서 실행해야 하는 작고 핵심적인 코드를 블러올 때 유용하다.

뒤에서부터 가져오기

HTML 문서 끝부분에 배치해 최대한 빨리 콘테츠를 로드하고 렌더링할 수 있게 하는 것이다.
하지만 몇 가지 심각한 제약 사하이 있다.
1) 스크립트의 요청이나 실행 여부를 조건에 따라 제한할 방법이 없다.
2) 끝부분에서 참조하기 때문에 콘텐츠보다 훨씬 늦게 요청되며 실행하기 까지 더 많은 시간이 소요된다.

defer와 async 속성을 지정해서 다시 앞에서부터 가져오기

  • defer : 스크립트를 HTML 완전히 불러오기 전이나 후에 실행
  • async : HTML을 로딩하는 동안 여기서 참조한 자바스크립트 파일을 불러오게 하는 기능
<script src="myscript.js" async defer></script>

작은 인라인 스크립트로 스크립트를 동적으로 로딩하기

(저자가 추천)
페이지에 자바스크립트 일부를 인라인 방식으로 직접 작성하고, 이를 통해 추가로 불러올 부분은 <script>로 추가한다. 그러면 다운로드와 실행을 동시에 진행할 수 있다.

다양한 방법이 있지만 insertBefore 메소드가 가장 안전하고 안정적이다.

<head>
  ...
  <script>
    var myJS = document.createElement("script");
    myJS.src = "myscript.js";
    var ref = document.getElementsByTagName("script")[0]'
    ref.parentNode.insertBefore(myJS, ref);
  </script>
  ...
</head>

실제로 이렇게 작성하면 DOM에서는 이렇게 보인다.

<head>
  ...
  <script src="myscript.js"></script> <!--추가됨-->
  <script>
    var myJS = document.createElement("script");
    myJS.src = "myscript.js";
    var ref = document.getElementsByTagName("script")[0]'
    ref.parentNode.insertBefore(myJS, ref);
  </script>
  ...
</head>

그러나 가장 큰 한계는 상호의존하는 여러개의 스크립트를 불러올 때 문제가 발생할 수 있다.
이 문제를 해결하기 위해 확장 스크립트 모두를 하나의 파일에 합치고 그거를 위와 같은 방법으로 호출하는 방법이 있다.

5.6.3 책임감 있게 향상하기

다양한 요소로 화려하게 꾸며야 하는 사이트를 개발한다고 생각해보자.
이렇게 하려면 모든 브라우저에 공통적으로 전송되는 초기 코드에 들어가지 않을 정도로 더 많은 양의 자바스크립트와 CSS가 필요하다.

그러나 불필요한 코드나 요청으로 부담을 주지 않고 이를 사용할 수 있도록 해야 한다.

요건 충족 여부 확인하기

@media only all로 적용할 CSS 규칙을 걸러내듯이 자바스크립트 향상 기법의 적용 여부를 전반적으로 검사할 때도 활용할 수 있다.

BBC 개발자 톰 마슬렌의 '2계층 방식 반응형 솔루션'

  • 브라우저 기능 지원 상태에 따라 단순히 핵심만 담은 HTML로 사용자 경험을 제공받을 지
  • 아니면 향상된 버전을 제공받을지 결정
if("querySelector" in document &&
   "localStorage" in window &&
   "addEventListener" in window){
  //이 브라우저는 요건을 충족한다.
}

브라우저가 요건을 충족했다면 <html>요소에 enhanced라는 클래스를 추가해 향상 프로세스를 시작한다.

5.6.4 통과된 asset 로딩하기

원하는 조건에 대한 만족 여부를 확인해서 각 브라우저에서 작업을 처리하는데 꼭 필요한 것만 요청하게 만들어서 사용한다.

5.7 모두 합치기

앞서 나온 기술들 (+ 앞으로 나올 기술들) 현재 나온 기술들을 총동원해서 책임감 있는 사이트를 제공하자.
(그냥 webpack 쓰자)

profile
개발관심자

0개의 댓글