# .env
REACT_APP_VERSION=0.0.0-${TURBO_HASH}
REACT_APP_VERSION을 자동으로 입력할 방법을 찾다가 결국 hash값을 추가했다.
yarn add -D react-app-rewired customize-cra
// package.json
"scripts": {
"start": "react-app-rewired start",
"build": "react-app-rewired build",
"test": "react-app-rewired test"
},
// .babelrc
{
"plugins": [
["@babel/plugin-proposal-decorators", { "version": "legacy" }],
["@babel/plugin-proposal-class-properties", { "loose": true }]
]
}
// config-overrides.js
const { useBabelRc, override } = require('customize-cra')
module.exports = override(useBabelRc())
CRACO로 구성하는게 지금은 맞는 것 같다.
interface PaginationProps {
/** 현재 페이지 번호 */
currentPage: number;
/** 전체 페이지 수 */
totalPages: number;
/** 페이지 변경 시 호출되는 콜백 함수 */
onPageChange: (pageNumber: number) => void;
/** 이전/다음 페이지 링크 표시 여부 (선택적) */
showPreviousNext?: boolean;
/** 페이지 번호 링크 표시 여부 (선택적) */
showPageNumbers?: boolean;
/** 페이지당 항목 수 (선택적) */
pageSize?: number;
}
- cbcruk/react-flat-pagination
- mayankshubham/react-pagination
- react-component/pagination
- wwwaiser/react-js-pagination
- material-ui/react-pagination/
- Pagination - NuxtLabs UI
- AdeleD/react-paginate
하지만 너무 많은 기능이 필요없기 때문에 최대한 단순한 컴포넌트를 만들었다.
Core Web Vitals & Performance Metrics
- Web Vitals
- Largest Contentful Paint (LCP)
- Optimize Largest Contentful Paint
- Largest Contentful Paint(최대 콘텐츠풀 페인트, LCP)
- Interaction to Next Paint(INP)
LCP 최적화
- AddyOsmani.com - Preload late-discovered Hero images faster
- How to improve the performance of your hero images - MeasureWorks
- Hack your PageSpeed LCP metric by enlarging your hero image | Erwin Hofman
- Optimising images for better LCP web vitals scores | by Javier Villanueva | ITNEXT
- Improve Largest Contentful Paint (LCP) With A JS + CSS Trick - Propel Digital Media Solutions
- Get a perfect Largest Contentful Paint (LCP) time with a single line of code - DevisedLabs
이미지 및 리소스 로딩 최적화
- The Humble
<img />Element And Core Web Vitals — Smashing Magazine - Preload, prefetch and other
<link />tags: what they do and when to use them · PerfPerfPerf - Optimizing resource loading with Priority Hints
- 향후 탐색 속도를 높이기 위해 리소스 미리 가져오기 | web.dev
- 즉각적인 페이지 탐색을 위해 Chrome에서 페이지 사전 렌더링 | Chrome for Developers
- Speculation Rules API - Web APIs | MDN
- https://csswizardry.com/2024/12/a-layered-approach-to-speculation-rules/
- https://blog.cloudflare.com/ko-kr/introducing-speed-brain/
사이트 속도 및 성능 최적화
- Fast load times
- Efficiently load third-party JavaScript
- How to Stop Lighthouse Complaining About Render Blocking Google Fonts | Codeboosh
- How To Leverage Browser Caching to Improve Site Speed | DebugBear
CSS 기반 성능 최적화
- Improving rendering performance with CSS content-visibility | Read the Tea Leaves
- CSS content-visibility for React devs - DEV Community
서드파티 스크립트 및 자원 관리
- Best practices for using third-party embeds
- Optimize loading third-parties
- A Next.js package for managing third-party libraries | Chrome for Developers
- Building a Faster Web Experience with the postTask Scheduler | by Callie | The Airbnb Tech Blog | Medium
Partytown 및 서드파티 스크립트 성능 개선
- Welcome To Partytown
- How we cut 99% of our JavaScript with Qwik + Partytown
- Introducing Partytown 🎉: Run Third-Party Scripts From a Web Worker - DEV Community
케이스 스터디: 웹 성능 개선 사례
- How We Improved Our Core Web Vitals (Case Study) — Smashing Magazine
- Case study: Analyzing Notion app performance · PerfPerfPerf
- A Netflix Web Performance Case Study | by Addy Osmani | Dev Channel | Medium
- React Performance Fixes on Airbnb Listing Pages | by Joe Lencioni | The Airbnb Tech Blog | Medium
- How We Improved SmashingMag Performance — Smashing Magazine
- Instagram 성능 개선 사례
메모리 및 성능 이슈 해결
MobX 비동기 action 처리 - action은 현재 스택에만 적용됨. await/then 이후 상태 변경은 별도 action 필요.
// ❌ then 콜백은 action 범위 밖
@action fetchProjects() {
fetchSomething().then(projects => {
this.data = projects // 에러!
})
}
// ✅ 방법 1: runInAction
@action async fetchProjects() {
const data = await fetchSomething()
runInAction(() => {
this.data = data
})
}
// ✅ 방법 2: flow (권장) - await 대신 yield
fetchProjects = flow(function* () {
this.state = "pending"
try {
this.data = yield fetchSomething() // 자동으로 action 래핑
this.state = "done"
} catch (e) {
this.state = "error"
}
})
flow는 async/await와 동일하게 작동하면서 수동 action 래핑 불필요. 취소도 가능 (cancel()).
- 프로젝트에 새롭고 반짝이는 기술보다는 지루한 기술을 선택하는 것이 좋습니다.
- 흥미로운 기술은 프로젝트에 불필요한 위험을 초래할 수 있습니다.
- 이미 확립되고 입증된 기술이 성공적인 결과로 이어질 가능성이 더 높습니다.
- 신기술을 둘러싼 과대 광고는 오해의 소지가 있습니다.
- 신기술의 수명을 예측하기는 어렵습니다.
- 지루한 기술은 화려하지 않을 수 있지만 안정적이고 신뢰할 수 있으며 예측 가능합니다.
- 최신 기술 유행보다는 비즈니스 문제 해결에 집중하세요.
- 사람과 프로세스에 투자하면 더 나은 결과를 얻을 수 있습니다.
- 지루한 기술을 선택하는 것은 보수적이거나 위험을 피하기 위한 것이 아니라 프로젝트의 장기적인 성공을 우선시하는 정보에 입각한 결정을 내리기 위한 것입니다.
Footnotes
-
항상 최신의 최첨단 솔루션을 쫓기보다는 확립되고 신뢰할 수 있는 기술을 사용하는 것을 지지하는 글. 특히 장기 프로젝트의 경우 기술 선택에서 안정성과 예측 가능성의 중요성을 강조. ↩
Footnotes
BDD는 무엇을 의미합니까?
BDD는 시스템의 원하는 동작을 협력적으로 지정하는 접근 방식입니다. 행동의 일부가 합의될 때마다 우리는 그 행동을 구현할 코드의 개발을 “추진”하기 위해 해당 사양을 사용합니다.
BDD의 세 가지 관행은 무엇이며 스토리에 어떤 순서로 적용합니까?
우리는 스토리에 필요한 행동의 범위를 공동으로 발견 하는 것으로 시작합니다. 일단 우리가 행동에 동의하면 우리는 비즈니스가 읽을 수 있는 언어로 사양을 공식화 합니다. 마지막으로 공식화된 사양을 자동화 하여 시스템이 실제로 예상대로 작동하는지 확인합니다.
Cucumber와 BDD는 어떤 관련이 있습니까?
Cucumber는 문서를 이해하고 자동화된 테스트로 변환하는 도구입니다.
BDD는 세 가지 방식으로 구성된 협업적 접근 방식입니다. BDD 실무자는 Cucumber를 사용하여 문서를 자동화할 수 있습니다.
“살아있는 문서”의 특별한 점은 무엇입니까?
문서가 애플리케이션의 동작과 동기화되지 않을 때 자동으로 알려 주기 때문에 “살아있는 문서”라고 부릅니다. 그것이 특별한 점입니다.
완료에 대한 정의의 일부로 이를 검토할 수 있지만 자동으로 유효성이 검사되지 않더라도 작성한 모든 사양 문서에 대해서도 마찬가지입니다.
그것은 자동화된 테스트에 의해 생성 되지 않습니다 - 여전히 작성해야 합니다! 자동화된 테스트는 귀하가 작성한 내용이 사실인지 아닌지를 알려줍니다.
이를 위한 변경 제어 프로세스가 있을 수 있습니다. 설명하는 코드와 함께 소스 제어에 유지하는 것이 좋습니다. 그러나 다시 말해서 특별한 것은 아닙니다. Word 문서에 대해 놀랍도록 투명한 변경 제어 프로세스를 가질 수 있지만 여전히 완전히 구식이고 잘못된 것일 수 있습니다.
커스텀 폰트 사용 시, 배포 중 Provided Edge Function is too large 에러가 발생할 경우 로컬 파일로 사용하지말고 fetch로 해당 폰트를 가져온다.12