Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion docs/docs/en/guide/_meta.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@
"type": "dir",
"name": "usage",
"label": "Usage"
}
},
"performance-optimization-tips"
]
91 changes: 91 additions & 0 deletions docs/docs/en/guide/performance-optimization-tips.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
# Performance Optimization Tips

#### Wrap the `renderItem` function with `useCallback` to prevent unnecessary re-renders.

```tsx
import { useCallback, useState } from 'react'; // [!code highlight]
import { ScrollView, Image, Modal } from 'react-native';
import { GestureViewer } from 'react-native-gesture-image-viewer';

function App() {
const images = [...];
const [visible, setVisible] = useState(false);

// [!code highlight:3]
const renderImage = useCallback((imageUrl: string) => {
return <Image source={{ uri: imageUrl }} style={{ width: '100%', height: '100%' }} resizeMode="contain" />;
}, []);

return (
<Modal visible={visible} onRequestClose={() => setVisible(false)}>
<GestureViewer
data={images}
renderItem={renderImage}
ListComponent={ScrollView}
onDismiss={() => setVisible(false)}
/>
</Modal>
);
}
```

#### For large images, we recommend using [`expo-image`](https://docs.expo.dev/versions/latest/sdk/image/) or [`FastImage`](https://github.com/DylanVann/react-native-fast-image).

```tsx
import { ScrollView, Modal } from 'react-native';
import { GestureViewer } from 'react-native-gesture-image-viewer';
import { Image } from 'expo-image'; // [!code highlight]

function App() {
const images = [...];
const [visible, setVisible] = useState(false);

const renderImage = useCallback((imageUrl: string) => {
return <Image source={{ uri: imageUrl }} style={{ width: '100%', height: '100%' }} contentFit="contain" />; // [!code highlight]
}, []);

Comment on lines +34 to +46
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Missing React hook imports in second snippet
The example invokes useCallback and useState but forgets to import them, resulting in a runtime error if readers copy the code verbatim.

-import { ScrollView, Modal } from 'react-native';
+import { useCallback, useState } from 'react';
+import { ScrollView, Modal } from 'react-native';
🤖 Prompt for AI Agents
In docs/docs/en/guide/performance-optimization-tips.mdx around lines 34 to 46,
the React hooks useCallback and useState are used but not imported, causing
runtime errors. Add an import statement for these hooks from 'react' at the top
of the code snippet to fix the issue.

return (
<Modal visible={visible} onRequestClose={() => setVisible(false)}>
<GestureViewer
data={images}
renderItem={renderImage}
ListComponent={ScrollView}
onDismiss={() => setVisible(false)}
/>
</Modal>
);
}
```

#### For handling many images, we recommend using [`FlashList`](https://shopify.github.io/flash-list/).

- [FlashList Performance Guide](https://shopify.github.io/flash-list/docs/fundamentals/performance)

```tsx
import { useCallback, useState } from 'react';
import { Image, Modal } from 'react-native';
import { GestureViewer } from 'react-native-gesture-image-viewer';
import { FlashList } from '@shopify/flash-list'; // [!code highlight]

function App() {
const images = [...];
const [visible, setVisible] = useState(false);

const renderImage = useCallback((imageUrl: string) => {
return <Image source={{ uri: imageUrl }} style={{ width: '100%', height: '100%' }} resizeMode="contain" />;
}, []);

return (
<Modal visible={visible} onRequestClose={() => setVisible(false)}>
<GestureViewer
data={images}
renderItem={renderImage}
ListComponent={FlashList} // [!code highlight]
onDismiss={() => setVisible(false)}
/>
</Modal>
);
}
```

#### Test on actual devices (performance may be limited in simulators).
3 changes: 2 additions & 1 deletion docs/docs/ko/guide/_meta.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@
"type": "dir",
"name": "usage",
"label": "사용법"
}
},
"performance-optimization-tips"
]
91 changes: 91 additions & 0 deletions docs/docs/ko/guide/performance-optimization-tips.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
# 성능 최적화 팁

#### `renderItem` 함수는 `useCallback`으로 감싸서 불필요한 리렌더링을 방지하세요.

```tsx
import { useCallback, useState } from 'react'; // [!code highlight]
import { ScrollView, Image, Modal } from 'react-native';
import { GestureViewer } from 'react-native-gesture-image-viewer';

function App() {
const images = [...];
const [visible, setVisible] = useState(false);

// [!code highlight:3]
const renderImage = useCallback((imageUrl: string) => {
return <Image source={{ uri: imageUrl }} style={{ width: '100%', height: '100%' }} resizeMode="contain" />;
}, []);

return (
<Modal visible={visible} onRequestClose={() => setVisible(false)}>
<GestureViewer
data={images}
renderItem={renderImage}
ListComponent={ScrollView}
onDismiss={() => setVisible(false)}
/>
</Modal>
);
}
```

#### 대용량 이미지의 경우 [`expo-image`](https://docs.expo.dev/versions/latest/sdk/image/)나 [`FastImage`](https://github.com/DylanVann/react-native-fast-image) 사용을 권장합니다.

```tsx
import { ScrollView, Modal } from 'react-native';
import { GestureViewer } from 'react-native-gesture-image-viewer';
import { Image } from 'expo-image'; // [!code highlight]

function App() {
const images = [...];
const [visible, setVisible] = useState(false);

const renderImage = useCallback((imageUrl: string) => {
return <Image source={{ uri: imageUrl }} style={{ width: '100%', height: '100%' }} contentFit="contain" />; // [!code highlight]
}, []);

Comment on lines +34 to +46
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

useCallback / useState 미임포트로 예제가 동작하지 않음
두 번째 예제에서 useCallback, useState 훅을 사용하지만 react 로부터 임포트하지 않아 그대로 복사-붙여넣기 시 컴파일 에러가 발생합니다.

-import { ScrollView, Modal } from 'react-native';
+import { useCallback, useState } from 'react';
+import { ScrollView, Modal } from 'react-native';
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
```tsx
import { ScrollView, Modal } from 'react-native';
import { GestureViewer } from 'react-native-gesture-image-viewer';
import { Image } from 'expo-image'; // [!code highlight]
function App() {
const images = [...];
const [visible, setVisible] = useState(false);
const renderImage = useCallback((imageUrl: string) => {
return <Image source={{ uri: imageUrl }} style={{ width: '100%', height: '100%' }} contentFit="contain" />; // [!code highlight]
}, []);
import { useCallback, useState } from 'react';
import { ScrollView, Modal } from 'react-native';
import { GestureViewer } from 'react-native-gesture-image-viewer';
import { Image } from 'expo-image'; // [!code highlight]
function App() {
const images = [...];
const [visible, setVisible] = useState(false);
const renderImage = useCallback((imageUrl: string) => {
return <Image source={{ uri: imageUrl }} style={{ width: '100%', height: '100%' }} contentFit="contain" />; // [!code highlight]
}, []);
🤖 Prompt for AI Agents
In docs/docs/ko/guide/performance-optimization-tips.mdx around lines 34 to 46,
the example code uses React hooks useCallback and useState but does not import
them from 'react'. To fix this, add an import statement for useCallback and
useState from 'react' at the top of the code snippet to ensure the example
compiles and runs correctly.

return (
<Modal visible={visible} onRequestClose={() => setVisible(false)}>
<GestureViewer
data={images}
renderItem={renderImage}
ListComponent={ScrollView}
onDismiss={() => setVisible(false)}
/>
</Modal>
);
}
```

#### 많은 수의 이미지를 다룰 때는 [`FlashList`](https://shopify.github.io/flash-list/) 사용을 권장합니다.

- [FlashList Performance 가이드](https://shopify.github.io/flash-list/docs/fundamentals/performance)

```tsx
import { useCallback, useState } from 'react';
import { Image, Modal } from 'react-native';
import { GestureViewer } from 'react-native-gesture-image-viewer';
import { FlashList } from '@shopify/flash-list'; // [!code highlight]

function App() {
const images = [...];
const [visible, setVisible] = useState(false);

const renderImage = useCallback((imageUrl: string) => {
return <Image source={{ uri: imageUrl }} style={{ width: '100%', height: '100%' }} resizeMode="contain" />;
}, []);

return (
<Modal visible={visible} onRequestClose={() => setVisible(false)}>
<GestureViewer
data={images}
renderItem={renderImage}
ListComponent={FlashList} // [!code highlight]
onDismiss={() => setVisible(false)}
/>
</Modal>
);
}
```

#### 디바이스에서 테스트하세요. (시뮬레이터에서는 성능이 제한될 수 있습니다.)