Repository navigation
๐ fix: contact ์บ๋ฒ์ค ์คํ์คํฌ๋ฆฐ ๋ฏธ์ ์ง ์์ + ์บ์ ์ฌ๋ง์ดํธ ํ์ - #100
Conversation
RenderWhenVisible์ด ์ดํ ์ setFrameloop('never')๋ฅผ ๋ช
๋ นํ์ผ๋ก ํธ์ถํ์ง๋ง,
R3F <Canvas>์ configure๊ฐ deps ์๋ layout effect๋ผ ๋งค ๋ฆฌ๋ ๋๋ง๋ค frameloop
prop(๊ธฐ๋ณธ๊ฐ 'always')์ ์คํ ์ด์ ์ฌ์ ์ฉํด ๊ณง๋ฐ๋ก ๋ฎ์ด์ผ๋ค. ๊ณ์ธก์ผ๋ก
IntersectionObserverยท๊ฐ์์ฑ ๋ก์ง์ ์ ์์ด๊ณ ๋ฆฌ๋ ๋๊ฐ ์์ธ์์ ํ์ธํ๋ค
(์คํ์คํฌ๋ฆฐ์์ resize ํ ๋ฒ์ neverโalways ์ฌํ).
๊ฐ์์ฑ์ React state๋ก ์ฌ๋ ค <Canvas frameloop={visible?'always':'never'}>๋ก
์ ์ดํ๋ค. prop์ด ์ง์ค์ด๋ฏ๋ก ๋ฆฌ๋ ๋๊ฐ ๋๋ ์๋ํ ๊ฐ์ด ์ ์ง๋๋ค.
RenderWhenVisible ์ปดํฌ๋ํธ๋ฅผ useCanvasVisibilityFrameloop ํ
์ผ๋ก ๋ฐ๊พธ๊ณ
heroยทcontact ์บ๋ฒ์ค๊ฐ onCreated์ gl.domElement๋ก ๊ตฌ๋
ํ๋ค.
hero๋ ์ด ํ์ด์ง์์ ํญ์ ๋ถ๋ถ ๋
ธ์ถ์ด๋ผ ์ ยทํ ๋ชจ๋ always๋ก ์ ์ ๋์ํ๋ค.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
#97 ํ์์ผ๋ก sourceScene ๋์ผ์ฑ๋ง์ผ๋ก ์บ์๋ฅผ ํ์ ํ๋ ๊ฒ ๋ผ์ฐํธ ์ด๋ ํ ์ฌ๋ง์ดํธ์์ ์์ ํ์ง ํ์ธํ๊ณ , ๊ฒฐ๋ก ์ "๋ฌธ์ ์์"์ด๋ค. drei useGLTF ์บ์๊ฐ URL ๋จ์๋ก scene ๊ฐ์ฒด๋ฅผ ์ ์งํ๊ณ ๋ ํฌ ์ด๋์๋ clear/disposeํ์ง ์์ผ๋ฏ๋ก, client-side ์๋ณต์๋ ๊ฐ์ scene์ด ๋์์ ์ธ์คํด์คยทmixer๊ฐ ๊ทธ๋๋ก ์ฌ์ฌ์ฉ๋๋ค(ํด๋ก ยทmixer ์ฌ์์ฑ ์์). ์ค์ธก์ผ๋ก๋ SPA ๋ผ์ฐํธ ์๋ณต ํ ์ ๋๋ฉ์ด์ ์ด ์ ์ ์ฌ๊ฐ๋จ์ ํ์ธํ๋ค. ๊ฐ์ด ๋ฐ๋๋ ๊ฒฝ์ฐ๋ .vN ๊ฒฝ๋ก ๋ณ๊ฒฝยทuseGLTF.clear๋ฟ์ด๊ณ ๋ ๋ค ์ ์ฒด ๋ฆฌ๋ก๋๋ผ ์ค๋๋ ํด๋ก ์ด ๋จ์ ๋์๋ ๊ฒฝ๋ก๊ฐ ์๋ค. ๋ค์ ์ฌ๋์ด ๊ฐ์ ์์ฌ์ ๋ฐ๋ณตํ์ง ์๋๋ก ํ์ ๊ทผ๊ฑฐ๋ฅผ ์ฃผ์์ผ๋ก ๋จ๊ธฐ๊ณ , ๊ฐ์ ๊ณ์ฝ์ ํ ์คํธ๋ก ๊ณ ์ ํ๋ค โ ๊ฐ์ scene ์ฌ๋ง์ดํธ๋ ์ฌ์ฌ์ฉ, ๋ค๋ฅธ scene์ ์ฌ์์ฑ. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Warning Review limit reachedNext included review available in 51 minutes. View limit detailsLimit details: Youโve used the included review currently available. You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Review configuration: โ๏ธ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Team Run ID: ๐ Files selected for processing (10)
โจ Finishing Touches๐ Generate docstrings
๐งช Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
๐ก Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 081f4dfebd
โน๏ธ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with ๐.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
๋ ๋ ๋ฃจํ ๋๋ฒ๊น ์ ๋ธ๋ก๊ทธ ์ํฐํด๋ก ์ ๋ฆฌํ๋ฉฐ ๋ง๋ ์ ์ฐจ๋ฅผ ์ฌ์ฌ์ฉ ๊ฐ๋ฅํ ์คํฌ๋ก ๋จ๊ธด๋ค. ๊ธฐ์กด ๋ฐํ ๊ธ์ ๋ฌธ์ฒด ๋จ์ผ ์ถ์ฒ๋ก ์ผ์ ์กด๋๋ง ํ๊ณ ํคยทTL;DRยท ์ง๋ฌธํ ์์ ๋ชฉยทbefore/after ์ยท๊ตํ ์ถ์ํ ๊ฒฐ๋ง์ ๊ฐ์ ํ๊ณ , ์ฑ๋ฅยทํ์ด๋ฐ ๋ฒ๊ทธ์ ์ /ํ๋ฅผ ์ค์ธก ์คํฌ๋ฆฐ์ท์ผ๋ก ๋ง๋๋ ์บก์ฒ ์ํฌํ๋ก(before/after ๋น๋ + GPU ๋ธ๋ผ์ฐ์ HUD ์ค๋ฒ๋ ์ด + ์คํฌ๋ฆฐ์ท)๋ฅผ references๋ก ๋ถ๋ฆฌํ๋ค. headless ์ํํธ์จ์ด ๋ ๋๋ง์ด ํ๋ ์๋ ์ดํธ๋ฅผ ๋ญ๊ฐ๋ ํจ์ ๋ ๋ช ์ํ๋ค. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
๋ชฉ์
PR #97์ด ํ์์ผ๋ก ๋ถ๋ฆฌํ 2๊ฑด์ ์ ๋ฆฌํ๋ค.
(1) contact ์บ๋ฒ์ค๊ฐ ํ ๋ฒ ๋ ธ์ถ๋ ๋ค ํ๋ฉด ๋ฐ์ผ๋ก ๋๊ฐ๋ ๊ณ์ ๋ ๋๋๋ค.
RenderWhenVisible์ดsetFrameloop('never')๋ฅผ ๋ช ๋ นํ์ผ๋ก ํธ์ถํ์ง๋ง, R3F<Canvas>๊ฐ ๋ฆฌ๋ ๋๋ง๋คframeloopprop(๊ธฐ๋ณธ๊ฐ'always')์ ์คํ ์ด์ ์ฌ์ ์ฉํด ๊ทธ ํธ์ถ์ ๊ณง๋ฐ๋ก ๋ฎ์ด์ผ๋ค. (2)characterInstanceCache์ฑ๊ธํด์ดsourceScene๋์ผ์ฑ๋ง์ผ๋ก ์บ์๋ฅผ ํ์ ํ๋ ๊ฒ ๋ผ์ฐํธ ์ด๋ ํ ์ฌ๋ง์ดํธ์์ ์์ ํ์ง ํ์ธ โ ๊ฒฐ๋ก ์ ๋ฌธ์ ์์, ๊ทผ๊ฑฐ๋ฅผ ์ฃผ์ยทํ ์คํธ๋ก ๋จ๊ฒผ๋ค.useFrame/์ด)setFrameloop<Canvas frameloop>์ ์ด propconfigure๊ฐ'always'๋ก ๋๋๋ฆผ์ ์ฉ ๋ฒ์:
use-render-when-visible.ts(์ปดํฌ๋ํธโํ ), hero/contact ์บ๋ฒ์ค 2๊ณณ์ ๋ฐฐ์ ,use-character-instance.ts์ฃผ์. ์ ๋๋ฉ์ด์ ยท์ ํ ๋ก์งยท์์ ์ ๊ฑด๋๋ฆฌ์ง ์์๋ค.์ค๊ณ
1. ์์ธ์ด IO root๊ฐ ์๋๋ผ
<Canvas frameloop>์ฌ์ ์ฉ์์ ๊ณ์ธก์ผ๋ก ์ขํ๋ค๊ณผ์ ์ ์ ๋ ฅ ํ๋ณด๋ "IO์
root๊ฐ ๊ธฐ๋ณธ๊ฐ(window)์ด๋ผ ์ค์ ์คํฌ๋กค ๋ฃจํธ([data-app-scroll-viewport])๋ฅผ ๋ชป ๋ฐ๋ผ๊ฐ๋ค"์๋ค. ํ๋ก๋์ ๋น๋ + GPU Chromium(M3 Pro) ๊ณ์ธก์ผ๋ก ๋ฐ์ฆํ๋ค.root=nullยทroot=์ฑ๋ทฐํฌํธ๋ ์ต์ ๋ฒ ๋ถ์ฐฉ, ์คํฌ๋กค in/outisIntersecting:false์ ํ ๋ฐํ โ IO๋ ๋ฌด์ฃRenderWhenVisible์ ๋ก๊ทธ ์ฃผ์setFrameloop('never')ํธ์ถ๋จ, contact ์ค์ ๋ก ๋ฉ์ถค(tโ60ms)always๋ก ๋ณต๊ท(RWV ํธ์ถ ์์). ์คํ์คํฌ๋ฆฐ์์resize1๋ฐ โneverโalways์ฌํR3F 9.5.0 ์์ค์์ ํ์ :
์ด ๋ฉ์ปค๋์ฆ์ "ํ ๋ฒ๋ ๋ ธ์ถ ์ ๋๋ฉด 0ํ/์ด"๋ ์ค๋ช ํ๋ค โ ์ ๋ณด์ด๋ ๋์ ์คํฌ๋กค์ด ์์ผ๋ฉด Canvas ๋ฆฌ๋ ๋๊ฐ ์์ด
never๊ฐ ์ ์ง๋๊ณ , ํ ๋ฒ ๋ณด์ด๋ ค๊ณ ์คํฌ๋กคํ๋ ์๊ฐ ๋ฆฌ๋ ๋๊ฐ ๋ค๋ฐ๋ก ๋ ํด๋ก๋ฒ๋๋ค.2. ์ controlled
frameloopprop์ธ๊ฐframeloopprop์ด R3F์ ์ง์ค์ด๋ผ, ์ํ๋ ๊ฐ์ prop์ผ๋ก ์ ์ดํ๋ฉด ๋ฆฌ๋ ๋๊ฐ ๋๋ ๊ทธ ๊ฐ์ด ์ฌ์ ์ฉ๋ผ ์ ์ง๋๋ค.๋ฒ๋ฆฐ ๋์
root๋ฅผ ์ฑ ์คํฌ๋กค ๋ทฐํฌํธ๋ก ๋ณ๊ฒฝ'never'์ฌ-assertconfigure๊ฐ'always'๋ก ์ธํ โ ์ฐ๋ฆฌ๊ฐ'never'๋ก ๋๋๋ฆฌ๋ ํํ. ํ๋ ์ ๋์๋ ์์ง๋ง ํ๋ ์์ํฌ์ ์ธ์ฐ๊ณ ํ๋จ ์ฃผ์ฒด๊ฐ ๋์ด ๋๋คframeloop="demand"3. resume ์ ๋ช ์์
invalidate()๋ฅผ ๋์ง ์์๋ค'never'โ'always'๋ณต๊ท ์, hero๊ฐ ์ด ํ์ด์ง์์ ํญ์always๋ผ ์ ์ญ rAF ๋ฃจํ๊ฐ ๋ฉ์ถ์ง ์์ผ๋ฏ๋ก ๋ค์ ํ๋ ์์ contact๊ฐ ์๋ ๋ ๋๋๋ค(์ค์ธก ํ์ธ). ์ด ๋ ์บ๋ฒ์ค๋ ํ ๋ผ์ฐํธ์๋ง ์กด์ฌํ๋ฏ๋ก hero๊ฐ ๋ฃจํ๋ฅผ ์ด๋ ค๋๋ ์ ์ ๊ฐ ํญ์ ์ฑ๋ฆฝํ๋ค. ์ ์ญinvalidate()๋ ๋ชจ๋ root๋ฅผ ๋ฌดํจํํด ๊ณผํ๋ฏ๋ก ๋์ง ์์๋ค.Changes
eb78ae5081f4dfRenderWhenVisible์ปดํฌ๋ํธ โuseCanvasVisibilityFrameloop(canvasElement)ํ . IO +visibilitychangeํ๋จ์ ๊ทธ๋๋ก, ๋ฐํ๋ง'always' | 'never'.onCreated์gl.domElement๋ฅผ state๋ก ์ก์ ํ ์ ๋๊ธฐ๊ณframeloopprop์ผ๋ก ์๋น. (hero๋ ์ด๋ฏธcanvasElementstate๊ฐ ์์ด ์ฌ์ฌ์ฉ.)getOrCreateCharacterCache์sourceSceneํค๊ฐ ์ฌ๋ง์ดํธ์ ์์ ํ ๊ทผ๊ฑฐ ์ฃผ์ + ๊ณ์ฝ ํ ์คํธ 2๊ฑด.์๋์ ์ผ๋ก ์ ๋ฐ๊พผ ๊ฒ
MIXER_MAX_DELTA_SECONDS์ํcharacterInstanceCache์ฑ๊ธํด ๊ตฌ์กฐ๋ฆฌ๋ทฐ ํฌ์ธํธ
<Canvas>configure๊ฐ ๋งค ๋ ๋frameloop์ ์ฌ์ ์ฉํ๋ค๋ ์ ์ (์ค๊ณ 1) โ ์ด๊ฒ ํ๋ฆฌ๋ฉด ์ง๋จ์ด ๋ฌด๋์ง๋ค. ์ค์น๋@react-three/fiber@9.5.0์ deps ์๋ layout effect +configure์frameloop๊ธฐ๋ณธ๊ฐ'always'๊ฐ ๊ทผ๊ฑฐ๋ค.<Canvas>๋ ๊ทธ ๊ฐ์ ๋ฐ๊ธฐ๋ง ํ๋ค.sourceScene๋์ผ์ฑ์ด ์ณ์ ํค๋ผ๋ ๊ทผ๊ฑฐ(drei useGLTF URL ์บ์๊ฐ ์ธ๋ง์ดํธ๋ก ์ ๋น์์ง)์ ๊ณ์ฝ ํ ์คํธ.Test plan
pnpm run check-typesโ ํต๊ณผpnpm run lintโ ํต๊ณผpnpm run test:vitestโ ์ ๋ฒํท ํต๊ณผ (์ ๊ท:useCanvasVisibilityFrameloop7๊ฑด, ์บ์ ๊ณ์ฝ 2๊ฑด)์ค์ธก ์ /ํ โ ํ๋ก๋์ ๋น๋ + GPU Chromium(M3 Pro), 1600ร1100,
/ko.useFrame/์ด ๊ณ์ธก:hero(main)๋ ์ ยทํ ๋ชจ๋ ํญ์ running(ํญ์ ๋ถ๋ถ ๋ ธ์ถ์ด๋ผ ์ ์). ์ฝ์ ์๋ฌ 0.
SPA ๋ผ์ฐํธ ์๋ณต(client-side) ํ ์ ๋๋ฉ์ด์ ์ ์ ์ฌ๊ฐ + ์บ์ ์ฑ๊ธํด ์ ์ง ํ์ธ (์บ์ ํ์ ๊ทผ๊ฑฐ)
ํญ ๋ฐฑ๊ทธ๋ผ์ด๋/๋ณต๊ท ๋ผ์ด๋ธ ๊ณ์ธก โ ๋ฏธ์คํ. ๊ตฌ๋ Chromium์ด
document.visibilityState์ฌ์ ์๋ฅผ ๋ง์ ๋ผ์ด๋ธ๋ก๋ ๋ชป ๊ฑธ์๋ค. ๋์ผapplyVisibility๊ฒฝ๋ก๋ผ ์ ๋ ํ ์คํธ๋ก ์ปค๋ฒ.pnpm run test:browserโ 25 passed / 1 failed. ์คํจํhome-hero-scene.spec.ts:39๋ ์ด ๋ณ๊ฒฝ๊ณผ ๋ฌด๊ดํ ๊ธฐ์กด flake:git stash๋ก cleanmain์ ๋ฆฌ๋น๋ํด ๋๋ ค๋ ๋์ผํ๊ฒ ์คํจ(๊ฐ์tabIndex5s ํ์์์). headless ์ํํธ์จ์ด ๋ ๋๋ง(โ4fps)์์ ์ฌ ์ค๋น๊ฐ poll์ ๋ชป ๋ง์ถ๋ ํ์ด๋ฐ ์ด์๊ณ , ๋ก์ปฌretries:0์ด๋ผ ๋ ธ์ถ๋๋ค. CI๋retries:2๋ผ ๋ง์คํน๋๋ค.ํ์
home-hero-scene.spec.ts:39์ headless ํ์ด๋ฐ flake โ ์ด๋ฒ ๋ณ๊ฒฝ๊ณผ ๋ฌด๊ดํ๋ ๋ก์ปฌ์์ ์ฌํ๋๋ค. 5sexpect.poll๋์ ๋ช ์์ ๋๊ธฐ ์กฐ๊ฑด์ผ๋ก ์์ ํํ๋ ๋ณ๋ ์์ ์ด ํ์ํ๋ค. ์ด๋ฒ PR ๋ฒ์ ๋ฐ(ํ ์คํธ ์ธํ๋ผ ์์ ).