왜 2026년에 React Native Skia인가
React Native 앱을 개발하다 보면 누구나 한 번쯤은 이 벽에 부딪히게 됩니다. 기본 제공 컴포넌트로는 도저히 구현할 수 없는 UI 말이에요. 커스텀 차트, 부드러운 그라데이션 전환, 인터랙티브한 파티클 효과 같은 것들요.
솔직히 저도 처음엔 SVG 라이브러리로 어떻게든 해보려고 했습니다. 그런데 데이터 포인트가 수백 개만 넘어가도 프레임이 뚝뚝 끊기더라고요. Canvas API는 React Native에서 제대로 된 지원 자체가 없었고요.
2026년 현재, React Native Skia가 이런 고민들의 사실상 표준 해답이 되고 있습니다. Shopify가 관리하고 William Candillon이 이끄는 이 라이브러리는 Google의 Skia 2D 그래픽 엔진을 React Native에 직접 가져온 건데요 — Chrome, Android, Flutter를 구동하는 바로 그 엔진입니다. 최신 버전 2.6.x 기준으로 React Native 0.79 이상, React 19를 지원하며, Expo SDK 53/55와도 잘 호환됩니다.
이 글에서는 설치부터 기본 도형, Reanimated 연동 애니메이션, 셰이더 효과, 실전 차트 구현까지 코드와 함께 다뤄보겠습니다. 자, 바로 들어가 봅시다.
React Native Skia 아키텍처 이해하기
JSI 기반 직접 통신
React Native Skia가 빠른 이유, 결국 아키텍처에 있습니다. 기존 브리지를 거치지 않고 JSI(JavaScript Interface)를 통해 Skia의 C++ 엔진과 직접 통신해요. JSON 직렬화도 없고, 비동기 메시지 큐도 없습니다. JavaScript에서 호출한 드로잉 명령이 네이티브 GPU로 곧바로 전달되는 구조죠.
성능 수치를 보면 좀 놀랍습니다. Fabric 렌더러 도입 이후 iOS에서 최대 50%, Android에서는 최대 200% 빠른 렌더링 속도를 기록했어요. 불변(immutable) 디스플레이 리스트로 전환하면서 동시성 문제도 깔끔하게 해결됐고요.
하이브리드 렌더링 패턴
여기서 한 가지 중요한 점 — Skia가 기존 React Native 뷰 시스템을 대체하는 게 아닙니다. 두 렌더링 경로가 공존하는 방식이에요.
내비게이션, 리스트, 폼 같은 표준 UI는 그대로 React Native 뷰로 처리하고, 차트나 그래픽 효과, 커스텀 애니메이션처럼 GPU 가속이 필요한 부분에만 Skia Canvas를 끼워넣는 거죠. 제 경험상 이 방식이 실제 프로젝트에서도 가장 현실적입니다.
// 하이브리드 패턴 예시: 일반 View 안에 Skia Canvas 임베드
import { View, Text } from "react-native";
import { Canvas, Circle } from "@shopify/react-native-skia";
export function DashboardCard() {
return (
<View style={{ padding: 16 }}>
<Text style={{ fontSize: 18, fontWeight: "bold" }}>
오늘의 활동
</Text>
{/* 표준 View 안에 Skia Canvas를 임베드 */}
<Canvas style={{ width: 300, height: 200 }}>
<Circle cx={150} cy={100} r={80} color="#4A90D9" />
</Canvas>
</View>
);
}
설치 및 환경 설정
Expo 프로젝트
Expo를 사용한다면 설치가 정말 간단합니다. 2026년 기준 Expo SDK 53 이상에서 완벽하게 지원돼요.
# React Native Skia 설치
npx expo install @shopify/react-native-skia
# Reanimated도 함께 설치 (애니메이션 연동용)
npx expo install react-native-reanimated
# 제스처 핸들링이 필요하다면
npx expo install react-native-gesture-handler
babel.config.js에 Reanimated 플러그인 설정이 되어 있는지 꼭 확인하세요. 이거 빠뜨리면 런타임에서 원인 모를 에러가 나서 한참 헤맬 수 있습니다.
// babel.config.js
module.exports = function (api) {
api.cache(true);
return {
presets: ["babel-preset-expo"],
plugins: ["react-native-reanimated/plugin"],
};
};
Bare React Native 프로젝트
Expo 없이 사용하는 경우에는 몇 가지 추가 설정이 필요합니다.
# npm으로 설치
npm install @shopify/react-native-skia
npm install react-native-reanimated
# iOS 네이티브 의존성 설치
cd ios && pod install && cd ..
버전 호환성은 반드시 체크하세요. @shopify/react-native-skia 2.x는 React Native 0.79 이상과 React 19가 필요합니다. React Native 0.78 이하를 쓰고 있다면 1.12.4 버전을 설치해야 해요. 이 부분에서 삽질하는 분들이 꽤 있더라고요.
기본 도형과 캔버스 다루기
Canvas 컴포넌트
모든 Skia 드로잉은 <Canvas> 컴포넌트 안에서 이루어집니다. Canvas는 일반 React Native View처럼 스타일링할 수 있고, 그 안에서 Skia의 선언적 API로 도형을 그리면 됩니다.
import { Canvas, Rect, Circle, Line, vec } from "@shopify/react-native-skia";
export function BasicShapes() {
return (
<Canvas style={{ width: 350, height: 300 }}>
{/* 사각형 */}
<Rect x={20} y={20} width={120} height={80} color="#FF6B6B" />
{/* 원 */}
<Circle cx={250} cy={60} r={50} color="#4ECDC4" />
{/* 선 */}
<Line
p1={vec(20, 150)}
p2={vec(330, 150)}
color="#95A5A6"
style="stroke"
strokeWidth={2}
/>
{/* 투명도가 있는 원 */}
<Circle cx={175} cy={220} r={60} color="rgba(74, 144, 217, 0.6)" />
</Canvas>
);
}
Path로 복잡한 도형 그리기
기본 도형만으로 부족할 때, Path를 쓰면 어떤 형태든 자유롭게 그릴 수 있습니다. SVG path 문법과 동일한 d 속성을 지원하니까, 웹에서 SVG 다뤄봤다면 금방 익숙해질 거예요.
import { Canvas, Path, Skia } from "@shopify/react-native-skia";
export function CustomShape() {
// 프로그래밍 방식으로 Path 생성
const path = Skia.Path.Make();
path.moveTo(50, 150);
path.cubicTo(50, 50, 175, 50, 175, 150);
path.cubicTo(175, 50, 300, 50, 300, 150);
path.close();
return (
<Canvas style={{ width: 350, height: 200 }}>
<Path
path={path}
color="#E74C3C"
style="fill"
/>
{/* SVG path 문법도 직접 사용 가능 */}
<Path
path="M 20 180 Q 175 100 330 180"
color="#3498DB"
style="stroke"
strokeWidth={3}
/>
</Canvas>
);
}
그라데이션과 Paint 효과
Skia의 Paint 시스템을 활용하면 그라데이션, 블러, 그림자 등 다양한 효과를 적용할 수 있습니다. 이 부분이 개인적으로 Skia에서 가장 만족스러운 기능 중 하나인데, 코드 몇 줄로 꽤 있어 보이는 UI를 만들 수 있거든요.
import {
Canvas,
RoundedRect,
LinearGradient,
Shadow,
vec,
} from "@shopify/react-native-skia";
export function GradientCard() {
return (
<Canvas style={{ width: 350, height: 200 }}>
<RoundedRect x={25} y={25} width={300} height={150} r={16}>
<LinearGradient
start={vec(25, 25)}
end={vec(325, 175)}
colors={["#667eea", "#764ba2"]}
/>
<Shadow dx={4} dy={8} blur={12} color="rgba(0,0,0,0.3)" />
</RoundedRect>
</Canvas>
);
}
Reanimated 연동: UI 스레드 애니메이션
왜 Reanimated인가
React Native Skia의 진짜 강점은 Reanimated와의 연동에서 드러납니다.
핵심을 말하자면, Reanimated의 shared value를 Skia 컴포넌트 props에 직접 전달할 수 있습니다. createAnimatedComponent나 useAnimatedProps 같은 래퍼가 필요 없어요. 그냥 shared value를 넘기면 Skia가 자동으로 감지하고 UI 스레드에서 업데이트합니다. 처음 이걸 발견했을 때 솔직히 좀 감동이었어요.
실질적으로 이게 의미하는 건, JS 스레드가 아무리 바빠도 — API 호출 중이든, 무거운 데이터 처리 중이든 — Skia 애니메이션은 60fps 이상을 유지한다는 겁니다.
기본 애니메이션: 펄스 효과
import { useEffect } from "react";
import { Canvas, Circle, Group } from "@shopify/react-native-skia";
import {
useSharedValue,
useDerivedValue,
withRepeat,
withTiming,
Easing,
} from "react-native-reanimated";
export function PulseAnimation() {
const progress = useSharedValue(0);
// 반복 애니메이션 시작
useEffect(() => {
progress.value = withRepeat(
withTiming(1, { duration: 2000, easing: Easing.inOut(Easing.ease) }),
-1, // 무한 반복
true // 역방향 포함 (ping-pong)
);
}, []);
// derived value로 반지름 계산
const radius = useDerivedValue(() => {
return 30 + progress.value * 40; // 30 ~ 70 사이
});
// derived value로 투명도 계산
const opacity = useDerivedValue(() => {
return 1 - progress.value * 0.6; // 1.0 ~ 0.4 사이
});
return (
<Canvas style={{ width: 200, height: 200 }}>
<Group>
{/* 외곽 펄스 링 */}
<Circle
cx={100}
cy={100}
r={radius}
color="#4A90D9"
opacity={opacity}
/>
{/* 중심 원 */}
<Circle cx={100} cy={100} r={30} color="#2C3E50" />
</Group>
</Canvas>
);
}
컬러 애니메이션
색상 보간에서 주의할 점이 하나 있는데요. Reanimated의 interpolateColor는 Skia와 색상 저장 형식이 달라서 바로 쓸 수가 없습니다. 이것 때문에 처음에 좀 헤맸는데, Skia에서 제공하는 interpolateColors를 대신 사용하면 됩니다.
import { useEffect } from "react";
import {
Canvas,
RoundedRect,
interpolateColors,
} from "@shopify/react-native-skia";
import {
useSharedValue,
useDerivedValue,
withRepeat,
withTiming,
} from "react-native-reanimated";
export function ColorTransition() {
const progress = useSharedValue(0);
useEffect(() => {
progress.value = withRepeat(
withTiming(1, { duration: 3000 }),
-1,
true
);
}, []);
// Skia 전용 색상 보간 함수 사용
const color = useDerivedValue(() => {
return interpolateColors(
progress.value,
[0, 0.5, 1],
["#FF6B6B", "#4ECDC4", "#45B7D1"]
);
});
return (
<Canvas style={{ width: 300, height: 100 }}>
<RoundedRect x={10} y={10} width={280} height={80} r={12} color={color} />
</Canvas>
);
}
제스처 연동 애니메이션
react-native-gesture-handler와 결합하면 터치 기반 인터랙션도 60fps로 구현할 수 있습니다. 코드도 놀라울 정도로 간결해요.
import { Canvas, Circle } from "@shopify/react-native-skia";
import { useSharedValue } from "react-native-reanimated";
import { Gesture, GestureDetector } from "react-native-gesture-handler";
export function DraggableCircle() {
const cx = useSharedValue(150);
const cy = useSharedValue(150);
const gesture = Gesture.Pan().onChange((event) => {
cx.value += event.changeX;
cy.value += event.changeY;
});
return (
<GestureDetector gesture={gesture}>
<Canvas style={{ width: 300, height: 300 }}>
<Circle cx={cx} cy={cy} r={40} color="#9B59B6" />
</Canvas>
</GestureDetector>
);
}
셰이더로 고급 시각 효과 만들기
SkSL 셰이더 기초
Skia는 SkSL(Skia Shading Language)이라는 자체 셰이더 언어를 지원합니다. GLSL과 문법이 거의 같고, GPU에서 직접 실행되니까 복잡한 시각 효과도 부드럽게 돌아갑니다.
그리고 여기서 꿀팁 하나 — ShaderToy에서 만든 WebGL 셰이더 대부분이 최소한의 수정만으로 React Native Skia에서 동작해요. 이미 만들어진 멋진 셰이더들을 가져다 쓸 수 있다는 뜻이죠.
import { Canvas, Rect, Skia, Shader } from "@shopify/react-native-skia";
import { useEffect } from "react";
import { useSharedValue, useDerivedValue, withRepeat, withTiming } from "react-native-reanimated";
// SkSL로 작성한 물결 효과 셰이더
const waveShader = Skia.RuntimeEffect.Make(`
uniform float2 iResolution;
uniform float iTime;
half4 main(float2 fragCoord) {
float2 uv = fragCoord / iResolution;
float wave = sin(uv.x * 10.0 + iTime * 3.0) * 0.05;
float3 col = float3(0.3 + wave, 0.5 + uv.y * 0.3, 0.9 - uv.x * 0.2);
return half4(col, 1.0);
}
`)!;
export function WaveEffect() {
const time = useSharedValue(0);
useEffect(() => {
time.value = withRepeat(
withTiming(Math.PI * 2, { duration: 4000 }),
-1,
false
);
}, []);
const uniforms = useDerivedValue(() => ({
iResolution: [350, 200],
iTime: time.value,
}));
return (
<Canvas style={{ width: 350, height: 200 }}>
<Rect x={0} y={0} width={350} height={200}>
<Shader source={waveShader} uniforms={uniforms} />
</Rect>
</Canvas>
);
}
유니폼(Uniform) 타입
셰이더에 전달할 수 있는 유니폼 타입은 다음과 같습니다:
float,float2,float3,float4— 스칼라 및 벡터float2x2,float3x3,float4x4— 행렬int,int2,int3,int4— 정수 타입
Reanimated의 useDerivedValue로 유니폼 값을 동적으로 변경하면, 셰이더 매개변수가 매 프레임 UI 스레드에서 업데이트됩니다. 브리지 통신이 없으니 전환이 정말 매끄러워요.
실전 프로젝트: 인터랙티브 라인 차트
자, 이제 지금까지 배운 내용을 종합해서 실제로 쓸 수 있는 인터랙티브 라인 차트를 만들어봅시다.
SVG 기반 차트 라이브러리를 써봤다면 아실 텐데, 데이터 포인트 수백 개에서 이미 버벅이기 시작합니다. Skia 기반 차트는 5,000개 이상에서도 60fps를 유지해요. 직접 테스트해보면 차이가 체감됩니다.
import { useMemo } from "react";
import {
Canvas,
Path,
Skia,
LinearGradient,
vec,
Circle,
} from "@shopify/react-native-skia";
import {
useSharedValue,
useDerivedValue,
withTiming,
} from "react-native-reanimated";
import { Gesture, GestureDetector } from "react-native-gesture-handler";
const CHART_WIDTH = 340;
const CHART_HEIGHT = 200;
const CHART_PADDING = 20;
interface DataPoint {
x: number;
y: number;
}
// 데이터를 Skia Path로 변환
function createChartPath(data: DataPoint[]): string {
if (data.length === 0) return "";
const maxX = Math.max(...data.map((d) => d.x));
const maxY = Math.max(...data.map((d) => d.y));
const scaleX = (v: number) =>
CHART_PADDING + (v / maxX) * (CHART_WIDTH - CHART_PADDING * 2);
const scaleY = (v: number) =>
CHART_HEIGHT - CHART_PADDING - (v / maxY) * (CHART_HEIGHT - CHART_PADDING * 2);
let d = `M ${scaleX(data[0].x)} ${scaleY(data[0].y)}`;
for (let i = 1; i < data.length; i++) {
// 부드러운 곡선을 위한 cubic bezier 보간
const prev = data[i - 1];
const curr = data[i];
const cpX = (scaleX(prev.x) + scaleX(curr.x)) / 2;
d += ` C ${cpX} ${scaleY(prev.y)} ${cpX} ${scaleY(curr.y)} ${scaleX(curr.x)} ${scaleY(curr.y)}`;
}
return d;
}
export function InteractiveChart({ data }: { data: DataPoint[] }) {
const pathString = useMemo(() => createChartPath(data), [data]);
// 터치 위치 추적
const touchX = useSharedValue(-1);
const touchY = useSharedValue(-1);
const isActive = useSharedValue(false);
const indicatorOpacity = useDerivedValue(() => {
return withTiming(isActive.value ? 1 : 0, { duration: 150 });
});
const gesture = Gesture.Pan()
.onBegin((e) => {
isActive.value = true;
touchX.value = e.x;
touchY.value = e.y;
})
.onChange((e) => {
touchX.value = e.x;
touchY.value = e.y;
})
.onEnd(() => {
isActive.value = false;
});
// 영역 채우기용 Path (차트 아래 그라데이션 영역)
const areaPath = useMemo(() => {
if (data.length === 0) return "";
const maxX = Math.max(...data.map((d) => d.x));
const scaleX = (v: number) =>
CHART_PADDING + (v / maxX) * (CHART_WIDTH - CHART_PADDING * 2);
return `${pathString} L ${scaleX(data[data.length - 1].x)} ${
CHART_HEIGHT - CHART_PADDING
} L ${scaleX(data[0].x)} ${CHART_HEIGHT - CHART_PADDING} Z`;
}, [data, pathString]);
return (
<GestureDetector gesture={gesture}>
<Canvas style={{ width: CHART_WIDTH, height: CHART_HEIGHT }}>
{/* 그라데이션 영역 채우기 */}
<Path path={areaPath}>
<LinearGradient
start={vec(0, 0)}
end={vec(0, CHART_HEIGHT)}
colors={["rgba(74, 144, 217, 0.3)", "rgba(74, 144, 217, 0.0)"]}
/>
</Path>
{/* 메인 라인 */}
<Path
path={pathString}
style="stroke"
strokeWidth={2.5}
color="#4A90D9"
strokeCap="round"
strokeJoin="round"
/>
{/* 터치 인디케이터 */}
<Circle
cx={touchX}
cy={touchY}
r={6}
color="#4A90D9"
opacity={indicatorOpacity}
/>
<Circle
cx={touchX}
cy={touchY}
r={12}
color="rgba(74, 144, 217, 0.2)"
opacity={indicatorOpacity}
/>
</Canvas>
</GestureDetector>
);
}
Skia vs SVG: 언제 무엇을 쓸까
모든 상황에서 Skia가 정답은 아닙니다. 오히려 대부분의 경우에는 기존 도구로 충분해요. 각각 언제 쓰면 좋은지 정리해봤습니다.
SVG가 더 나은 경우
- 간단한 아이콘, 로고 표시
- 정적인 일러스트레이션
- 데이터 포인트가 적은 단순 차트 (100개 이하)
- 접근성(Accessibility)이 중요한 UI 요소
Skia가 더 나은 경우
- 대량 데이터 포인트의 실시간 차트 (수천 개 이상)
- 커스텀 셰이더 효과 (블러, 노이즈, 물결)
- 인터랙티브 드로잉 및 시그니처 기능
- 파티클 시스템, 복잡한 애니메이션
- 이미지 필터와 합성 효과
- 게임 스타일 렌더링
성능 비교
5,000개 데이터 포인트를 가진 라인 차트 기준으로, SVG는 거대한 DOM 트리 때문에 스크롤할 때 눈에 띄게 버벅입니다. 반면 Skia는 터치 인터랙션 중에도 120fps 디스플레이에서 매끄럽게 동작해요.
성능 차이의 핵심은 세 가지입니다: GPU 렌더링(CPU 기반 뷰 대신), UI 스레드 실행(JS 스레드 대신), 배치 드로우 콜(요소당 개별 뷰 대신). 이 세 가지가 합쳐지면 차이가 극적으로 벌어지게 됩니다.
성능 최적화 팁
1. 불필요한 리렌더링 방지
Skia 컴포넌트도 결국 React 컴포넌트입니다. 리렌더링 규칙이 동일해요. 정적 요소는 메모이제이션하고, 동적 값은 반드시 Reanimated shared value로 처리하세요. 이걸 간과하면 Skia를 쓰는 의미가 반감됩니다.
import { useMemo } from "react";
import { Canvas, Path, Skia } from "@shopify/react-native-skia";
export function OptimizedChart({ data }: { data: number[] }) {
// Path 객체를 useMemo로 캐싱
const path = useMemo(() => {
const p = Skia.Path.Make();
p.moveTo(0, 200 - data[0]);
data.forEach((value, index) => {
p.lineTo(index * 5, 200 - value);
});
return p;
}, [data]);
return (
<Canvas style={{ width: 350, height: 200 }}>
<Path path={path} style="stroke" strokeWidth={2} color="#4A90D9" />
</Canvas>
);
}
2. 무거운 계산은 워크렛에서
Reanimated 워크렛을 사용하면 복잡한 계산도 UI 스레드에서 직접 처리할 수 있습니다. JS 스레드를 전혀 건드리지 않기 때문에 메인 비즈니스 로직에 영향을 주지 않아요.
3. Canvas 크기 최소화
Canvas 크기는 실제 필요한 영역만큼만 잡으세요. 전체 화면 크기의 Canvas 하나보다는, 필요한 위치에 작은 Canvas를 여러 개 배치하는 게 GPU 메모리 효율이 훨씬 좋습니다. (이건 의외로 많은 분들이 놓치는 부분이에요.)
4. 이미지 텍스처 활용
복잡한 정적 배경은 매 프레임 다시 그리지 마세요. 이미지 텍스처로 한 번 렌더링해서 캐싱하는 것이 훨씬 효율적입니다.
미래 전망: WebGPU와 Skia Graphite
Shopify 팀에서 Skia Graphite라는 차세대 백엔드를 실험적으로 내놓고 있습니다. 현재는 Ganesh가 기본 백엔드이고, Graphite는 @next 배포 채널에서 프리뷰로 써볼 수 있어요. 아직 프로덕션에는 추천하지 않지만, 방향성은 확실합니다.
Graphite와 함께 WebGPU 지원도 예고됐습니다. Android에서는 Vulkan, iOS에서는 Metal을 통해 3D 그래픽까지 가능해지는 건데요. Skia의 2D 프리미티브를 3D 씬 위에 비용 없이 합성할 수 있게 되면, GPU 컴퓨트를 활용한 물리 시뮬레이션이나 파티클 시스템도 구현할 수 있게 됩니다. 개인적으로 이 부분이 가장 기대되네요.
2026년 시점에서 React Native Skia는 이미 프로덕션에서 검증된 성숙한 라이브러리입니다. Shopify를 포함한 대규모 기업들이 실제 서비스에서 사용 중이고, 커뮤니티도 빠르게 성장하고 있어요. 지금 익혀두면 앞으로 WebGPU 전환에도 자연스럽게 대응할 수 있을 겁니다.
자주 묻는 질문 (FAQ)
React Native Skia는 Expo에서 사용할 수 있나요?
네, 완벽하게 지원됩니다. npx expo install @shopify/react-native-skia 한 줄이면 Expo SDK 53 이상에서 바로 사용할 수 있어요. 다만 Expo Go에서는 동작하지 않고 Development Build를 써야 한다는 점만 주의하세요.
Skia를 쓰면 앱 번들 크기가 많이 커지나요?
Skia 네이티브 바이너리가 추가되면서 플랫폼별로 약 6~8MB 정도 증가합니다. 솔직히 GPU 가속 그래픽의 이점을 생각하면 충분히 감수할 만한 수준이에요. 웹에서는 CanvasKit WASM 파일이 gzip 기준 약 2.9MB이며 비동기 로드가 가능해서 초기 로딩 영향을 최소화할 수 있습니다.
React Native Skia와 Reanimated 없이 애니메이션을 만들 수 있나요?
가능합니다. Skia 자체적으로 useClockValue나 타이밍 기반 API를 제공하거든요. 하지만 Reanimated와 함께 쓰면 UI 스레드 실행, 제스처 연동, Spring/Timing 이징 등 훨씬 풍부한 도구를 활용할 수 있어서, 2026년 기준으로는 Reanimated 조합이 사실상 표준 패턴으로 자리잡았습니다.
기존 react-native-svg 프로젝트를 Skia로 마이그레이션해야 하나요?
꼭 그럴 필요는 없습니다. 간단한 아이콘이나 정적 그래픽에는 SVG가 여전히 좋은 선택이에요. 마이그레이션이 의미 있는 건 대량 데이터 차트에서 성능 이슈가 있거나, 커스텀 셰이더가 필요하거나, 인터랙티브 드로잉 기능을 구현할 때입니다. 두 라이브러리는 같은 프로젝트에서 공존할 수 있으니, 필요한 화면에서만 점진적으로 도입하는 걸 추천합니다.
Skia는 tvOS나 macOS도 지원하나요?
네, @shopify/react-native-skia 2.x 버전부터 tvOS, macOS, macOS Catalyst를 공식 지원합니다. iOS, Android 외에 다양한 플랫폼에서 동일한 Skia 코드를 재사용할 수 있다는 건 확실히 큰 장점이에요.