-
[핀더펜] 성능 최적화 마지막개발 프로젝트: 핀더펜 2024. 5. 14. 00:08728x90
1. Avoids enomous network payloads
페이지에서 요청한 모든 리소스의 총 크기를 보여주며, 1600KiB 밑으로 만드는 것을 목표로 해야한다.
@font-face { font-family: 'Pretendard'; font-weight: 700; font-display: swap; src: local('Pretendard Bold'), url(./assets/font/woff2-subset/Pretendard-Bold.subset.woff2) format('woff2'); } @font-face { font-family: 'Pretendard'; font-weight: 600; font-display: swap; src: local('Pretendard SemiBold'), url(./assets/font/woff2-subset/Pretendard-SemiBold.subset.woff2) format('woff2'); } @font-face { font-family: 'Pretendard'; font-weight: 500; font-display: swap; src: local('Pretendard Medium'), url(./assets/font/woff2-subset/Pretendard-Medium.subset.woff2) format('woff2'); } @font-face { font-family: 'Pretendard'; font-weight: 400; font-display: swap; src: local('Pretendard Regular'), url(./assets/font/woff2-subset/Pretendard-Regular.subset.woff2) format('woff2'); } @font-face { font-family: 'Pretendard'; font-weight: 300; font-display: swap; src: local('Pretendard Light'), url(./assets/font/woff2-subset/Pretendard-Light.subset.woff2) format('woff2'); }
woff2 파일을 서브셋 woff2 파일로 교체했다. 그 결과 payload 크기를 1600Kib 밑으로 줄일 수 있었습니다.
서브셋은 화면이 로드될 때 필요한 글자에 대한 폰트를 우선적으로 로드하기 때문에 로드속도를 줄일 수 있습니다.
+) 2024/05/30 FOUC 문제 해결을 위해 font-display 속성 swap에서 block으로 변경
2. Eliminate render-blocking resources
페이지의 첫 번째 페인트를 차단하는 모든 URL을 나타낸다. 해결 방법은 index.html 파일에서 css 파일을 로드할 때 media="print"와 같은 속성을 부여해야한다고 한다. 해당 파일의 경우 빌드하는 과정에서 index.html 파일에 적용되기 때문에 vite의 build 옵션을 찾아보았다.
https://ko.vitejs.dev/guide/features.html#css-code-splitting
위 링크 페이지를 읽어본 결과 vite의 자동 최적화로 인해 css 파일이 자동으로 번들로 쪼개지고 청크를 불러올 때 css 계산이 완료된 후 청크가 렌더링되도록 한다고 한다. FOUC를 회피하기 위해 적용된 것이라고 한다.
결론은 해결할 수 없는건가..
+) 2024/05/30 문제 해결
vite.config.ts파일에 커스텀 플러그인을 구현해서 해결했다.
function addPreloadToCSS(): Plugin { return { name: "add-preload-to-css", enforce: "post", apply: "build", generateBundle(_, bundle) { const htmlFileName = Object.keys(bundle).find((name) => name.endsWith(".html") ); if (htmlFileName) { const htmlFile = bundle[htmlFileName] as { source: string }; let html = htmlFile.source; // Modify the HTML to add preload to CSS link html = html.replace( `rel="stylesheet"`, `rel="preload" as="style" onload="this.onload=null;this.rel='stylesheet'"` ); htmlFile.source = html; } }, }; }
vite에서 모듈을 참조할 때 자동으로 rel="modulepreload"를 추가해주는 것을 보고 css에도 추가해주고 싶었다. 그 방법을 build 옵션에 있을 것이라고 생각해서 build 옵션 관련 문서만 읽느라 시간을 보냈다. 그런데 해결 방법은 커스텀 플러그인을 생성하는 것이었다.
rel="stylesheet"라고 되어있는 곳을 `el="preload" as="style" onload="this.onload=null;this.rel='stylesheet'"라고 치환해 css 파일을 prelaod하여 reder blocking이 일어나지 않도록 해결했다.
그 과정에서 2개의 css 파일 참조 태그에 모두 적용하고 싶었는데 왜인지 replaceAll이 적용되지 않아서 build options에 ㅊcssCodeSplit을 false로 지정해 css 번들을 분리하지 않고 하나로 빌드하도록 설정해주었다.
(vite는 빌드 최적화를 위해서 자동으로 css 를 분리한다고 한다.)
// vite.config.ts export default defineConfig({ plugins: [react(), tsconfigPaths(), addPreloadToCSS()], css: {}, base: "/fin-the-pen-web/", server: { proxy: { "/local": { target: "http://localhost:8080", changeOrigin: true, rewrite: (path) => path.replace(/^\/local/, ""), }, }, }, build: { rollupOptions: { output: { manualChunks: (id) => { if (id.includes("node_modules")) { const module = id.split("node_modules/").pop().split("/")[0]; return `vendor/${module}`; } }, }, }, cssMinify: "esbuild", cssCodeSplit: false, }, });
3. Largest Contentful Paint element
이미지 파일을 로딩하는데 시간이 걸리는 것을 파악되었다. 그래서 svg 이미지 파일을 최적화할 수 있는 방법을 찾아보았다.
현재 화면에서 사용되고 있는 이미지 파일을 매번 화면이 로딩될 때마다 새롭게 http 요청이 들어가 이미지 호출 횟수가 많아지는 문제가 있는 상황이다. 이것을 해결하기 위해 svg 스프라이트를 적용해볼 계획이다.
이미지 스프라이트란?
하나의 이미지 파일에 페이지에서 사용할 여러가지 이미지들을 넣어 좌표와 범위를 통해 특정 이미지를 불러오는 기법으로 한번의 이미지 로딩을 통해 여러가지 이미지를 불러올 수 있어 이미지 호출 횟수를 줄일 수 있다.이미지 스프라이트 결과
성능적으로 크게 향상된 부분은 없지만 파일의 수가 줄어들어서 그런지 빌드 속도가 단축됐다는 점에서 만족스럽다.
(21s -> 12s)
+) 더이상 아이콘 이미지가 LCP가 아니게 되었지만 여전히 LCP로 인해 10초 정도의 딜레이가 발생하고 있다. Render Delay가 97%를 차지하고 있어서 원인을 찾아보고는 있지만 쉽지가 않다. 진지하게 SSR을 고려해봐야하나 생각이 든다.
728x90'개발 프로젝트: 핀더펜' 카테고리의 다른 글
[핀더펜] Vitest 적용하기 (0) 2024.06.04 [핀더펜] 이미지 스프라이트 적용 (1) 2024.06.03 [핀더펜] 성능 최적화 (0) 2024.05.04 [핀더펜] 성능 최적화 - 접근성 검사 (0) 2024.04.30 [핀더펜] 성능 최적화 - 성능검사(FCP) (0) 2024.04.30