LHJ

I'm a FE developer.

gulp-imagemin 이미지 최적화 속도를 높이는 방법

15 Oct 2020 » node_module

gulp-imagemin 이미지 최적화 속도를 높이는 방법

이슈

export const optimize_imgs = () => {
    return src([
        `${config.src}/img/**/*.{png,jpg,svg,gif}`,
        `!${config.src}/img/sprites/**/*`,
        `!${config.src}/img/sprites-svg/**/*`
    ], {since: lastRun(optimize_imgs)})
        .pipe(imagemin([
            imagemin.gifsicle({interlaced: true}),
            imagemin.mozjpeg({quality: 75, progressive: true}),
            imagemin.optipng({optimizationLevel: 5}),
            imagemin.svgo({
                plugins: [
                    {removeViewBox: true},
                    {cleanupIDs: false}
                ]
            })
        ], {
            verbose: true
        }))
        .pipe(dest(`${config.dist}/img/`))
}

위와 같이 gulp-imagemin으로 각 이미지파일들을 최적화할 때 since lastRun으로 마지막으로 변형된 시간을 체크해 변형된 파일만 최적화하도록 하면 이슈가 한가지 발생합니다.
바로 새로 추가된 이미지는 인식을 못하는 문제입니다.
그 이유는 since lastRun이 파일의 mtime 값을 사용하기 때문이라고 합니다. (참고링크)
mtime이란 파일이 마지막으로 수정된 시간을 나타내는 timestamp입니다. (참고링크)
복사 붙여넣기로 새로 추가된 파일엔 lastRun 이 반환한 이전 mtime 값이 없기 때문에 인식을 못하는 것이라고 합니다.

때문에 이를 해결하기 위해선 다른 라이브러리를 활용해야됩니다.

해결방법 gulp-newer

export const optimize_imgs = () => {
    return src([
        `${config.src}/img/**/*.{png,jpg,svg,gif}`,
        `!${config.src}/img/sprites/**/*`,
        `!${config.src}/img/sprites-svg/**/*`
    ])
        .pipe(newer(`${config.dist}/img/`))
        .pipe(imagemin([
            imagemin.gifsicle({interlaced: true}),
            imagemin.mozjpeg({quality: 75, progressive: true}),
            imagemin.optipng({optimizationLevel: 5}),
            imagemin.svgo({
                plugins: [
                    {removeViewBox: true},
                    {cleanupIDs: false}
                ]
            })
        ], {
            verbose: true
        }))
        .pipe(dest(`${config.dist}/img/`))
}

위와 같이 since lastRun 옵션을 빼고, gulp-newer 라이브러리를 통해서 새로운 이미지 또는 변형된 이미지를 인식하게 하면 됩니다.

주의할 점

export const clean_imgs= () => {
    return del(`${config.dist}/img`)
};

export const gulpWatch = () => {
    watch(`${config.src}/img/**/*`, series(clean_imgs, parallel(optimize_imgs, spriteSvg, sprites), sass, browserSyncReload));
}

src 폴더와 dist 폴더의 씽크를 완벽하게 맞추기 위해 watch 함수에서 img의 변화가 감지될 때마다 clean_imgs란 함수로 dist 폴더에 나가있는 img 폴더를 지우고 다시 최적화 함수를 실행했습니다.
하지만 이렇게하면 gulp-newer 또는 since:lastRun 을 쓰는 의미가 아예 없어지게 됩니다.
gulp-newersince:lastRun 은 처리된 파일들은 건들지 않게해 걸프의 컴파일 속도를 끌어올리는 기능을 하는 라이브러리, 옵션입니다.
그런데 watch 함수로 변화를 감지할 때마다 dist/img 폴더를 삭제하면 since: lastRun일 경우 변화된 이미지 파일만 나가기 때문에 dist/img 폴더에 변화된 파일을 제외한 파일은 모두 삭제되는 결과를 나을 것입니다.
gulp-newer일 경우 dist/img 폴더가 아예 삭제되었으므로 src/img 폴더에 있는 파일들을 전체 다시 내보냅니다.
그러면서 gulp-imagemin 라이브러리가 다시한번 전체 이미지파일을 최적화합니다. (gulp-newer을 쓰는 의미X, 그리고 컴파일 시간 오래걸림)

결론 및 정리

  1. image 폴더를 watch 함수로 감시할 땐 dist의 img폴더를 삭제하지않는 것이 좋습니다.
  2. since: lastRun 옵션이 아닌 gulp-newer 라이브러리를 사용하면 변경 또는 추가된 이미지만 최적화해 컴파일 속도가 빨라집니다.
  3. 단, 그렇게되면 src 폴더에서 삭제된 이미지 파일이 dist 폴더엔 계속 남아있으므로 gulp build를 해 씽크를 맞춰줍니다. (build 함수엔 dist 폴더를 삭제하는 함수가 들어있습니다.)

느낀점

회사 걸프엔 이와 같은 방식으로 적용되어있습니다.
gulp-newer 라이브러리를 몇달전에 추가하셨던 것 같은데 그 이유가 이거인줄은 몰랐습니다.
(하지만 회사 걸프는 아직 watch 함수에 image 폴더 삭제 코드가 들어가 있더라구요. 이점은 개선해야될 부분일듯합니다.)