YouTube 모바일 웹페이지에서는 동영상이 자동으로 재생된다?

2016.07.09 13:08

모바일 사파리나 크롬 모바일과 같은 모바일 브라우저에서는 동영상이 자동으로 재생되지 않습니다. autoplay 속성을 사용하거나 JavaScript 함수를 이용해서 자동으로 재생시킬 수 없습니다. 이것은 데이터 네트워크에서 사용자가 의도하지 않게 고용량의 동영상을 시청할 때 발생할 수 있는 비용을 막고자 함입니다. (참고) 결과적으로 클릭과 같은 사용자의 행동이 있어야만 동영상이 재생됩니다.


그런데 우연히 유튜브 모바일 웹에서는 자동으로 동영상이 재생된다는 이야기를 들었습니다. 저 또한 모바일 웹에서 자동으로 동영상을 재생시키려다 포기한 적이 있어 그 방법이 궁금해서 잠시 살펴봤는데, 결론은 자동으로 재생되는 것 처럼 보인다는 것입니다.


자동으로 재생되는 것처럼 보이는 이유는 유튜브 모바일 웹이 Single Page Application (SPA) 이기 때문입니다. 첫페이지에서 동영상을 클릭하면 마치 페이지가 이동하는 것처럼 보이지만 실제로는 페이지의 모습이 다른 형태로 변경되는 것을 발견했습니다. 페이지 이동이 아니니 사용자가 동영상 목록에서 특정 동영상을 클릭했을 때 페이지의 모습을 바꾸고 동영상을 바로 재생시킬 수가 있는 것입니다. 시청하던 동영상의 URL을 복사하여 새로운 탭에서 붙여 넣고 유튜브 사이트로 접근하면 동영상이 자동으로 재생하지 않는 것을 알 수 있습니다. 만약 자동재생이 가능했다면 동영상의 URL로 직접 접근하더라도 자동으로 동영상이 재생되어야 할 것입니다.


개발자 도구의 element나 network, timeline 탭을 열고 페이지를 사용해보시면 금방 확인할 수 있습니다.


nundefined ETC autoplay, Chrome, mobile, mobile safari, YouTube, 동영상, 동영상 자동재생, 모바일, 모바일 사파리, 유튜브, 자동재생, 크롬

  1. Blog Icon
    de

    자동재생 되는데요??유튜브 캐시 재거하고 사파리에서도 띄어보고 먼가 다른 방법으로 구현한거같아요

  2. Blog Icon
    de

    아모바일에서 맞네여 흐음 난감하네요 모바일에서 채팅 푸쉬 알람 소리로 구현해야하는데 ㅜ

Nginx를 reverse proxy로 사용할 때 POST 요청에서 500 에러 발생

2016.07.05 00:56

오늘 마주친 문제는 Nginx에서 reverse proxy를 설정해 application server를 연결했을 때, POST 요청을 보내면 500 에러가 발생하는 현상입니다. 요청에 따라 정상적으로 실행되기도 합니다. Nginx를 사용해 많은 개발 작업을 해봤던 분들이라면 한 번쯤 겪었을 듯 한 문제가 아닐까 하는 생각이 듭니다.


문제의 원인은 client_body_buffer_size 보다 큰 값이 post의 body로 전달됐기 때문입니다. 기본 값이 32bit에서는 8K, 64bit에서는 16K인데, 문제를 발생시켰던 요청의 body는 24K가 넘었습니다. 요청 중에 body의 크기가 7K 정도였던 것은 정상적으로 실행된 이유도 함께 알 수 있습니다.


client_body_buffer_size를 50K로 변경한 후 다시 시도하니 정상적으로 요청을 처리할 수 있었습니다.


이 방법 외에도 테스트해보지는 않았지만 client_body_temp_path 를 설정해도 문제를 해결할 수 있을 것으로 보입니다. (테스트는 해보지 않았습니다.) 이 값을 설정하면 요청의 body를 임시로 해당 위치에 저장하게 됩니다.


참고: http://shim0mura.hatenadiary.jp/entry/20120701/1341162337


nundefined ETC client_body_buffer_size, client_body_temp_path, nginx, nginx proxy post body size, reverse proxy

Web Performance Tooling 요약

2016.06.15 00:41

Web Performance Tooling의 요약입니다. 이 세션에서는 두 명이 동시에 연단에 등록하여 마치 만담을 하듯이 연기하며 성능 개선에 대한 이야기를 풀어갑니다. 종종 이런 형식을 빌려 세션을 진행하는 경우가 있는데 연기를 잘 하지는 못하지만 평범한 형식이 아니라서 개인적으로는 좋아하는 형태입니다.


- 성능은 일을 줄이는 기법이고 일을 효과적으로 진행할 수 있는 방법이다.

- 성능 개선을 진행하는 기본적인 방법

    - 사용자: 사용자가 만족하게 만드는 것이 성능 개선의 목적

    - 측정: 프로파일러를 사용. 살펴봐야 할 시간의 종류를 이해하는 것이 중요.

    - 비용의 해석: 일어나고 있는 일을 이해하는 것

    - 병목 지점의 파악: 문제가 있는 지점을 파악

    - 개선 시도

    - 재측정: 변화가 일으킨 결과를 확인


케이스 스터디


- android.com/auto

    - 3초 동안 스피너가 돈 후에 이미지가 화면에 노출되는 문제

    - 첫 추측: 이미지가 2MB가 넘을 것이며 압축을 하지 않았을 것이다.

        - 이미지는 1MB를 다운로드

        로드가 완료된 후 2초동안 네트워크로 다운로드 하는 것이 없다.

    - 코드의 해석

        - 이미지는 화면 크기에 따라 선택적으로 받고 있음.

        - cmd + shift + p 를 사용하여 devtools의 기능을 검색할 수 있는 기능을 켠 후 search를 입력하여 검색 기능을 사용

        - setInterval의 간격을 1초로 설정하여 이미지가 로드되었는지를 확인하는 코드를 발견

        - 이미지 로드 후 화면에 표시할 때까지 1초가 걸리는 코드를 발견

        - 이 두 가지 요소가 2초 동안 아무 동작을 하지 않는 이유를 설명해준다.

    - 스크롤 기능과 관련된 성능 확인

        - 어떤 인터랙션을 했는지 표시해줌

        - interactions > input events 에 표시된 붉은 줄은 사용자가 터치한 후 실제 이벤트 핸들러가 메인 스레드에서 실행될 때까지 걸린 시간을 의미


- modern-web.org

    - 로딩에 10초가 걸림

    - bottom-up

        - 메인 스레드에서 실행되는 모든 비용을 요약해서 보여줌

        - youtube 이미지와 addthis 기능이 도메인 기준으로 시간을 가장 많이 소비하는 도메인임

    - addthis의 기능을 뺐을 때를 간단히 확인해보기 위해 request blocking을 사용 (실험실 기능)

        - network 패널에서 특정한 요청을 선택한 후 오른쪽 버튼을 클릭하여 block request domain 선택

        - 개선 후 7초 이내에 로딩이 완료됨

    - 모바일은 랩탑보다 더 느릴 수 있다. 이를 위해 CPU throttling 기능이 실험실에 포함되어 있음.

    - Youtube는 iframe으로 로드된다. 유저의 관점에서 생각해보면 첫 비디오를 처음에 보고, 뒤에 나오는 비디오는 페이지 로드할 때 보지 않을 것이다. 따라서 인스턴스를 throttling해서 생성하거나  Intersection Observer 등을 사용하여 lazy loading과 같은 방법을 쓰면 될듯. 작업을 지연시키면 된다.

    - setTimeout을 이용하여 1.5초마다 youtube 플레이어를 생성한다.

    - 개선 후에는 4초 정도에서 로딩이 완료됨


- ESLint (node application의 성능 개선)

    - 파일이 수백개 정도인데 기대보다 느리다.

    - chrome devtools를 지원하는 node에서 옵션을 걸어 프로그램을 실행시키면 devtools을 사용할 수 있다.

    - Profiles에서 cpu profiles을 선택하고 실행시키면 프로그램을 실행한다.

        - 12초가 걸린다.

        - Glob.Sync 부분이 매우 크다.

        - 해당 bar를 클릭하면 source 패널로 이동하는데 소스 코드 좌측에 함수 실행 시간이 표시된다. 함수 단위 및 라인 레벨로 표시된다.

        - 원인: 26000개의 파일을 먼저 읽은 후 eslint ignore의 값으로 필터링 한 후 lint 작업을 한다. 최종적으로 lint 대상이 되는 파일은 30개.

        - 해결 방법: eslint ignore을 먼저 읽게 하고 filter object를 glob.sync에 전달하여 30개의 파일만 읽도록 함.

        - 4초 정도에 실행이 완료.

    - 이런 작업은 pull request로 프로그램에 반영하면 좋겠다.

        - https://github.com/eslint/eslint/pull/6215



이 동영상의 주요 내용은 데모를 이용하여 설명하므로 꼭 동영상을 직접 확인하시기 바랍니다. 



nundefined ETC cpu throttling, devtools, google io, google io 2016, intersection observer, lazy loading, Performance, request blocking, 성능, 성능개선, 퍼포먼스

High performance web user interfaces 요약

2016.06.07 00:50

Google I/O 2016에서 웹쪽 주제로는 첫 번째 세션이었던 High performance web user interfaces 를 요악합니다.


- Progressive Web Apps

    - 여러 기능을 사용하기 위해서는 HTTPS가 필요

        - push messaging, offline 혹은 좋지 않은 접속 상태 (by service worker)

- 사용자는 native app처럼 생긴 앱은 native app 처럼 동작하기를 기대한다.

    - 동작(behaves)은 두 가지로 나뉜다. - performance, interaction

- Performance

    - RAIL

        - 퍼포먼스를 고려할 때 사용자를 중심에 두고 생각하는 모델

        - Response (0.1 sec), Animation (16ms), Idle (50ms), Load (1 sec)

        - 현실에서 중요도는 L > A > R > I 로 생각된다.

        - Add to homescreen에서 실행되거나 PWA에서는 중요도가 R = A > I > L 라고 생각.

            - add to homescreen에서 실행되는 경우에는 service worker가 기본으로 설정되어 있어야 하기 때문

            - SW에서 오프라인이거나 연결상태가 좋지 않을 경우 로딩을 컨트롤 할 수 있다.

            - 매일 실행하는 앱에서는 스크롤이 잘 되거나, 반응성이 좋거나 하는 것이 더 중요하다.

            - App이 아니라 site의 경우에도 user interface의 반응성이 좋은 것은 중요


- Three components의 성능을 높이는 사례를 볼 것임

    - sidenav, dismissable card, expanding and collapsing view

- sidenav

    - pointer-events: none;

        - 미리 준비되어 있어야 하고 언제든 동작 가능해야 하는데 사용자가 클릭하자마자 동작해야 하므로 렌더트리 내에 포함되어 있어야 한다. 그렇지 않다면 렌더트리에 포함될 때 layout, styles, painting 이 트리거 된 후에야 움직일 수 있다. 따라서 hidden 되어 있지 않고 렌더트리에 포함되어 있으려면 모든 엘리먼트의 최상단에 있어야 하는데 그렇게 되면 다른 엘리먼트를 클릭할 수 없다. 따라서 pointer-events를 none으로 설정하면 클릭이 아래에 깔린 엘리먼트로 넘어가게 된다. 화면에 노출될 때는 auto로 변경

    - sidenav가 자체의 composite layer를 갖도록 한다.

        - composite layer: 페이지의 특정한 부분을 페이지의 다른 부분과 분리하는 것

        - will-change: transform; 사용 (예전에는 translateZ(0) 사용)

        - 필요한 곳에만 쓸 것. 메모리 과다 사용 문제, compositing에 걸리는 시간 최소화.

    - 터치로 sidenav를 움직일 경우 document에 이벤트 처리를 위임한다.

        - requestAnimationFrame 사용

        - touchmove 이벤트 핸들러에서 event.preventDefault()를 사용한다.

            - 기본적으로 크롬에서는 touchmove 이벤트를 발생시키는 회수를 줄인다. 손가락으로 가리키는 모든 이벤트를 받고자 한다면 preventDefault()를 사용해야 함.

    - Supercharged 동영상 http://bit.ly/side-nav

- swipeable cards

    - this.onStart = this.onStart.bind(this);

        - prototype을 instance로 복사하면서 현재 instance와 바인딩한다.

        - 호출하면 항상 현재 instance를 참조하고 addEventLister에서 this.onStart으로 등록/제거가 가능

    - onStart에서 style.willChange를 지정해서 별도 레이어로 분리 (필요할 때만 분리한다는 점이 중요)

    - 손쉬운 easing 패턴

        - value += (target - value) / strength

    - Supercharged 동영상 http://bit.ly/swipeable-cards

- Expand and Collapse

    - 이건 좀 어려운데 width, height, top, left를 변경하면 매 프레임마다 layout 트리거 되고 paint도 트리거됨

        - layout은 dom size에 비례하여 시간이 증가

    - transform을 쓰면 layout만 트리거 할 수 있다. (그래서 발표자가 좋아함) (참고: 크롬에서만..)

    - FLIP 방법을 적용

        - First, Last, Invert, Play

        - First: 초기 상태의 position을 얻는다. (getBoundingClientRect)

        - Last: 애니메이션을 마지막 프레임으로 옮겨간다. 그리고 마지막 상태의 position을 얻는다. (getBoundingClientRect)

        - Last로 갈 때 layout, style이 강제로 트리거 된다. Layout은 나쁜데 이렇게 해도 괜찮은가?

            - 단 한 번만 layout함. RAIL의 도움을 얻을 수 있다. 

        - Invert: Last에서 First로 되돌리는 값을 얻어 transform 시킨다. 그리고 transform에 transition을 설정.

        - Play: transform = 'none' 으로 설정하면 카드가 늘어나게 된다.

        - FLIP 주의점

            - scales은 자식 엘리먼트를 변경시킨다. 형제 엘리먼트를 고려해야 할지도

            - first 에서 last로 가는 과정은 layout과 style을 발생시키므로 조심해야 함

        - 성능에 덜 민감하고 Responsive Web Design에도 유용

- 렌더링 퍼포먼스에 대해 알고 싶다면

    - http://bit.ly/render-perf

- 데모에 나온 UI를 더 자세히 살펴보고 싶다면

    - http://bit.ly/supercharged-ui



이 동영상에는 코드에 대한 설명이 많아 모든 내용을 요약하지는 않았습니다. 보다 상세한 내용이 궁금한 분은 동영상을 확인하기 바랍니다.

nundefined ETC expand and collapse, Flip, google io, google io 2016, https, progressive web app, pwa, Rail, requestAnimationFrame, side navigation, sidenav, supercharged ui, swipeable, swipeable cards, Transform, Transition

DevTools in 2016: Accelerate your workflow 요약

2016.06.06 01:13

DevTools에 새롭게 추가된 기능에 대한 세션입니다.


- 새로운 기능은 chrome canary 버전에서 chrome://flags 에서 Enable Developer Tools experiments를 활성화해야 사용할 수 있음

- Authoring

    - Device mode

        - Mobile first를 먼저 하길 권장. 이에 맞춰 개선했음

        - responsive design을 쉽게 확인하도록 다양한 사이즈를 쉽게 선택해서 볼 수 있음

        - 디바이스 회전 아이콘을 클릭하면 키보드 노출 화면도 확인 가능

        - settings - show the device frame 을 선택하면 기기의 프레임을 보여줌. 

        - 스크린샷 촬영 가능

        - 기기를 추가할 수 있고

        - device pixel ratio 지정 가능

        - network throttling 설정 가능. 네트워크 패널에 있는 것과 동일

        - 줌 레벨을 낮추면 4K 모니터에서도 어떻게 보이는지 확인 가능

        - 랩탑의 디바이스 타입 설정 가능 (터치 유무)

        - show media queries를 선택하면 media query에 지정된 너비를 선택해서 볼 수 있음

    - color

        - css variable 사용 가능

        - 클래스를 설정해서 클래스 선택에 따라 스타일이 달라지는 모습을 확인할 수 있음

    - animation

        - 새로운 bezier curve editor

        - animation inspector

    - devtools의 기능을 쉽게 찾고 싶을 때

        - sublime text edtor에서 처럼 command + shift + p 를 누르고 키워드를 입력해서 기능을 쉽게 찾을 수 있음

- 새로운 기능

    - source diff - element에서 변경하면 소스코드에서 변경된 부분을 표시해줌

    - quick source - source와 동일. element에서 style tab에 해당하는 부분을 동시에 보여줌

    - css source map을 on 하면 scss 원본 파일과 연결해줌. 이 상태에서 수정해도 반영됨.

        - 변수에 지정된 값을 변경 가능

        - 저장하면 원본 파일도 같이 변경됨. 파일을 변경해도 스타일 반영됨.

- application

    - resources 패널이 변경됨

    - manifest를 시각적으로 표현

    - service worker 를 다양하게 테스트 가능

    - sw에서 생성하는 로그의 색을 변경하는 데모 보여줌

    - clear storage

- lighthouse

    - progressive web app을 만들기 위한 체크리스트 역할을 하는 프로젝트

- DevTools에 node.js를 디버깅할 수 있는 기능 추가 


이 세션의 후반부인 Application 패널부터는 Great libraries and tools for great Progressive Web Apps 의 후반부와 내용이 같습니다. Node.js 프로그램을 DevTools에서 디버깅하는 데모도 동일합니다. 둘 중 하나의 영상만 봐도 충분합니다. 다만 Application 패널에 대한 설명은 service worker pane에 대한 데모가 추가되어 있는 이 동영상이 더 낫습니다. 나머지는 거의 비슷하니 두 개 중 하나만 보셔도 충분할 것입니다.



잘못된 부분이 있을 수 있으니, 꼭 원본 동영상을 참고하시기 바랍니다.









nundefined ETC Animation, application, Canary, Chrome, device mode, devtools, google io, google io 2016, LIGHTHOUSE, node.js, service worker, 서비스 워커, 크롬