전에 HTTP/2 Server Push 사용하기(https://yiunsr.tistory.com/852)  라는 글을 적은 적 있다. 이 때 나는 Nginx 의 http2_push 만을 이용한 방법을 이야기 했다.
 우선 http2 server push 는 html 페이지가 전달될 때, 해당 html 페이지에서 사용하는 css, js, img 등을 같이 한 번에 보내는 방법이다. http2_push 의 경우는 nginx 설정에 들어가기 때문에 고정적인 asset 만 가능하다. (HTTP/2 Server Push 사용하기(https://yiunsr.tistory.com/852)  를 참고할 것) 그런데 이번에 알게된 http2_push_preload 의 경우 flask 에서 Reponse 하는 Header 에 따라서 동적으로 nginx 에게 http2 sesrver push 리소스를 알려줄 수 있다. 이렇게 하면 nginx 에서 알아서 해당 리소스를 같이 http2 server push 해서 보내가 된다. 
내 경우 Flask-Assets 이라는 것을 이용해서 js, css 파일을 번들링해서 하는 파일이름에 hash된 이름이 들어간다.  (app_common.js?7a0733ee 이런 식으로 파일의 hash 가 생성되어 추가된다. ). 이 때마다 nginx 설정을 변경하는 것은 너무 불편하다. 이런 것을 자동으로 구현 할 수 있게 된다. 
예를 flask 만을 들었는데, django 의 경우도 가능할 것 같다. reponse header 를 수정할 수 있는 모든 플러그인은 가능할 것 같다. (그래서 PHP 같은 것도 가능할 것 같다. ) 

 사용하기 위해서는 nginx  에서 설정하는 방법은 아래와 같이 on 시키면 된다. 

location  = / {
        include uwsgi_params;
        uwsgi_pass .............
        ............
        http2_push_preload on;
        ............
    }


 여기서 중요한 것은 Flask 서버쪽에서도 설정이 필요하다. 일반적으로 Request Header 를 이용하는 경우는 있어도 Response Header 를 이용하는 경우는 거의 없을 것이다. 크롬 DevTools 을 통해 네트워크를 보면 Response Header도  볼 수있다. 

이 Response Header 에 link 키에 </static/js/script.js>; rel=preload; as=script    같은 것을 넣어주면 된다. 이러면 Nginx 가 자동으로 html 전달되는 동안 /app/script.js 파일도 같이 전달한다. css 의 경우 </static/css/common.css>; as=style; rel=preload 같은 형태로 넣으면 된다. 2개 이상일 경우 이것을 ,(콤마) 로 구별해서 넣을 수 있다. </static/js/script.js>; rel=preload; as=script,</static/css/common.css>; as=style; rel=preload   당연히 이 경로는 해당도메인/static/js/script.js 가 접근가능하도록 설정되어 있어야 한다. 

Flask 에서는 Reponse Header 는 https://stackoverflow.com/a/25860353/6652082  에서 나타난 것처럼 할 수도 있고 https://stackoverflow.com/a/63691704/6652082 에서 처럼 return 할 때 지정할 수도 있다. 
대략 아래와 같은 형태가 될 것이다. 

from flask import make_response

@main.route('/', methods=['GET'])
def index():
    resp = make_response(render_template('main/index.html'))
    resp.headers["link"] = "</static/js/script.js>; rel=preload; as=script,</static/css/common.css>; as=style; rel=preload"
    return resp

 

당연히 HTML 코드는 아래 처럼 되어 있을 것이다. 

<html>
    <link href="/static/css/common.css" rel="stylesheet">
    <body>
        Hello, World
    	<script src="/static/js/script.js"></script>
    </body>

</html>

만약 HTTP/2 를 지원하지 않는다면  기존과 같이 HTML 을 랜더링 할 때 common.css, script.js 파일을 서버로 요청할게 될 것이다. 



여기에 더 나가서 cookies 를 잘 이용하면 이미 해당 리소스가 있는 경우(최근에 해당 페이지에 접근해서 리소스를 받은 경우) http2 server push 가 필요없는 경우 굳이 보내지 않도록 설정할 수도 있다. 내 경우에는 Flask-Assets 때문에 좀 더 고민을 해봐야 한다. 어느정도 코드가 정리되면 올리도록 하겠다. 

 

회사에서 외주 퍼블리시 한 HTML 코드를 보다보니, 화가 났다. 내 기준에으로 코드가 너무 엉망이었다. 수정이 쉽도록 CSS 를 통해서 grid 를 사용할 수 있도록 해주어야 하는데, 그렇게 되어 있지 않았다. (처음부터 이것을 분명히 짚고 넘어갔지만 가격때문에 강하게 주장할 수 없었다. 사실 이런 것을 원하면 전문 업체에게 요청하는게 맞다. )
 CSS를 잘 이용하면 javascript 없이 구현 가능한 코드인데 이 코드를 js 로 구현했다. checkbox 와 radio 형식의 버튼을 자바스크립트 onclick 이벤트시 class 를 추가하는 방식으로 구현하고 있었다. 이 코드는 아무리봐도 css checkbox 를 이용하면 될 것 같아서 구현해 보았다. 

https://jsfiddle.net/nahanmil/bkqj7x4c/11/



IE 11 에서도 정상적으로 동작한다. 

 외부 서비스를 이용해서 홈페이지를 만들었는데, 기본 템플릿으로 만들어진 사이트가 IE11 에서만 엄청 느리게 동작하는 현상이 있었다. 고민하다가 Edge 로 동작시키는 방법이 있지 않을까 하고 열심히 찾았다. 그러다 
stackoverflow.com/a/65258124 이런 글을 보았다.

주소에  microsoft-edge:google.com 이런 식으로 주소를 이동시키면 Edge 가 있는 경우 Edge 브라우저를 강제로 열 수가 있다. chrome 에서도 된다. 아래와 같은 팝업이 뜬다.

IE11 에서는 위와 같은 창이 없이 그대로 뜬다. 
IE11 일 때 edge 로 이동시키고 싶으면 아래와 같은 자바스크립트를 삽입하면 동작한다. 

<script>
if(navigator.userAgent.indexOf('MSIE')!==-1
|| navigator.appVersion.indexOf('Trident/') > -1){
    window.location.href = 'microsoft-edge:' + window.location.href;
}
</script>

IE11 일 때만 Edge 를 강제로 열어서 현재 주소로 이동시킨다. 다만 Edge 가 없는 환경일 때는 문제가 발생한다. 자바스크립트만으로는 Edge 브라우저가 있는지 없는지 알 수 없다. 그러나 IE11 사용자부터가 소수이고, windows 7은 이미 기술지원이 완료되었기 때문에 IE11 사용자의 컴퓨터 환경에 Edge 브라우저가 있다고 생각된다.  때문에 이렇게 사용하면 더 많은 사용자를 고려할 수 있을 거라 판단된다. 

예전에는 IE6 이 없어져야 한다고 생각했는데, 이제는 IE11 이다. IE11 때문에 개발하기 너무 힘들다.