React Native와 Expo로 앱을 개발할 때, 이미지는 사용자 경험에서 매우 중요한 요소입니다. 로딩 속도가 느리거나 이미지가 깜빡이면 사용자 만족도가 떨어질 수 있습니다. 그래서 이번 글에서는 Expo가 공식으로 제공하는 이미지 처리 도구인
expo-image
와
expo-asset
을 함께 활용하여 이미지를 효율적으로 관리하고 보여주는 방법을 알아보겠습니다.
두 라이브러리 모두 설치도 간단하고 사용법도 직관적이기 때문에 초보자도 충분히 쉽게 따라할 수 있습니다.
🚀
expo-image로 외부 이미지 불러오기 🔗
expo-image
는 고성능 이미지 뷰어입니다. 기본적인 Image
컴포넌트보다 더 다양한 기능을 제공하며, 내부적으로 캐싱과 전환 효과 등 고급 기능을 포함하고 있어 성능이 매우 뛰어납니다.
터미널에서 아래 명령어를 실행합니다.
npx expo install expo-image
외부 URL로부터 이미지를 불러오는 가장 기본적인 예시는 다음과 같습니다.
import { Image } from 'expo-image' ;
import { View, StyleSheet } from 'react-native' ;
export default function App () {
return (
< View style ={ styles.container } >
< Image
style ={ styles.image }
source = "https://picsum.photos/seed/picsum/3000/2000"
contentFit = "cover"
transition ={ 1000 }
/>
</ View >
);
}
const styles = StyleSheet. create ({
container: {
flex: 1 ,
justifyContent: 'center' ,
},
image: {
width: '100%' ,
height: 300 ,
backgroundColor: '#ccc' ,
},
});
contentFit
속성은 CSS의 object-fit
처럼 동작하며, 이미지가 어떻게 맞춰질지를 결정합니다.
🚀
expo-asset으로 앱 내부 이미지 로딩하기 🔗
앱에 포함된 정적인 이미지 파일을 불러오려면 expo-asset
을 사용합니다. 이 라이브러리는 require()
를 통해 자산을 불러올 수 있게 하며, 이미지, 폰트, 사운드 등 모든 정적 파일을 지원합니다.
npx expo install expo-asset
import { Asset } from 'expo-asset' ;
import { Image } from 'expo-image' ;
import { useEffect, useState } from 'react' ;
import { View, StyleSheet } from 'react-native' ;
export default function App () {
const [ localUri , setLocalUri ] = useState < string | null >( null );
useEffect (() => {
async function loadImage () {
const [ asset ] = await Asset. loadAsync ( require ( '@/assets/example.png' ));
setLocalUri (asset.localUri);
}
loadImage ();
}, []);
return (
< View style ={ styles.container } >
{ localUri && (
< Image
style ={ styles.image }
source ={ localUri }
contentFit = "contain"
transition ={ 500 }
/>
) }
</ View >
);
}
const styles = StyleSheet. create ({
container: {
flex: 1 ,
justifyContent: 'center' ,
},
image: {
width: 300 ,
height: 300 ,
},
});
위 코드는 앱 내부의 이미지 파일을 asset으로 로딩하고, 해당 파일의 경로(localUri)를 expo-image
에 전달하여 보여줍니다.
expo-asset
에서는 useAssets
라는 훅도 제공합니다. 이 훅은 여러 자산을 한 번에 불러올 때 유용하며, 로딩 상태와 에러 상태도 함께 관리할 수 있습니다.
import { useAssets } from 'expo-asset' ;
import { Image } from 'react-native' ;
const [ assets , error ] = useAssets ([
require ( './assets/image1.png' ),
require ( './assets/image2.jpg' ),
]);
return assets ? < Image source ={ assets[ 0 ] } /> : null ;
이 방식은 코드가 더욱 간결하며, 여러 이미지가 필요한 컴포넌트에서 유용하게 사용할 수 있습니다.
🚀
Blurhash로 이미지 로딩 전 부드러운 UX 제공하기 🔗
이미지 로딩 시 흰 화면이나 깜빡임이 보이면 사용자에게 어색함을 줄 수 있습니다. 이를 개선하기 위해
expo-image
는
blurhash
기능을 제공합니다. Blurhash는 아주 작은 문자열을 기반으로 흐릿한 이미지를 생성해주는 기술입니다. 마치 이미지의
썸네일 미리보기
처럼 동작하지만 훨씬 더 가볍고 빠릅니다.
import { Image } from 'expo-image' ;
import { View, StyleSheet } from 'react-native' ;
export default function App () {
return (
< View style ={ styles.container } >
< Image
style ={ styles.image }
source = "https://picsum.photos/seed/blurimage/3000/2000"
contentFit = "cover"
transition ={ 500 }
placeholder = "blurhash"
blurhash = "L|LqFGRiWBaz~qWAV@ayt8axf6fR"
/>
</ View >
);
}
const styles = StyleSheet. create ({
container: {
flex: 1 ,
justifyContent: 'center' ,
},
image: {
width: '100%' ,
height: 300 ,
backgroundColor: '#eee' ,
},
});
여기서
blurhash="L5H2EC=PM+yV0g-mq.wG9c010J}I"
는
임의의 blurhash 값
입니다. 실제로는
blurhash
문자열을 생성해주는 툴이나 백엔드 서비스에서 생성해 사용해야 합니다.
blurhash를 사용할 경우 로딩 중인 이미지가 자연스럽게 부드러운 배경으로 대체되어 깜빡임이나 딜레이에 대한 시각적 거부감이 크게 줄어듭니다.
blurhash 문자열을 생성하려면 서버에서 이미지 파일을 분석해 blurhash 값을 만들어주는 과정이 필요합니다. 대표적인 도구는 다음과 같습니다.
프론트엔드 앱에서 사용하는 것은 expo-image
가 처리해주지만, 생성은 일반적으로 백엔드나 빌드 프로세스에서 수행합니다.
expo-image
는 외부 및 내부 이미지 모두를 고성능으로 처리할 수 있게 해주는 훌륭한 컴포넌트이며,
expo-asset
은 자산 파일들을 깔끔하게 관리해주는 도구입니다. 이 두 가지를 함께 사용하면 앱의 이미지 처리 속도와 안정성을 크게 향상시킬 수 있습니다.
특히 앱 내 자산을 불러올 때는
expo-asset
을 통해
localUri
를 얻고, 이를
expo-image
로 넘겨주는 방식이 가장 추천되는 방식입니다.
expo-image
와
expo-asset
기능에 더해,
blurhash
는 UX를 부드럽게 개선해주는 매우 유용한 기술입니다. 이미지 로딩이 느린 환경에서도 사용자가 불편을 느끼지 않도록 자연스러운 흐릿한 미리보기를 제공할 수 있습니다.
특히 외부 URL로 이미지를 불러오는 경우에는
blurhash
를 함께 사용하면 앱의 완성도가 한층 높아집니다. 정적인 자산(
expo-asset
)과 함께 조합해 사용할 수도 있으며, 이는 고품질 앱의 이미지 전략으로 매우 권장되는 방식입니다.
이미지 최적화를 위해 WebP 포맷 사용도 고려해보세요.
필요하다면 앱 시작 시 SplashScreen
을 활용해 이미지 로딩이 완료될 때까지 기다리는 방식도 좋습니다.
CDN을 활용하여 외부 이미지 로딩 속도를 높일 수도 있습니다.