링크 대신 HTML에 스타일 / 스크립트를 포함하지 않는 이유는 무엇입니까?


41

CSS와 JavaScript 파일을 연결하여 HTTP 요청 수를 줄이고 성능을 향상시킵니다. 결과는 다음과 같은 HTML입니다.

<link rel="stylesheet" href="all-my-css-0fn392nf.min.css">
<!-- later... -->
<script src="all-my-js-0fn392nf.min.js"></script>

서버 측 / 빌드 로직을 통해이 모든 작업을 수행 할 수 있다면 한 단계 더 나아가 HTML에 이러한 연결된 스타일과 스크립트를 포함시키지 않겠습니까?

<style>.all{width:100%;}.my{display:none;}.css{color:white;}</style>
<!-- later... -->
<script>var all, my, js;</script>

HTTP 요청이 두 개 적지 만 실제로이 기술을 보지 못했습니다. 왜 안돼?


12
캐싱을 비난합니다.

답변:


98

캐싱을 해제하여 HTTP 요청을 저장하면 달성 할 때 거의 소용이 없습니다. 스타일 시트와 스크립트가 개별적으로 제공되는 경우 아주 잘 캐시되어 매우 다양한 페이지에 대한 많은 요청에서 상각 될 수 있습니다. 동일한 HTML 페이지에 숨겨져 있으면 매번 다시 전송해야합니다. 단일. 의뢰.

예를 들어이 페이지의 HTML은 현재 13KB입니다. 180KB의 CSS가 캐시에 도달했으며 360KB의 JS도 마찬가지입니다. 두 캐시 적중에는 시간이 거의 걸리지 않았으며 대역폭을 거의 소비하지 않았습니다. 브라우저의 네트워크 프로파일 러를 채취하여 다른 사이트에서 사용해보십시오.


1
단일 페이지 앱 스타일 사이트를 수행하는 경우 대부분의 코드가 한 페이지에만 적용되는 사이트가 여전히 의미가 있습니까?
JohnB

3
John : 페이지를 한 번만 방문하면 그렇습니다. 여러 번 방문한 경우 내장 된 모든 항목이 한 번이 아니라 여러 번 전송되어 캐시됩니다.
Konerak

또 다른 좋은 점은 이러한 서비스를 별도로 제공함으로써 리소스를 최소화하여 크기를 줄일 수 있다는 것입니다.
maple_shaft

2
@maple_shaft 정교하게 말씀해주십시오. 왜 자원을 정상적으로 축소 한 다음 포함시킬 수 없습니까?

1
@JohnB는 isp에서 CDN 또는 로컬 캐싱의 영향을 잊지 않습니다. 동일한 isp를 사용하는 다른 사람이 isp가 이미 데이터를 캐시하게 만들었 기 때문에 로컬에서 캐시 미스가 발생하더라도 Google의 자바 스크립트에 대한 요청은 Google에 도달하지 않을 것입니다.

19

단순히 웹 성능이 중요 하기 때문에 ! 99 % 배 더 빠른 최종 사용자 응답 시간을 제공합니다.

다음은 Velocity Conf의 몇 가지 시험입니다.

  • Bing – 2 초 느린 페이지로 인해 수입 / 사용자가 4.3 % 감소했습니다.
  • Google – 400 밀리 초 지연으로 검색 / 사용자가 0.59 % 감소했습니다.
  • 야후 ! – 400 밀리 초의 속도 저하로 인해 전체 페이지 트래픽이 5-9 % 감소했습니다.
  • Shopzilla – 사이트 속도를 5 초 단축 시키면 전환율이 7-12 % 증가하고 검색 엔진 마케팅 세션 수가 두 배가되었으며 필요한 서버 수는 절반으로 줄었습니다.
  • Mozilla – 방문 페이지에서 2.2 초를 줄이면 다운로드 전환 수가 15.4 % 증가하여 연간 6 천만 건의 Firefox 다운로드가 증가 할 것으로 예상됩니다.
  • Netflix – 단일 최적화, gzip 압축을 채택하여 속도가 13-25 % 증가하고 아웃 바운드 네트워크 트래픽이 50 % 감소했습니다.

웹 성능 최적화의 선구자 인 Steve Souders가

최종 사용자 응답 시간의 80-90 %가 프런트 엔드에 소비됩니다. 먼저 여기에서 시작하십시오.

JavaScript 및 CSS 파일은 브라우저 / 네트워크 / 프록시 (캐시 헤더가있는 HTTP 프로토콜에 정의 됨)에 의해 캐시되므로 외부 파일을 사용하면 더 빠른 페이지가 생성됩니다. HTML 문서에 인라인 된 JavaScript 및 CSS는 HTML 문서가 요청 될 때마다 다운로드됩니다. 이렇게하면 필요한 HTTP 요청 수가 줄어들지 만 HTML 문서의 크기는 커집니다. Jquery와 유사한 스크립트를 사용하는 경우 300KB의 스크립트를 쉽게 참조 할 수 있으며 웹 사이트에서 열린 단일 응용 프로그램 (브라우저)을 실행하여 모든 사람이 대기 시간이 짧은 100MBits / s 대역폭을 가지고 있다고 생각하지 않습니다. 99 % 배 더 빠른 최종 사용자 응답 시간을 제공합니다.

요청 된 HTML 문서 수와 관련하여 외부 JavaScript 및 CSS 구성 요소가 캐시되는 빈도도 중요합니다. 사이트의 사용자가 세션 당 여러 페이지보기를 가지고 있고 많은 페이지가 동일한 스크립트 및 스타일 시트 (번들)를 재사용하는 경우 캐시 된 외부 파일의 잠재적 이점이 더 큽니다.

그러나 단일 페이지 응용 프로그램 또는 세션 당 하나의 단일 페이지보기가있는 웹 사이트에는 인라인이 선호되는 경우가 있습니다. 황금률은 없으며 일반적으로 최종 사용자 성능에 실제로 관련된 매우 구체적인 웹 사이트와 관련되어 있으므로 잊어 버리십시오.

성능이 중요한 이유를 여기서 읽을 수 있습니다 (면책 조항 : 저자입니다).


3

최신 버전의 HTTP는 1999 년에 만들어졌습니다. 1999 년에는 모두 전화 접속으로 인터넷에 연결했습니다. 인터넷은 매우 느 렸습니다. 16 년 후, 많은 일들이 진행되었지만 우리가 사용하는 프로토콜은 그렇지 않았습니다.

'캐싱을 방해하기 때문에'인라인해서는 안되는 답변은 특히 초고속 인터넷 시대에 약간 오해의 소지가 있습니다. 실제로 계산을 수행 할 때 인라인 된 경우 캐시 웜 및 캐시 콜드 사용자의로드 시간간에 무시할만한 차이가 종종 있습니다. 이 사실 이다 작은 차이점은 인라인 때문에 본질적 아니라, 때문에 HTTP / 1.1의 유연성 디자인.

SPDY 프로토콜은 server push 라는 것을 구현 합니다 . 이것은 본질적으로 HTML 문서 자체와 프로토콜로 인라인됩니다. 지능형 서버는 클라이언트가 이미 가지고있는 리소스를 알고 있습니다. 벙어리 서버는 성능에 영향을 미치지 만 대역폭 측면에서 비용이들 수 있습니다. 브라우저에 캐시에 내용이있는 경우 수신 사본을 버릴 수 있습니다. 서버는 추가 리소스를 보내기 전에 HTML이로드 될 때까지 기다립니다. 이론적으로 브라우저는 서버 푸시를 취소하라는 신호를 보낼 수 있습니다.

HTTP / 2.0은 SPDY를 기반으로하며 서버 푸시를 구현할 가능성이 높지만 이론적으로는 SPDY 사용을 시작할 수 있습니다. 따라서 우리가 인라인하지 않는 실제 이유는 레거시 중 하나입니다. 현재 존재하는 프로토콜은 오래되었으며 '프로토콜 수준 인라인'을 달성하기에 충분히 유연하지 않습니다.


2
흥미로운 답변이지만 "레거시"보다는 현재 인라인하지 않은 이유는 현재 웹 프로토콜 인프라에 가장 적합하기 때문입니다. HTTP / 2.0 / SPDY가 완전히 배포 된 n 년 동안 모두가 같은 일을 계속하고 있다면 레거시가 될 것입니다. ;-)
andybuckley

2
인용을하거나 계산을 스케치하거나 최소한 "초고속"에 대한 야구장 번호를 줄 수 있습니까? 문명화 된 제 1 세계 국가의 사람들은 온라인 (읽기 : 고객)에 대해 상당한 액수의 돈을 여전히 초당 또는 수백 메가 바이트보다 적은 대역폭으로 탐색 할 수 있습니다. 하나는 3MB / s, 종종 700KB / s 미만에는 거의 도달하지 않습니다. 별도의 요점으로, OP가 제안한 방식으로 인라인 할 이유를 제공하지 않고 (실제로 하지 않는 이유를 제공함) 프로토콜을 최적화 할 이유를 제공합니다.

1
내 3G 연결이 "초고속"이거나 전화 요금이 불필요한 데이터를 높이 평가하지는 않습니다. 잊지 마세요. 테 더링 및 3G 지원 태블릿 / 노트북을 사용하여 모든 모바일 데이터 사용이 전화기에있는 것은 아닙니다. Esp. 랩탑의 경우 가정 광대역 연결의 Wi-Fi / 이더넷으로 가정합니다. 원격 테 더링시 감사하지 않음 ...
AnonJr

3

다른 답변이 제기하는 캐싱 및 검색 문제 외에도 파싱이라는 또 다른 더 모호한 문제를 강조하고 싶습니다 .

HTML에 나타나는 JavaScript는 다음 예와 같이 구문 분석 문제가 발생할 수 있습니다.

<html>
<head>
<script>
function myfunc() {
    if ("</style> isn't a problem")
        return "but </script> is"
}
</script>
<style>
body::after {
  content: '</script> is okay, but not </style>'
}
</style>
</head>
<body>
<script>document.write(myfunc())</script>
</body>
</html>

... HTML로 트리거되는 일부 문자를 이스케이프하려면 스크립트를 변환해야합니다. CSS와 JavaScript를 외부 리소스로 제공하면 더 이상 '부모'구문 분석 컨텍스트를 고려할 필요가 없으므로이 문제는 사라집니다.

콘텐츠를 XML로 제공하는 경우 CDATA 섹션을 사용하여이 문제를 해결할 수 있습니다. 그러나 CDATA에는 비슷한 문제가 있습니다.

<?xml version="1.0" encoding="utf-8"?>
<html>
<head>
<script>
// <![CDATA[
function myfunc() {
    if ("</script> is no longer a problem")
        return "but ]]> is"
}
// ]]>
</script>
<style>
<![CDATA[
body::after {
  content: 'same ]]> issue here'
}
]]>
</style>
</head>
<body>
<script>document.write(myfunc())</script>
</body>
</html>

인라이너는 조심해야합니다.


1

프리젠 테이션의 스타일링에서 컨텐츠를 분리하는 것이 일반적으로 적은 수의 http 요청보다 큰 이점입니다.

모든 스타일을 분리하면 재사용 및 공유 파일을 활성화하고 장려합니다.

또한 파일의 내용은 정적이며 해당 페이지와 방문한 다른 페이지 모두에 대해 서버와 클라이언트 모두에서 캐싱 할 수 있습니다.

당신에게 구체적인 질문 ...하지만 서버가 축소 자체를 수행하면 자산을 유지 관리하고 디버그하기가 더 어려워집니다. 그러나 많은 프레임 워크가 이제 파일 수준에서 수행합니다 (예 : 모든 cs 및 모든 j). 예를 들어 ruby ​​on rails 프레임 워크는 이제 생산 자산을 최소화합니다. 5-10 개의 추가 http 요청은 일반적으로 병목 현상이 아니며, 100 개 이상의 http 요청이있는 경우에는 더 많은 병목 현상이 발생하지 않습니다.

실제로 페이지 자체에 코드를 포함시키는 추가 단계는 다운로드 순서를 신중하게 관리해야하는 더 큰 페이지의 단점이 있으며 페이지는 (현재 큰) 페이지의 나머지 부분 없이는 내용을 자주 표시 할 수 없습니다 다운로드 중입니다.


명확히하기 위해 스타일과 컨텐츠를 분리하면 개발자에게 이익이되거나 최종 사용자의 브라우저 성능에 도움이된다고 말하는가?

나는 회사에 대한 전반적인 이익이 일반적으로 비즈니스 용어 요청 감소보다 큰 승리라고 말하고 있습니다.
Michael Durrant

3
OP는 별도의 파일로 개발하는 것을 옹호하고 배포 중에 최소화, 난독 화 및 "일반적인"연결과 함께 연결하는 것을 옹호한다는 것을 알고 있습니까? 유지 관리 가능한 코드 기반을 확보하고 성능상의 이점도 누리십시오. 이는 소스 코드 축소 및 여러 JS / CSS 파일을 하나로 연결하는 것과 같은 다른 코드 처리 최적화와의 일반적인 관행입니다.

나는 그것을 모른다. "연결된 스타일과 스크립트를 HTML에 포함 시켰습니까?"라는 단어 혼란스러워
Michael Durrant

명확히하기 위해, 나는 실제로 @delnan이 그의 의견에서 나를 대신하여 명확히 한 것을 제안하는 것을 의미했습니다. 내 질문의 문구가 애매한 경우 죄송합니다.
GladstoneKeep

1
  1. 중복 코딩을 최소화하십시오. 시간 절약 (한 페이지에 코딩 된 스타일과 JS 함수를 재사용 할 수 있음).
  2. 변화 노력을 최소화하십시오. (고객이 웹 사이트의 버튼 색상을 변경하도록 요청하는 경우 한 페이지 씩 이동해야합니다.)
  3. 로드 시간 단축 (CSS와 JS가 중복되는 경우 개별 페이지 크기가 증가하고 다운로드하는 데 시간이 걸리지 만 일반적인 CSS JS는 계속해서 다시 다운로드 할 필요가 없음)을 의미합니다.
  4. 원격 사용. (공통 CSS js JS를 원격지에 둘 수 있습니다. 동일한 호스팅 서버가 아닙니다)
  5. 버그 수정 시간을 줄입니다. 하나의 기능에 버그가있는 경우 임베디드 JS 및 CSS의 버그를 수정하려면 페이지별로 이동해야합니다.
  6. SEO를 높이려면 (메타 데이터로 콘텐츠를 간단히 분리)
  7. 보다 깨끗하고 이해하기 쉬운 코드 (모든 파일을 하나의 파일 디버그에 포함 시키면 코드 선명도가 사라지고 각 페이지는 매우 긴 페이지가됩니다).
  8. 또한 제품 크기를 줄이는 데 도움이됩니다.
  9. 그러나 여전히 가장 독특한 것을 동일한 페이지에 포함시키는 것을 고려할 수 있습니다.

0

HTML에 스타일 / 스크립트를 포함해서는 안됩니다.

매 페이지 요청마다 내장 스타일 / 스크립을 다운로드해야합니다.

이러한 스타일은 브라우저에서 캐시하여 다른 페이지에 재사용 할 수 없습니다. 이 때문에 가능한 한 적은 양의 CSS / JS를 포함하는 것이 좋습니다.

대신 CSS / 스크립트를 바인딩하기 위해 링크를 사용할 때 링크 코즈를 사용합니다.

여러 페이지 요청에 대한 사이트 속도가 증가합니다.

사용자가 웹 사이트를 처음 방문하면 브라우저가 현재 페이지의 HTML과 연결된 CSS 및 JS 파일을 다운로드합니다. 다른 페이지로 이동하면 브라우저는 새 페이지의 HTML 만 다운로드하면되고 CSS / JS 파일은 캐시되므로 다시 다운로드 할 필요가 없습니다. 큰 스타일과 스크립트 파일이있는 경우 특히 큰 차이를 만들 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.