-
이미지 처리에 대한 고찰 - 어렵다, 나만 그런건가? Gatsby와 함께!Web Dev/5. Projects 2021. 3. 2. 23:45728x90
이미지를 처리하는 방법을 고민하게 된 이유
css파일은 네이버같이 큰 회사도 파일의 사이즈가 이미지 하나정도밖에 되지 않는다고하고, 많은 사람들이 페이지가 느리거나 트래픽이 문제가 되는건 대부분 이미지때문일거라고 해서 이미지를 어떻게 처리해야하는건지 고민하게 되었다.
그리고 HTTP 요청관련해서 img는 그냥 img태그만 넣어도 브라우저가 알아서 요청을 받아오고 그러는데, img request할때 헤더는 어떻게 처리가 되는건지? 하는 것도 모르겠고 response에 cache관련 설정을 할 수 있다는데 대체 뭐지...? 하는 복잡한 생각이 들었다.
그리고 반응형으로 페이지를 만들어야하는데 이미지는 텍스트처럼 fluid하지가 않아서 크기도 좀 이상하고 그래서 img 관련해서 좀 딥다이브 해보기로 했다.(이미지 처리가 어려운 이유는 텍스트(naturally fluid)의 경우는 넘치면 알아서 넘어가지만 이미지는 그렇지 않기 떄문이다)
대체 이미지, 얘를 어쩌면 좋을까....
Gatsby의 gatsby-plugin-sharp 플러그인과 Responsive Images
Gatsby의 플러그인 중에서 gatsby-plugin-sharp를 쓰면 내가 가진 이미지를 여러 사이즈로 알아서 프로세싱을 해준다.
이 플러그인을 통해서 많은 것들을 할 수 있는 것 같은데, 나는 fluid 속성을 이용하고 있다. [참고]
Create fluid sizes (in width) for the image. If the max width of the container for the rendered markdown file is 800px, the sizes would then be: 200px, 400px, 800px, 1200px, 1600px – enough to provide close to the optimal image size for every device size / screen resolution.Fluid 속성에 관한 설명을 보면 max-width(default가 800px)가 800px이면 200px, 400px, 800px, 1200px, 1600px 사이즈 이미지를 생성해준다. 그리고 그에 맞춰서 srcset과 sizes도 생성해준다.
그럼 이제 이미지는 다 생성된거고, 이미지 크기에 대해서는 srcSetBreakpoints: [ 200, 340, 520, 890 ] 이런식으로 옵션을 줄수도 있다. 중요한건 여기서 srcset과 sizes 속성에 대해서 내가 모른다는 거다.
이제 srcset과 sizes를 알아보자.
Responsive Images란?
웹사이트는 요새 크기가 아주 난리다. 내가 이해하려고 하는 두가지 속성은 1. srcset , 2. sizes 이다.
Responsive Images의 개념은 - 여러 스크린 사이즈 해상도 및 각종 피쳐에도 잘 동작하는 이미지를 말한다. HTML은 responsive image를 지원하기 위해서 여러것들을 지원하고 있다.
근데 이거 왜 필요할까?
데스크탑에서 웹사이트를 방문하면 이미지가 짱 커도 된다. (max-width, min-width)
이때 화면을 줄이면 max-width나 width, min-width 등의 속성으로 처리해도 되지만, 근데 문제가 되는게 모바일만큼 쪼만한데서 데스크탑이미지를 작게작게 줄여서 viewport의 100%로 맞추면 넘 쪼꼬매서 뵈는게 없어지는 문제가 생길지도 모른다.
해결방법은 어떤 사이즈보다 작을때는 잘린 버전의 사진이든 뭐든 쪼만한데서도 뭐하는건지 보이는 사진을 보여주게 하는 것이다. 그리고 또한 쪼만한 화면에서 큰 사진을 부르지 않도록도 해야한다. 왜냐하면 쓸데없이 큰사이즈 사진을 부르면 괜히 트래픽만 증가하는 것이다. 근데 이거외에 작은 화면이라도 해상도가 다 다르고, 큰화면도 해상도가 다다르고 아주 난리다.
웹이 처음에 등장했을땐 이런 문제가 없었는데, 이제는 뭐 기기도 엄청 많고 해상도도 다르고 아주 난리라, 브라우저 개발자들이 이제는 해결법을 생각해낸거같다.
Responsive image technologies were implemented recently to solve the problems indicated above by letting you offer the browser several image files, either all showing the same thing but containing different numbers of pixels (resolution switching), or different images suitable for different space allocations (art direction).
Responsive images가 해결한건 그래서 즉, Resolution switching 과 art direction 문제이다.
Resolution switching
1. Different Sizes대비하기: srcset과 sizes로
이제 이미지는 아래처럼 표현할 수 있다.
<img srcset="elva-fairy-480w.jpg 480w, elva-fairy-800w.jpg 800w" sizes="(max-width: 600px) 480px, 800px" src="elva-fairy-800w.jpg" alt="Elva dressed as a fairy">
srcset은 브라우저가 어떤이미지를 선택할지목록을 주는거다.
sizes는 미디어 컨디션을 준다(스크린 너비같은). 이걸 통해서 해당 미디어 컨디션에서 어떤 이미지를 선택하면 좋을지를 알려준다
그래서 전체적인 흐름은 아래와 같다.
- 디바이스의 크기를 본다.
- sizes 내의 미디어 컨디션을 보고 해당하는 첫번째를 가져온다(이건 무조건 px 값이다.)
- srcset에서 해당하는 이미지를 가져온다.
2. 해상도 대비:
이건 srcset에
<img srcset="elva-fairy-320w.jpg, elva-fairy-480w.jpg 1.5x, elva-fairy-640w.jpg 2x" src="elva-fairy-640w.jpg" alt="Elva dressed as a fairy">
이렇게 표현하는 거다.
Art direction
developer.mozilla.org/en-US/docs/Learn/HTML/Multimedia_and_embedding/Responsive_images#art_direction
이건 읽어보자. picture태그를 사용하는거랑 위에 srceset과 구체적으로 어떻게 다른건진 잘모르겠는데, 코드를 보면 아래와 같다.
<picture> <source media="(max-width: 799px)" srcset="elva-480w-close-portrait.jpg"> <source media="(min-width: 800px)" srcset="elva-800w.jpg"> <img src="elva-800w.jpg" alt="Chris standing up holding his daughter Elva"> </picture>
이렇게보면 media size에 대해서 더 구체적으로 지정할 수 있다는게 장점인걸까? [참고자료]
여기서 요약한 글을 보면 srcset은 resolution switching 문제를 해결하고 picture 는 art-direction을 해결하는데, 이게 더 정제된 것이다.
그래서 이제 Gatsby에서 적용하는 방법은?
Gatsby는 데이터를 Graphql로 가져온다. 그래서 image sharp plugin으로 생성된 여러가지 사이즈의 이미지의 srcset, sizes를 쿼리로 가져온다.
const AboutPage = () => { const data = useStaticQuery(graphql` { utilsJson { about { how_to_come map how_to_come_alt } } allFile(filter: { relativePath: { eq: "route-to-gomtang.jpeg" } }) { nodes { childImageSharp { fluid { srcSet src sizes } } } } } `); return ( <Layout> <AboutLayout> <ImgWrapper> <Typography variant="h5"> {data.utilsJson.about.how_to_come} </Typography> <img srcSet={data.allFile.nodes[0]["childImageSharp"]["fluid"]["srcSet"]} sizes="(max-width: 200px) 180px, (max-width: 400px) 250px, (max-width: 800px) 450px, 600px" src={data.allFile.nodes[0]["childImageSharp"]["fluid"]["src"]} alt={data.utilsJson.about.how_to_come_alt} /> </ImgWrapper> <ImgWrapper> <Typography variant="h5">{data.utilsJson.about.map}</Typography> <img srcSet={data.allFile.nodes[0]["childImageSharp"]["fluid"]["srcSet"]} sizes="(max-width: 200px) 180px, (max-width: 400px) 250px, (max-width: 800px) 450px, 600px" src={data.allFile.nodes[0]["childImageSharp"]["fluid"]["src"]} alt={data.utilsJson.about.how_to_come_alt} /> </ImgWrapper> </AboutLayout> </Layout> ); };
이런식으로 graphql로 srcSet과 sizes의 값을 가져온다음 모든것은 이제 Gatsby에 맡기면 된다!
브라우저는 이미지 캐슁처리를 어떻게 하고 있는가?
현재 내가 개발한 사이트는 이미지가 샘플로 들어있긴한데, 초기에 로드하면 200이지만 그다음부터는 304 not modified응답을 받는다.
"The HTTP 304 Not Modified client redirection response code indicates that there is no need to retransmit the requested resources. It is an implicit redirection to a cached resource. This happens when the request method is safe, like a GET or a HEAD request, or when the request is conditional and uses a If-None-Match or a If-Modified-Since header."
초기에 Response헤더가 localhost의 경우에는 Cache-control: public, max-age=0 이런데, netlify의 경우에는 resource를 다르게 관리하는 것 같다.
img 태그 자체의 request 헤더는 바꿀수가 없다.
나는 request할때도 헤더를 바꿀수있는건가? 싶었는데 아니라고 한다. 브라우저가 알아서 한다고 한다.
stackoverflow.com/questions/27000152/set-custom-header-for-the-request-made-from-img-tag
서버에서 응답을 보낼때 cache 관련 헤더도 같이 포함이 된다.
Netlify의 경우 cache-control을 어떻게 하는지 이문서를 보고 파악했다.
“max-age=0, must-revalidate, public” = “please cache this content, and then do not trust your cache”. This seems a bit counterintuitive, but there’s a good reason. This favors you as a content creator — you can change any of your content in an instant. Let a broken page out in a deploy? Roll back instantly. Want to make sure that your new marketing site all goes out — text, code, and assets — at the same instant so your visitors don’t experience the dreaded new/old mixture that old, file-at-a-time deploy methods left you with? We’re ready!
얘는 리소스에 “max-age=0, must-revalidate, public” 이렇게 한다. 이렇게 함으로써 이컨텐츠를 캐슁하되 계속 검사는 하라고 정책을 하고 있다고 한다.
이렇기때문에 내가 컨텐츠를 바꿀때까진 계속 이런식으로 나 캐쉬있는데~ 확인해볼께~ 한다음 바꼈으면 바뀐걸 받아온다. 근데 게다가 gatsby 가 알아서 이미지에 해쉬코드같은걸 붙여서 이미지가 변경되면 새로운 리소스를 요청할 수 있도록 관리하고 있다.
후기
생각보다 브라우저가 더 많은 일들을 하고 있었다. 캐슁같은것도 지가 알아서 거의 하고, 이미지 관련해서도 html 로 제공하는 기능이 많다. 다 잘 사용하는 것이 어렵겠지만 앞으로 잘 응용해봐야겠다.
참고자료
developer.mozilla.org/en-US/docs/Learn/HTML/Multimedia_and_embedding/Responsive_images
www.usefulparadigm.com/2014/11/03/processing-images-on-responsive-web/
thenewcode.com/586/CSS-Fluid-Image-Techniques-for-Responsive-Site-Design
Caching: medium.com/@codebyamir/a-web-developers-guide-to-browser-caching-cc41f3b73e7c
www.gatsbyjs.com/docs/caching/
www.gatsbyjs.com/plugins/gatsby-plugin-netlify/
developer.mozilla.org/en-US/docs/Web/HTTP/Caching
superuser.com/questions/1316540/where-has-chrome-cache-been-moved-to
'Web Dev > 5. Projects' 카테고리의 다른 글