YouTube 임베드는 너무 무겁고, 고칠 수 있음
(frontendmasters.com)- 기본 YouTube
<iframe>임베드는 빈 페이지에 하나만 넣어도 32개 요청, 1.3MB 전송량이 발생해 작은 영상 UI에 비해 부담이 큼 - 여러 영상을 붙이면 리소스가 공유되지 않아 무게가 선형으로 증가하며, Zach Leatherman 측정에서는 2개 2.4MB, 3개 3.6MB까지 늘어남
- 처음 보이는 기능은 포스터 이미지, 제목, 큰 재생 버튼 정도라
<lite-youtube>같은 Web Component로 같은 경험을 더 가볍게 재현할 수 있음 lite-youtube-embed는 약 100KB 수준이고 여러 임베드 간 리소스를 공유해, 기능 손실 없이 속도와 효율을 개선함- YouTube 임베드가 널리 쓰이는 만큼, 임베드당 메가바이트 단위 데이터를 줄이는 일은 전기 사용과 탄소 배출까지 낮추는 실질적 최적화가 됨
기본 <iframe> 임베드의 비용
- YouTube 공유 메뉴에서
<> Embed를 선택하면<iframe>기반 HTML이 제공됨 - 기본 코드에는
loading="lazy"가 없어, 화면 밖 영상도 즉시 로드될 수 있음 - YouTube가 기본 iframe에 지연 로딩만 추가해도 즉각적인 성능 개선이 가능함
<iframe
...
loading="lazy"
>
</iframe>
- iframe을 반응형으로 만들고 원래 비율을 유지하려면 CSS로 YouTube embed iframe을 직접 지정할 수 있음
iframe[src^="https://www.youtube.com/embed/"] {
inline-size: 100%;
block-size: auto;
aspect-ratio: 16 / 9;
}
실제 측정치와 선형 증가
- 빈 페이지에 YouTube 임베드 하나만 넣었을 때도 로드 비용이 크게 나타남
-
32개 요청
- 1.3MB 데이터 전송
- 작성자 WiFi 기준 2.76초 로드
- Zach Leatherman은 임베드가 늘어날수록 리소스가 공유되지 않아 무게가 선형으로 증가한다고 기록함
- 임베드 2개: 2.4MB
- 임베드 3개: 3.6MB
- 현재는 Zach가 확인했던 시점보다 크기가 더 늘어난 것으로 보임
-
사용자가 처음 보는 UI는 단순함
- YouTube 임베드에서 사용자가 처음 마주하는 요소는 제한적임
- 영상의 포스터 이미지
- 영상 제목
- 클릭하면 재생되는 큰 재생 버튼
- 이 정도 UI와 동작은 전체 YouTube 플레이어 리소스를 먼저 로드하지 않아도 구현 가능함
- 가벼운 임베드가 참여도를 낮춘다는 이야기는 방법론과 데이터가 공개되지 않으면 판단하기 어려움
- 과거 YouTube 엔지니어가 더 가벼운 비디오 페이지를 테스트했을 때 평균 로드 시간이 오히려 증가한 사례도 있음
- 더 가벼운 페이지가 저성능 기기와 느린 인터넷 환경의 사용자에게까지 도달함
- 새로 접근 가능해진 사용자의 이용이 평균 로드 시간 지표를 느리게 만들었을 수 있음
- 평균 로드 시간만 보면 사용자별 실제 속도 개선을 놓칠 수 있음
대안: <lite-youtube> Web Component
- Google의 성능 관련 인물인 Paul Irish가 만든 lite-youtube-embed는 기본 임베드 경험을 더 가볍게 재현하는 Web Component임
- 프로젝트 설명은 실제 임베드처럼 렌더링하면서 약 224배 빠르다고 소개함
- 사용자 경험은 기본 YouTube 임베드와 거의 같음
- 포스터 이미지 표시
- 제목 표시
- 큰 재생 버튼 표시
- 클릭 시 비디오 재생
- 차이는 리소스 사용량과 공유 방식에 있음
- 기본 YouTube 임베드: 약 1.3MB
<lite-youtube>: 약 100KB- 여러 임베드 간 리소스 공유 가능
- 기능 손실 없이 속도, 효율, 기본 개인정보 보호를 얻을 수 있음
사용 방식과 관련 구현
- JavaScript로 Web Component를 등록한 뒤
<lite-youtube>요소를 쓰는 방식임 - npm 설치, 직접 복사, CDN 링크 방식이 모두 가능함
import "https://esm.sh/lite-youtube-embed";
- README 권장 방식은 HTML을 먼저 두고, 스크립트를 비동기로 로드해 점진적 향상을 적용하는 형태임
- JavaScript가 로드되기 전에도 올바르게 보이도록
background-image를 HTML 안에 넣을 수 있음
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/…;
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/…; integrity="sha512-utq8YFW0J2abvPCECXM0zfICnIVpbEpW4lI5gl01cdJu+Ct3W6GQMszVITXMtBLJunnaTp6bbzk5pheKX2XuXQ==" crossorigin="anonymous" referrerpolicy="no-referrer" />
<lite-youtube videoid="ogfYd705cRs" style="background-image: url('https://i.ytimg.com/vi/ogfYd705cRs/hqdefault.jpg');">
<a href="https://youtube.com/watch?v=ogfYd705cRs" class="lty-playbtn" title="Play Video">
<span class="lyt-visually-hidden">Play Video: Keynote (Google I/O '18)</span>
</a>
</lite-youtube>
- 관련 구현과 대안도 있음
- Shadow DOM version: 스타일 보호가 더 강하지만 스타일링이 더 번거로움
- Building a YouTube Embed Web Component: vanilla와 WebC 방식 구현
- YouTube and Vimeo Web Component: YouTube와 Vimeo용 Web Component
- youtube-video-element:
<video>DOM API와 맞춘 Mux 구현 - React Port
- Next.js Official Version
댓글과 토론
Hacker News 의견들
-
커뮤니티 포럼 플랫폼에서 YouTube 임베드를 감지해, 클릭 전에는 로드되지 않는 프록시 썸네일로 바꿔 둠
스레드의 한 사람이 YouTube 영상을 공유했다고 해서 그 페이지를 여는 모두가 1MB+ JavaScript를 내려받고 Google에 IP 추적까지 당할 필요는 없음- YouTube, SoundCloud, Reddit 임베드가 대부분인 무한 스크롤 사이트를 운영하는데, YouTube는 이렇게 처리해야 겨우 쓸 만해졌음
추적은 크게 신경 쓰지 않아서 YouTube가 제공하는 썸네일을 그대로 쓰고 있음 - SoundCloud에도 비슷한 해법이 있는지 궁금함
SoundCloud 플레이어도 엄청 무거움 - 마침 같은 문제를 다루는 중이라, 이 방식에 대한 팁이나 예제가 있으면 알고 싶음
- 썸네일도 캐시하거나 프록시하는지 궁금함
썸네일을 핫링크하면 Google이 거기서도 추적할 수 있음
- YouTube, SoundCloud, Reddit 임베드가 대부분인 무한 스크롤 사이트를 운영하는데, YouTube는 이렇게 처리해야 겨우 쓸 만해졌음
-
글쓴이는 더 가벼운 버전이 참여도를 낮춘다는 증거를 믿지 않는다고 했지만, 나는 충분히 그럴 수 있다고 봄
추천된 lite-youtube-embed 프로젝트 데모에는 라이트 플레이어와 일반 플레이어가 모두 있는데, 라이트 버전은 영상 재생 시작까지 눈에 띄게 더 오래 걸림
로드 시간이 1밀리초 늘 때마다 참여도는 줄어들고, 여기서는 차이가 수백 밀리초 이상으로 보임
https://paulirish.github.io/lite-youtube-embed/- 그럴 가능성이 크지만, 영상을 더 빨리 시작시키는 게 임베드된 웹페이지 자체를 느리게 만드는 대가를 치를 만큼 가치 있는지도 따져봐야 함
모든 밀리초가 중요하다는 논리는 웹페이지에도 적용됨. 사용자가 페이지에서 이탈하면 영상까지 가지도 못함
또 사용자가 영상을 안 보고 싶어하는 것도 괜찮을 수 있음. 개인적으로는 웹페이지에 요약이 있으면 영상을 피할 수 있어서 좋음
YouTube의 데스크톱 개편도 불만인데, 정작 보러 온 영상보다 다른 영상을 홍보하는 데 화면을 너무 많이 씀. 방해 요소가 적었으면 함 - 임베드 영상을 실제로 보려고 하는 드문 순간에 몇백 밀리초 기다리는 편이, 보지도 않을 임베드 플레이어를 페이지 방문 때마다 전부 로드하는 것보다 훨씬 낫다고 봄
신호등으로 치면 모든 신호가 짧게 빨간불인 것보다, 내가 접근하는 신호가 초록불인 편이 좋음 - “로드 시간이 1밀리초 늘 때마다 참여도가 줄어든다”는 건 90년대식 믿음에 가까움
대기업들의 실제 행동을 보면 그런 걸 신경 쓰지 않는 게 분명하고, 그들에게 중요하지 않다면 우리가 대신 최적화해 줄 이유도 없음
이 용례에서는 큰 문제가 아니지만, 나머지 스택에서는 성능을 신경 써야 함 - 예전 YouTube 플레이어는 영상 전체를 로드하고 버퍼링해서, 다시 볼 때 재다운로드가 필요 없어 편했음
어쩌다 이렇게 후퇴했는지 모르겠고, Google은 멀쩡히 잘 작동하던 것들을 점점 망가뜨리는 것 같음 - 차이가 있긴 하지만 그렇게 크지는 않아 보이고, 100ms까지 간다면 놀랄 듯함
환경에 따라 달라질 수 있음: Firefox, 2년쯤 된 i7-1185G7 노트북, Windows 11, 32비트 모드 Edge가 계속 업데이트 중이고 몇 주간 재부팅 안 한 상태
느리다는 인상을 주는 건 회전 로딩 표시 때문이 큼. 스스로 느리다고 광고하는 셈임
클릭 후 재생까지의 지연이 영향을 주긴 하겠지만, 그 정도를 제대로 측정하려면 YouTube 정도 규모의 주체가 필요함
- 그럴 가능성이 크지만, 영상을 더 빨리 시작시키는 게 임베드된 웹페이지 자체를 느리게 만드는 대가를 치를 만큼 가치 있는지도 따져봐야 함
-
더 가벼운 임베드가 참여도를 낮춘다는 소문과 제안된 lite-youtube-embed에 대해, 사용자는 플레이어가 조금만 다르게 보이거나 다르게 동작해도 낯설고 못 믿을 대상으로 받아들일 수 있음
데모의 lite-youtube-embed는 제목이 보여도 실제 YouTube 페이지로 넘어가는 링크가 없어서, 원본 “콘텐츠”로 못 가게 막는 듯한 적대적인 느낌까지 줌
물론 그 기능은 쉽게 추가할 수 있겠지만, 더 큰 문제를 드러냄
나는 임베드 영상을 거의 재생하지 않지만, 재생한다면 그냥 일반 YouTube 경험이면 충분함. 또 다른 알 수 없는 레이어로 감싸 놓으면 클릭할 가능성이 줄어듦
이 글의 “희생되는 게 없다”는 표현은 개발자가 사용자가 소프트웨어를 어떻게 쓰는지 안다고 착각하는 사례임. 실제로는 늘 추측일 뿐임
영상이 줄고, 모든 곳의 Google 의존과 JavaScript 덩어리가 줄어들길 바람. 더 나은 웹을 위해 YouTube 영상을 아무 데나 임베드하지 않았으면 함
https://paulirish.github.io/lite-youtube-embed/- YouTube 공식 임베드 UI에서도 Watch on YouTube 버튼이 충분히 눈에 띄지 않아서, 항상 재생을 누른 뒤 일시정지하고 오른쪽 아래 YouTube 버튼을 눌렀음
이제 알게 됐으니 이런 라이트 플레이어에도 그 버튼이 있으면 좋겠음. 그래도 이 구현은 링크를 얻는 쉬운 방법을 완전히 막지는 않음 - lite-youtube-embed에는 나중에 볼 동영상 저장 버튼도 빠져 있는데, 자주 쓰는 기능임
영상을 재생하면 접근할 수는 있지만 그건 목적에 어긋남. 영상을 재생하고 싶지 않고, 로드될 때까지 기다렸다가 일시정지한 뒤 저장 버튼을 누르고 싶지도 않음
- YouTube 공식 임베드 UI에서도 Watch on YouTube 버튼이 충분히 눈에 띄지 않아서, 항상 재생을 누른 뒤 일시정지하고 오른쪽 아래 YouTube 버튼을 눌렀음
-
이제 블로거들이 GitHub Gist 임베드를 쓰지 못하게만 하면 됨
Hugo와 아마 다른 정적 사이트 생성기들은 구문 강조가 있는 코드 조각을 기본 지원하고, 더 동적인 사이트도 highlight.js로 제3자 서비스 의존을 없앨 수 있음
작은 코드 조각에 무거운 iframe을 쓰는 건 정말 이상함
https://gohugo.io/content-management/syntax-highlighting/
https://highlightjs.org- 사람들이 자기 사이트에서 원하는 걸 하게 두면 되지 않나 싶음
내가 마음에 안 들어도, 내 취향에 맞추라고 사이트 변경을 “강제”하는 건 말이 안 됨 - Automattic에서 일할 때 Gist의 하트 이모지가 GitHub가 아니라 WordPress에서 제공되고 있다는 걸 발견한 적 있음
몇 주 안에 고쳐졌지만, 그 상태로 몇 년이나 있었다는 게 놀라웠음
- 사람들이 자기 사이트에서 원하는 걸 하게 두면 되지 않나 싶음
-
페이지에서 Content Security Policy를 활용할 수 있다면, 광고를 차단해 임베드의 전체 무게를 줄이고 사용자 경험도 개선할 수 있음
관련 정보: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Co...Content-Security-Policy에 unsafe-inline을 무심코 넣지 않는 게 좋음
CSP의 삽입 공격 방어를 꺼 버리기 때문임. 꼭 필요하다면 인라인 스크립트를 허용하는 더 안전한 방법들이 있음
https://content-security-policy.com/
-
“더 가벼운 임베드가 참여도를 낮췄다”는 이야기에는 큰 부분이 빠져 있는 것 같음
당연히 로드 시간이 빨라지면 참여도는 좋아져야 함. 그런데 가벼운 임베드에서 참여도가 떨어졌다면 어떤 기능이나 동작이 희생됐다는 뜻임
그런데 이 글은 희생된 게 없다고 말하니, 이야기 어딘가가 빠져 있음- Facebook이나 Uber 같은 대형 기술 회사가 최적화를 추가했더니 비슷한 결과가 나왔고, 알고 보니 이전에는 페이지조차 못 열던 새로운 시장에서 접근하기 시작했다는 글을 본 기억이 있음
여기서도 비슷할 수 있음. 더 가벼운 임베드 덕분에 많은 사람이 처음으로 영상을 로드할 수 있게 됐지만, 기기나 연결이 느려서 재생 단계에서 이탈했을 수 있음
그러면 이전에는 플레이어를 완전히 로드하지 못해 아무 데이터도 남지 않던 사람들이, 이제는 “영상 시청 중단” 비율을 높이는 식으로 보일 수 있음 - “로드 시간이 빨라지면 참여도가 좋아진다”가 그렇게 단순하진 않음
사용자는 대상에 따라 로딩 시간 기대치와 허용치가 다르고, 페이지와 그 안의 영상은 서로 다른 대상임
페이지 전체 로드 시간이 임베드 로드 시간에 항상 묶이는 것도 아니고, 전체 페이지 로드가 콘텐츠 로드 시간을 가릴 수도 있음
더 중요한 지표는 임베드 로드 시간이 아니라 클릭 후 재생까지의 지연일 수 있음
- Facebook이나 Uber 같은 대형 기술 회사가 최적화를 추가했더니 비슷한 결과가 나왔고, 알고 보니 이전에는 페이지조차 못 열던 새로운 시장에서 접근하기 시작했다는 글을 본 기억이 있음
-
uBlock 사용자를 위한 사용자 측 해법으로 click2load 필터를 쓸 수 있음
단, Chrome은 Manifest V3로 전환 중이라 동작하지 않을 수도 있음. yokoffing/filterlists의 필터를 참고하면 됨
https://raw.githubusercontent.com/yokoffing/filterlists/main...
Betterfox 제작자이고 GitHub에 다른 유용한 필터도 있음- Click2load는 개선이지만, 임베드는 여전히 별로임
원하는 건 그냥 평범한 링크라서, 예전에 페이지의 YouTube iframe을 링크로 바꿔 쓰는 짧은 사용자 스크립트를 만들었음
단순한 구현치고는 놀랄 만큼 잘 동작함.youtube.com/embed와youtube-nocookie.com/embediframe을 찾아watch?v=링크로 바꾸고, 타임스탬프도 유지할 수 있게 했으며, 원하면 썸네일 이미지도 붙일 수 있음
- Click2load는 개선이지만, 임베드는 여전히 별로임
-
“임베드 수가 늘수록 무게도 선형으로 늘어난다. 두 개는 2.4MB, 세 개는 3.6MB”라는 부분이 이상함
왜 이 리소스들이 캐시에서 가져와지지 않는지 궁금함. 모두www.youtube.com에서 로드된다면 동일 출처 정책상 캐시된 리소스를 쓸 수 있어야 하지 않나 싶음 -
글에서 가장 좋았던 부분은, 가벼운 페이지로 바꿨더니 평균 페이지 로드 시간이 오히려 올라갔다는 대목임
더 자세히 보니 저사양·저속 인터넷 기기 사용자까지 YouTube를 처음으로 실제 사용할 수 있게 됐고, 그들이 많이 사용하면서 평균이 느려진 것처럼 보였음
실제 사용 속도는 모두에게 상대적으로 빨라졌고, 평균 페이지 로드 속도라는 지표는 결국 의미 없는 미끼였다는 점이 인상적임 -
예전에 Firefox 확장으로 모든 YouTube 임베드를 썸네일로 바꾸고, 클릭하면 YouTube를 여는 걸 만든 적 있음
원래는 휴대폰에 Flash가 없는데 Flash 임베드가 흔해서 만들었고, 나중에는 iframe 임베드까지 처리하게 확장했음
대부분의 경우 작은 임베드 창보다 YouTube 웹사이트나 앱 전체로 여는 쪽이 사용자 경험도 더 나았음
당시 새 고수준 확장 API에 맞춰 작성했는데도 브라우저 버전 간 지원이 기대만큼 이어지지 않아 짜증 나서 WebExtension으로 옮기지는 않았음. 이 글을 보니 다시 포팅하고 싶어짐