관리 메뉴

취미개발 블로그와 마음수양

Http와 스프링 (1) : Encoding - Brotli 본문

개발관련 잡다/HTTP

Http와 스프링 (1) : Encoding - Brotli

아라한사 2019. 11. 4. 01:15

 

목차

https://adunhansa.tistory.com/261

 

http와 스프링(0) - 연재를 시작하며..

운 좋게, 좋은 스터디원분들과 좋은 책을 만나 HTTP 스터디를 시작하며 다음의 연재글을 시작해보려고 합니다. 목차 http와 스프링 뒤적뒤적 연재 시리즈~ --- 1편 - Encoding - Brotli 적용해보기 https://adunha..

adunhansa.tistory.com


 

요즘 BackToBasic - HTTP 스터디를 다니고 있는데 이런저런 옵션들을 한번 스프링에 적용해보고 싶었단 말이지?

 


0 . 소개 

2015년에 나온 압축기술인데

 

https://blog.naver.com/kgj1/220622925193

 

머.. 아무튼..  성능은 이정도로 Gzip 보다 더 작은 파일이 나온다고 하더라 ?

 

https://merj.com/blog/case-study-improve-page-speed-with-minification-and-compression

 

Case study: Improve Page Speed with Minification & Compression

Looking to improve page load speed? We show how minification and Brotli can reduce file transfer sizes by 90% and why it's important to statically compress them.

merj.com

 

브라우저 request 헤더요청에서 다음과 같이 보내게되면 난 brotli 로 힙하게(2015년에 나왔지만) 받을 수 있어~라고 전달한다고 한다. 크롬에서는 사실 뭐 당연히 받는 인코딩방법이랄까

 

 

흠... 그리하야.. 그냥저냥 연습해보는 브랜치 하나 생성후.. 쪼~금 연습해보았다.

 

1단계 EncodedResourceResolver 의 등록

 

second 프로젝트에 있고..

 

GzipResourceResolver 를 넣으려고 하니, Deprecated 되었다고한다.

 

그래서 대신에 EncodedResourceResolver를 넣으라고 하는데... 뭐.. 자바로 대충 만들어서 로그 좀 찍어가면서 기능을 익혔다. 

 

EncodedResourceResolver는 5.1부터 나온건가..  스프링 소스 설명 잠시 읽고

 

 

baeldung 따라 만든 연습용 설정이심.

 

 

2단계  프론트파일의 준비

그리고 css 파일을 대충 만들고 브로틀리 압축을 시켜야 한다. 

여기와서 대충 가져옴

https://www.npmjs.com/package/brotli

 

const path = require("path");
const fs = require('fs');
const compress = require('brotli/compress');
var brotli = require('brotli');

const brotliSettings = {
    extension: 'br',
    skipLarger: true,
    mode: 1, // 0 = generic, 1 = text, 2 = font (WOFF2)
    quality: 10, // 0 - 11,
    lgwin: 12 // default
};

fs.readdirSync('./css').forEach(file => {
    if (file.endsWith('.js') || file.endsWith('.css') || file.endsWith('.html')) {
        const buffer = fs.readFileSync(path.resolve(__dirname, './css/' + file))
        const result = brotli.compress(buffer, brotliSettings);
        fs.writeFileSync('./css/' + file + '.br', result);
    }
});

맨처음에 압축한 브로틀리 파일이 자꾸 null 떠서 뭔가 했더니 파일이 너무 작아서 null 떳던 것.. 

 

뭐.. 연습용으로 폴더도 대충대충^^

 

자..이제 웹페이지에 접속해보면..

브로틀리 인코딩으로 응답이 내려옴을 볼 수 있다. 

 

 

 

실제 코드로 찾는 과정은 여기..흠.. 

protected Resource resolveResourceInternal(@Nullable HttpServletRequest request, String requestPath,
                                               List<? extends Resource> locations, ResourceResolverChain chain) {
        logger.info("resolve Resource Internal : " + request + " , locations : "+locations + " ,  requestPath : "+requestPath);
        Resource resource = chain.resolveResource(request, requestPath, locations);
        logger.info("resource : "+ resource);
        if (resource == null || request == null) {
            return resource;
        }

        String acceptEncoding = getAcceptEncoding(request);
        logger.info("accept Encoding : "+ acceptEncoding);
        if (acceptEncoding == null) {
            return resource;
        }

        for (String coding : this.contentCodings) {
            logger.info("coding : "+coding);
            if (acceptEncoding.contains(coding)) {
                try {
                    logger.info("acceptEncoding :"+acceptEncoding +", with coding :"+coding);
                    String extension = getExtension(coding);
                    logger.info("extension :"+extension);
                    Resource encoded = new CustomEncodedResourceResolver.EncodedResource(resource, coding, extension);
                    logger.info("encoded :"+encoded+", exists():"+encoded.exists());
                    if (encoded.exists()) {
                        return encoded;
                    }
                }
                catch (IOException ex) {
                    if (logger.isTraceEnabled()) {
                        logger.trace("No " + coding + " resource for [" + resource.getFilename() + "]", ex);
                    }
                }
            }
        }
        return resource;
    }

 

 

 


참고했던 링크들 (글 잘 정리된 한글 블로그가 잇엇는데 링크가 보이질 않는다 ㅠ ) 

- https://www.baeldung.com/spring-mvc-static-resources

 

Serve Static Resources with Spring | Baeldung

How to map and handle static resources with Spring MVC - use the simple configuration, then the 3.1 more flexible one and finally the new 4.1 resource resolvers.

www.baeldung.com

- https://www.slideshare.net/arawnkr/resource-handling-in-spring-mvc

 

Resource Handling in Spring MVC

Adied 2014, 봄싹 세미나에서 발표한 `Resource Handling in Spring MVC`의 발표자료입니다. 주요 내용으로 Spring MVC에서 정적 자원(css, js, etc)을 다루는 방법을 다루고 있습니다. 데모 코드 : https://github.com/ara…

www.slideshare.net

 

연습깃헙 :

 

https://github.com/arahansa/learn_http_with_spring

 

다음의 책을 보면서 스프링 예제코드를 찾아보았습니다 . 리얼월드 HTTP 도서 입니다.

 

https://www.aladin.co.kr/shop/wproduct.aspx?ItemId=187943894

 

리얼월드 HTTP

HTTP가 발전한 여정을 더듬으면서, 브라우저 내부에서 어떤 일이 일어나는지 그리고 서버와 어떻게 상호작용하는지 등을 다룬다. 메서드와 경로, 헤더, 바디, 스테이터스 코드 같은 HTTP 기본을 충실하게 설명한다.

www.aladin.co.kr