인셔셔RSS 관심 있는 블로그, 뉴스, 기술 정보를 효율적으로 추적하고 읽으세요
원문 읽기 InertiaRSS에서 열기

추천 피드

雷峰网
雷峰网
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
The GitHub Blog
The GitHub Blog
博客园 - Franky
Google DeepMind News
Google DeepMind News
J
Java Code Geeks
Last Week in AI
Last Week in AI
V
Visual Studio Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Blog — PlanetScale
Blog — PlanetScale
D
Docker
GbyAI
GbyAI
V
V2EX
IT之家
IT之家
酷 壳 – CoolShell
酷 壳 – CoolShell
博客园 - 聂微东
博客园_首页
月光博客
月光博客
量子位
罗磊的独立博客

DEV Community

Gemma 4 on Android: Tricks for Faster On-Device Inference Your AI agent has amnesia. You've just normalized it. I built an AI that reviews every PR automatically (because nobody was reviewing mine) 🌿 Git Mastery: The Complete Developer Guide Bringing Gemma 4 E2B to the Edge: Building a Privacy-First Dream Analyzer with Flutter & LiteRT Google I/O 2026 Wasn’t About Features — It Was About AI Becoming the Developer Environment Building an AI Vedic Astrology App in 25 Days — What Actually Worked (and What Didn't) Hermes Agent Has Four Memories — And That's Why It Doesn't Forget You Pressure Isn't Killing You -Your Relationship With It Is 🐳 How to Run Any Project in Docker: A Complete Guide AccessLens — a blind person's lanyard, powered by Gemma 4 on-device Glyph v0.2: the release is the joinery How I Built a Blazingly Fast, Privacy-First Batch Image Converter in the Browser Using OPFS and Web Workers Cómo solucionar \"Text content does not match server-rendered HTML\" en Next.js App Router FCoP 3.0: Why AI Agents Need a Track, Not a Brake Fibonacci: Quiz app which anyone can make revenue by viewing ads to the quiz contestants. The Subconscious Powered by Edge AI GPU Utilization Is Becoming the New Cloud Waste Crisis Cómo solucionar `docker run` con exit code 1 en Raspberry Pi JWT is a scam and your app doesn't need it 7 Agent Skill Packs That Actually Make AI Coders Better More Control, More Cost: Why Commanding AI Isn't Delegation SecureScan Synthadoc: We Built an AI Judge for Our AI Wiki Compiler - Here's What We Learned Cómo solucionar el error de permiso al ejecutar `pip.exe` en entorno virtual (Python 3.10 en Windows) Postgres-grade Serializable at 20k+ ops/s — on a laptop. Don’t try this at home. Pure Core, Imperative Shell in Rust with Stillwater Lean 4 for Programmers: Building a Todo List with Proof Trustless Bug Bounty Releases with a PoW-Gated DLC Oracle Building Autonomous DevOps Agents with MCP and LangChain Multimodal Gemma 4 Visual Regression & Patch Agent Git Time Machine — How Version Control Can Save Your Project My Dad Got an Electricity Bill He Couldn't Understand. Google I/O 2026 Just Made That Problem Solvable. My Dad Got an Electricity Bill He Couldn't Understand. Google I/O 2026 Just Made That Problem Solvable. Read Replicas Lie About Consistency. 4 Sync Modes Behind the Lie. Reviving My Coding Project with GitHub Copilot I Tried Gemini 3.5 Flash After Google I/O 2026 - Here is What I Found :)) Zero-Cost AI in VS Code Blueprints Might Be More Important Than Frameworks AI CareCompanion - Offline Health Assistant Long-Context Models Killed RAG. Except for the 6 Cases Where They Made It Worse. I Built a Neural Network Engine in C# That Runs in Your Browser - No ONNX Runtime, No JavaScript Bridge, No Native Binaries An In-Depth Overview of the Apache Iceberg 1.11.0 Release Your Agent Just Called the Same Tool 47 Times. Here's the 20-Line Detector. How I Built a Multi-System Astrology Bot in Python (And What Meta Banned Me For) Gemma 4 Has Four Variants. Here's How to Pick the Right One Before You Write a Single Line of Code. Log Level Strategies: Balancing Observability and Cost Why WebMCP Is the Most Important Thing Google Announced at I/O 2026 (And Nobody's Talking About It) Making LLM Calls Reliable: Retry, Semaphore, Cache, and Batch Google's 2x Energy Efficiency Claim Is Real — But Here's What They're Not Measuring
190개국, 0 API 호출: 크롬 확장 프로그램에서 배송 정적 데이터 전송
SHOTA · 2026-05-23 · via DEV Community

SHOTA

데이터가 필요한 대부분의 Chrome 확장 프로그램은 두 가지 패턴 중 하나에 해당합니다: 외부 API를 호출하거나, 사용자 특정 데이터를 로컬에 작은 양 저장합니다. EntryCheck는 둘 다 하지 않습니다. 190개 이상의 여권/목적지 조합에 대한 비자 요건의 정적 데이터 세트를 확장 프로그램에 직접 포함하고, 모든 조회를 클라이언트 측에서 네트워크 요청 없이 해결합니다.

이 트레이드오프 — 큰 번들, 즉각적인 검색, API 의존성 없음 —은 여행 데이터에 적합한 결정이 되어온다. 그 이유와 작동 방식은 다음과 같다.

왜 정적 데이터가 API보다 낫은가

비자 요건은 자주 변경되지 않습니다. 한 나라는 연중 비자 도착 리스트를 두 번 또는 세 번 업데이트할 수 있습니다. API는 지연 시간을 추가하고 인증을 요구하며, 비행기를 예약하기 전에 사용자가 빠르게 확인하려는 상황에서 네트워크가 없거나 API가 다운되거나 요청 한도를 초과하는 실패 모드를 만들 수 있습니다.

더 현실적으로는 비자 요건에 대한 신뢰할 수 있는 무료 공개 API는 없습니다. 데이터 소스는 정부 웹사이트와 참조 데이터베이스입니다. 실시간 API를 위해 이들을 스크래핑하거나 라이선스하는 것은 속도와 간단함의 가치를 가진 도구에 대해 가치가 없습니다.

확장 프로그램 시작 시 로드되는 로컬 JSON 파일은 모든 것을 피하ます.

데이터 구조

핵심 데이터셋은 두 글자 ISO 여권 코드로 키가 되는 JSON 객체로, 그 다음으로 두 글자 목적지 코드로 구성됩니다:

type VisaStatus =
  | 'visa_free'
  | 'visa_on_arrival'
  | 'e_visa'
  | 'visa_required'
  | 'not_admitted';

interface EntryRequirement {
  status: VisaStatus;
  maxStay?: number;        // days, undefined if no limit
  notes?: string;
}

type VisaMatrix = Record<string, Record<string, EntryRequirement>>;

전체 화면 모드 입력 전체 화면 모드 종료

조회는 단지 두 번의 배열 접근입니다:

function lookup(matrix: VisaMatrix, passport: string, destination: string): EntryRequirement | null {
  return matrix[passport]?.[destination] ?? null;
}

전체 화면 모드 입력 전체 화면 모드 종료

행렬 자체는 잘 압축됩니다: visa_free 그리고visa_required는 대부분의 조합을 포함하므로 JSON에는 많은 반복된 구조가 있습니다. Gzipped로 압축하면 전체 데이터셋이 30KB 미만입니다.

WXT와 함께 묶기

행렬은 public/visa-matrix.json에 있습니다. WXT(확장 프레임워크)는 public/ 디렉토리를 출력 루트에 정확히 복사합니다. 배경 서비스 워커는 설치 시 한 번 로드하고 결과를 캐시합니다:

let cachedMatrix: VisaMatrix | null = null;

async function getMatrix(): Promise<VisaMatrix> {
  if (cachedMatrix) return cachedMatrix;
  const url = chrome.runtime.getURL('visa-matrix.json');
  const resp = await fetch(url);
  cachedMatrix = await resp.json();
  return cachedMatrix;
}

전체 화면 모드 입력 전체 화면 모드 종료

chrome.runtime.getURL는 확장 프로그램의 내부 chrome-extension:// URL로 상대 경로를 변환합니다. 이는 서비스 워커에서 포함된 자산에 접근하는 표준 패턴입니다. MV3에서는 특별한 권한 없이 작동합니다.

Google Flights에서의 콘텐츠 스크립트 주입

검색 팝업은 그 자체로 잘 작동하지만, 더 유용한 기능은 구글 항공권 자동 주입입니다. 사용자가 항공편을 검색하고 페이지에 목적지가 표시될 때, EntryCheck의 콘텐츠 스크립트는 목적지를 감지하고 사용자가 저장한 여권의 요구 사항을 조회한 다음 검색 결과 옆에 배지를 주입합니다.

콘텐츠 스크립트는 URL 파라미터와 페이지 DOM에서 현재 목적지를 읽고, chrome.runtime.sendMessage을 통해 배경으로 검색을 요청한 다음, 인라인으로 작은 배지 컴포넌트를 렌더링합니다.

chrome.runtime.sendMessage(
  { type: 'VISA_LOOKUP', passport: savedPassport, destination: detected },
  (response: EntryRequirement | null) => {
    if (response) renderBadge(response);
  }
);

전체 화면 모드를 입력합니다. 전체 화면 모드를 종료합니다.

배경은 이를 받고, 호출합니다getMatrix()를 반환합니다. 첫 번째 로드 후 행렬이 메모리에 있기 때문에, 콘텐츠 스크립트의 관점에서는 응답이 동기식입니다.

유지보수 문제

정적 데이터는 명백한 단점이 하나 있습니다: 그것은 구식이 될 수 있습니다. 제 현재 접근 방식은 확장 버전 업데이트마다 JSON 파일을 업데이트하고 일반 CWS 업데이트로 푸시하는 것입니다. 수동적이지만 관리 가능합니다 - 비자 요건은 충분히 드물게 변경되어 연 4회 검토가 변경 사항의 95%를 커버합니다.

더 자주 업데이트되는 내용(환율, 사업 시간)에 대해서는 이 모델이 작동하지 않고 API가 더 합리적입니다. 비자 요건은 정적이 실제로 이긴 드문 경우입니다.


🔗 Chrome 웹 스토어의 EntryCheck: 설치