웹팩 설정을 마치고 프로젝트를 진행하다가 문제가 하나 생겼습니다.
개발 모드에서는 이미지가 로드되었는데 빌드된 파일에서는 이미지 로드가 되지 않는 문제가 있었죠..
빌드된 html에서..🙄
실제로 빌드된 폴더에서 image 자체가 없었습니다..헉..💀
이미지가 로드되지 않은 이유는 웹팩에서 이미지를 로드시켜주는 로더인 file-loader
를 설정하지 않아서였습니다. 그래서 다음 명령어로 file-loader
와 url-loader
를 설치하였습니다.
yarn add -D file-loader url-loader
? 갑자기 url-loader
는 뭔데?
url-loader
는 작은 이미지 파일을 url 인코딩 문자열로 지정이됩니다. 그래서 추가적인 HTTP 요청이 필요하지 않아서 초기 로딩 속도가 개선이 된다는 장점이 있습니다.
무거운 파일은 file-loader로 이미지를 처리하고, 가벼운 파일은 url-loader로 처리하여 최적화한 세팅을 진행해야합니다.
그 이유는 크게 3가지가 있다고 합니다.
번들 크기 증가
: 큰 이미지 파일을 데이터 URL로 인라인하는 경우, 해당 이미지는 번들에 직접 포함되어 번들 크기를 크게 증가시키며 커진 번들로 인해 초기 로딩시간이 늘어나게 됩니다.브라우저 캐시
: 데이터 URL로 인라인된 이미지는 브라우저 캐시에 저장되지 않습니다. 따라서 페이지를 새로 고칠 때마다 이미지를 다시 로드해야합니다..😥 그래서 작은 파일만 url-loader
를 사용합니다.메모리 사용 증가
: 데이터 URL로 인라인된 이미지는 javascript
문자열로 처리되므로, 해당 이미지를 화면에 표시할 때 메모리 사용이 증가됩니다.전부 file-loader
로 로드시키는 방법도 좋지 않은 방법입니다.
초기 로딩 속도 지연
: 모든 이미지를 별도의 파일로 분리하면, 초기 로딩 시간이 증가합니다. 브라우저는 별도의 이미지를 HTTP 요청으로 다운로드해야 하기 때문입니다.요청 용량 초과
: 브라우저는 동시에 처리할 수 있는 HTTP 요청의 수에 대한 제한이 있습니다. 보통의 브라우저에서는 동일한 도메인에 대해 약 6~8개의 동시 요청을 처리할 수 있습니다. 이러한 이유로 요청 용량이 초과하면 브라우저가 뚝뚝 끊기는 듯한 현상이 나타납니다.그렇다면 결국 file-loader
와 url-loader
두 가지를 사용해야 웹 페이지 로딩 속도를 개선할 수 있다는 것입니다! 가장 좋은 방법은 이미지 크기를 압축
하고 다양한 이미지 파일을 Sprite Image
로 처리하면 성능 개선에 매우매우 좋다고합니다.
어떻게 하면 두 가지 로더를 잘 사용할 수 있을까 했더니, loader 옵션 중에, limit
옵션이 있었습니다.
어째튼..! webpack.config.js
의 모듈 규칙에 다음과 같이 추가해주세요.
module: {
rules: [
// 기본 설정들..(babel-loader, ts-loader 등)
{
test: /\.(jpg|jpeg|gif|png|svg|ico)?$/,
use: [
{
loader: "url-loader",
options: {
limit: 10000,
fallback: "file-loader",
name: "image/[name].[ext]"
}
}
]
}
]
},
limit: 10000
: 파일 크기가 10,000Byte(10KB) 미만인 경우, 파일을 인코딩 문자열
로 변환합니다.
fallback: "file-loader"
: 파일 크기가 설정 크기를 초과할 경우, file-loader
를 사용합니다.
name: "image/[name].[ext]"
: 출력될 파일의 경로와 이름을 설정합니다. 여기서는 image 폴더 내에 원본 파일 이름과 확장자를 사용합니다.
더 다양한 설정은 웹팩의 file-loader와 url-loader를 참고해주세요
이제 다시 빌드를 하여 빌드된 html을 열어보았더니..!
이미지가 정상적으로 출력되었습니다..!!👏👏
추가로 개발자 모드를 열어서 확인을 해보니 react 로고인 logo.192.png
파일은 10KB 이하로 처리되어 url-loader
가 사용된 모습..! 굿굿굿~
url-loader
로 이미지가 처리되어서 빌드된 폴더 안에 제가 설정했던 image
폴더가 생성되지 않았습니다.🤗
이미지와 같은 이유로 파비콘이 출력되지 않는다..😥
webpack.config.js
plugins: [
new webpack.ProvidePlugin({
React: "react"
}),
new HtmlWebpackPlugin({
template: "./public/index.html",
favicon: "./public/favicon/favicon.ico",
minify:
process.env.NODE_ENV === "production"
? {
collapseWhitespace: true,
removeComments: true
}
: false
}),
new CleanWebpackPlugin()
]
위와 같이 HtmlWebpackPlugin
에 favicon
을 설정해주면 됩니다.
그럼 끝!..하지만 디바이스별로 파비콘을 알맞게 설정하려면 다른 설정을 해주어야합니다.
아래 명령어로 favicons-webpack-plugin
패키지를 설치해야합니다.
yarn add -D favicons-webpack-plugin
webpack.config.js
new FaviconsWebpackPlugin({
logo: './public/favicon/favicon.ico',
manifest: './public/manifest.json'
}),
플러그인 설정해주는 곳에 FaviconsWebpackPlugin
을 셋팅해줍니다. favicon
과 manifest
를 설정해줍니다. HtmlWebpackPlugin
에서 favicon을 설정해주었다면 제거해줘야합니다.
파비콘이 제대로 출력되는 모습!