design/vercel

4 min czytania 962 słów
design/vercel screenshot

Vercel: Developer Experience jako filozofia projektowania

„Developerzy są uczuleni na złe UX—nie chcą 'zachwycającego onboardingu', jeśli ich spowalnia."

Filozofia projektowania Vercel jest bezwzględnie skoncentrowana na developerach. System projektowy Geist stawia na klarowność, szybkość i gęstość informacji ponad dekorację. Każdy piksel służy przepływowi pracy developera.


Dlaczego Vercel ma znaczenie

Vercel udowadnia, że narzędzia developerskie mogą mieć wyjątkowy design bez bycia „designerskimi". Dashboard jest szybki, gęsty informacyjnie i nie przeszkadza w pracy.

Kluczowe osiągnięcia: - Stworzenie Geist, kroju pisma zaprojektowanego specjalnie dla developerów - Redesign dashboardu zmniejszył First Meaningful Paint o 1,2s - Pionierskie podejście dark-mode-first w narzędziach developerskich - Wyznaczenie standardu dla UX wdrożeń - Ikony kart odzwierciedlające status deploymentu (budowanie, błąd, gotowy)


Kluczowe wnioski

  1. Tryb ciemny to szacunek, nie funkcja - Developerzy pracują w terminalach i IDE z ciemnym tłem; biały dashboard tworzy irytujące przełączanie kontekstu i zmęczenie oczu
  2. Status powinien być widoczny wszędzie - Favicony kart, tytuły stron, kropki na osi czasu: status deploymentu powinien być widoczny bez przełączania fokusa czy otwierania kart
  3. Optymistyczny UI eliminuje postrzeganą latencję - Pokaż oczekiwany stan natychmiast, synchronizuj z rzeczywistością w tle; developerzy zauważają opóźnienia 300ms
  4. Puste stany to instrukcje, nie ilustracje - Pokaż dokładną komendę do uruchomienia (git push origin main), nie dekoracyjną grafikę z przyciskiem „Rozpocznij"
  5. Wydajność to design - Redesign dashboardu Vercel zmniejszył First Meaningful Paint o 1,2s; żadna ilość pięknych animacji nie rekompensuje wolnego ładowania

Podstawowa filozofia projektowania

Zasada skoncentrowana na developerze

Developerzy oceniają produkty po tym, jak mało ich spowalniają. Design Vercel to odzwierciedla:

ANTYWZORCE (Co developerzy nienawidzą)     PODEJŚCIE VERCEL
───────────────────────────────────────────────────────────────────
„Zachwycające" animacje dodające opóźnienia Natychmiastowe stany bez przejść
Kreatory onboardingu blokujące pracę        CLI-first, dashboard opcjonalny
Gęsta dokumentacja ukryta w kartach         Informacje widoczne na pierwszy rzut oka
Spinnery ładowania przy każdej akcji        Optymistyczne aktualizacje + SWR
Teksty marketingowe w dashboardzie          Czysto funkcjonalny UI

Kluczowy wniosek: Developerzy nie chcą być „zachwyceni". Chcą dostarczać kod.


Biblioteka wzorców

1. Doskonałość trybu ciemnego

Tryb ciemny Vercel to nie przełącznik. To domyślne ustawienie. Design jest chirurgiczny: ostro kontrastowa czerń i biel tworzą maksymalny kontrast.

Filozofia kolorów:

:root {
  /* Paleta Vercel jest niezwykle prosta */

  /* Tła - czysta czerń, bez szarości */
  --bg-000: #000000;
  --bg-100: #0A0A0A;
  --bg-200: #111111;

  /* Pierwszy plan - wysoki kontrast bieli */
  --fg-100: #FFFFFF;
  --fg-200: #EDEDED;
  --fg-300: #A1A1A1;
  --fg-400: #888888;

  /* Obramowania - subtelne, ale widoczne */
  --border-100: #333333;
  --border-200: #444444;

  /* Semantyczne - status deploymentu */
  --color-success: #00DC82;  /* Zielony - wdrożony */
  --color-error: #FF0000;    /* Czerwony - błąd */
  --color-warning: #FFAA00;  /* Bursztynowy - budowanie */
  --color-info: #0070F3;     /* Niebieski - w kolejce */

  /* Akcent - sygnatura Vercel */
  --accent: #FFFFFF;         /* Biel jako akcent na czerni */
}

Dlaczego czysta czerń działa: - Maksymalny kontrast dla czytelności tekstu - Estetyka inspirowana terminalem, której developerzy ufają - Zmniejsza zmęczenie oczu w ciemnym otoczeniu - Sprawia, że kolorowe wskaźniki statusu wyróżniają się


2. Wskaźniki statusu w kartach

Vercel odzwierciedla status deploymentu w ikonach kart przeglądarki, czyniąc informacje widocznymi nawet gdy karta nie jest aktywna.

┌─ Pasek kart przeglądarki ──────────────────────────────────────────┐
│                                                                    │
│  [▶] acme-web - Budowanie   [✓] blog - Gotowy   [✕] api - Błąd    │
│                                                                    │
└────────────────────────────────────────────────────────────────────┘

Stany ikony karty:
  ⏳ W kolejce (szare kółko)
  ▶  Budowanie (animowany spinner)
  ✓  Gotowy (zielony znacznik)
  ✕  Błąd (czerwony X)

Wzorzec implementacji:

// Dynamiczny favicon na podstawie statusu deploymentu
function updateFavicon(status) {
  const link = document.querySelector("link[rel~='icon']");

  const icons = {
    queued: '/favicon-queued.svg',
    building: '/favicon-building.svg',  // Animowany
    ready: '/favicon-ready.svg',
    error: '/favicon-error.svg',
  };

  link.href = icons[status];
}

// Tytuł również odzwierciedla status
function updateTitle(projectName, status) {
  const prefixes = {
    queued: '⏳',
    building: '▶',
    ready: '✓',
    error: '✕',
  };

  document.title = `${prefixes[status]} ${projectName} - Vercel`;
}

Kluczowy wniosek: Developerzy mają otwartych wiele kart. Status widoczny na pasku kart oznacza, że nie muszą przełączać kart, by sprawdzić status budowania.


3. Oś czasu deploymentu

Inspektor deploymentu pokazuje przejrzystą oś czasu procesu wdrożenia.

┌─ Oś czasu deploymentu ─────────────────────────────────────────────┐
│                                                                    │
│  [o] W kolejce                                   12:34:56 PM       │
│  │                                                                 │
│  [o] Budowanie                                   12:34:58 PM       │
│  │ └─ Instalowanie zależności... 3.2s                              │
│  │ └─ Budowanie... 12.4s                                           │
│  │ └─ Generowanie statycznych stron... 2.1s                        │
│  │                                                                 │
│  [o] Wdrażanie                                   12:35:14 PM       │
│  │ └─ Przesyłanie artefaktów budowania...                          │
│  │                                                                 │
│  [*] Gotowy                                      12:35:18 PM       │
│    └─ https://acme-abc123.vercel.app                               │
│                                                                    │
│  Łącznie: 22s                                                      │
│                                                                    │
└────────────────────────────────────────────────────────────────────┘

Kodowanie wizualne:

.timeline-step {
  position: relative;
  padding-left: 24px;
}

.timeline-step::before {
  content: '';
  position: absolute;
  left: 0;
  top: 6px;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--step-color);
}

/* Linia łącząca */
.timeline-step:not(:last-child)::after {
  content: '';
  position: absolute;
  left: 4px;
  top: 16px;
  width: 2px;
  height: calc(100% - 6px);
  background: var(--border-100);
}

/* Stany kroków */
.timeline-step[data-status="complete"]::before {
  background: var(--color-success);
}

.timeline-step[data-status="active"]::before {
  background: var(--color-warning);
  animation: pulse 1.5s infinite;
}

.timeline-step[data-status="error"]::before {
  background: var(--color-error);
}

.timeline-step[data-status="pending"]::before {
  background: var(--fg-400);
}

4. Design przeglądarki logów

Przeglądarka logów Vercel jest zintegrowana z przeglądem deploymentu, nie jest osobną stroną.

┌─ Logi budowania ───────────────────────────────────────────────────┐
│                                                                    │
│  Filtr: [Wszystko ▼]  [Funkcja: api/hello ▼]       [Kopiuj] [↓]   │
│                                                                    │
├────────────────────────────────────────────────────────────────────┤
│                                                                    │
│  12:34:58.123  info   Instalowanie zależności...                   │
│  12:35:01.456  info   dodano 1234 pakiety w 3.2s                   │
│  12:35:01.789  info   Uruchamianie budowania...                    │
│  12:35:14.012  info   ✓ Skompilowano pomyślnie                     │
│  12:35:14.234  warn   Duży rozmiar bundla: pages/index.js (245kb)  │
│  12:35:14.567  info   Generowanie statycznych stron...             │
│  12:35:16.890  info   ✓ Wygenerowano 42 strony                     │
│                                                                    │
└────────────────────────────────────────────────────────────────────┘

Kluczowe funkcje: - Kopiowanie do schowka jednym kliknięciem - Filtrowanie po funkcji lub wyjściu budowania - Poziomy logów oznaczone kolorami (info, warn, error) - Znaczniki czasu z precyzją do milisekund - Adresy URL do udostępniania konkretnych linii logów

Implementacja:

.log-line {
  display: flex;
  font-family: var(--font-mono);
  font-size: 12px;
  line-height: 1.6;
  padding: 2px 12px;
}

.log-line:hover {
  background: var(--bg-200);
}

.log-timestamp {
  color: var(--fg-400);
  min-width: 100px;
  margin-right: 12px;
}

.log-level {
  min-width: 48px;
  margin-right: 12px;
}

.log-level[data-level="info"] { color: var(--fg-300); }
.log-level[data-level="warn"] { color: var(--color-warning); }
.log-level[data-level="error"] { color: var(--color-error); }

.log-message {
  color: var(--fg-100);
  white-space: pre-wrap;
  word-break: break-word;
}

5. Puste stany

Puste stany Vercel są funkcjonalne, nie dekoracyjne. Mówią ci, co zrobić dalej.

┌─ Pusty stan: Brak deploymentów ────────────────────────────────────┐
│                                                                    │
│                                                                    │
│                         Brak deploymentów                          │
│                                                                    │
│               Wypchnij do repozytorium, aby utworzyć               │
│                    swój pierwszy deployment                        │
│                                                                    │
│                                                                    │
│           git push origin main                                     │
│                                                                    │
│                                                                    │
│                         [Zobacz dokumentację]                      │
│                                                                    │
│                                                                    │
└────────────────────────────────────────────────────────────────────┘

Zasady projektowania: - Brak dekoracyjnych ilustracji - Jasna akcja (komenda git) - Pomocny link do dokumentacji - Monospace dla komend (łatwe do skopiowania)


System projektowania wizualnego

Typografia (Geist)

Vercel stworzył Geist specjalnie dla doświadczeń developerskich:

:root {
  /* Geist Sans - UI i tekst główny */
  --font-sans: 'Geist', -apple-system, BlinkMacSystemFont, sans-serif;

  /* Geist Mono - kod i treści techniczne */
  --font-mono: 'Geist Mono', 'SF Mono', monospace;

  /* Skala rozmiarów */
  --text-xs: 12px;
  --text-sm: 13px;
  --text-base: 14px;
  --text-lg: 16px;
  --text-xl: 18px;
  --text-2xl: 24px;

  /* Wysokości linii */
  --leading-tight: 1.25;
  --leading-normal: 1.5;
  --leading-relaxed: 1.75;

  /* Odstępy między literami */
  --tracking-tight: -0.02em;
  --tracking-normal: 0;
  --tracking-wide: 0.02em;
}

/* Liczby tabelaryczne dla danych */
.tabular-nums {
  font-variant-numeric: tabular-nums;
}

/* Lub użyj Geist Mono do porównań */
.data-value {
  font-family: var(--font-mono);
}

System odstępów

:root {
  /* Jednostka bazowa 4px */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 20px;
  --space-6: 24px;
  --space-8: 32px;
  --space-10: 40px;
  --space-12: 48px;
  --space-16: 64px;
}

Zaokrąglenia rogów

:root {
  /* Subtelne, spójne promienie */
  --radius-sm: 4px;
  --radius-md: 6px;
  --radius-lg: 8px;
  --radius-xl: 12px;
  --radius-full: 9999px;
}

Wzorce animacji

Optymistyczne aktualizacje

Vercel używa optymistycznych aktualizacji UI. Akcje czują się natychmiastowe.

// Wzorzec SWR dla aktualizacji w czasie rzeczywistym
const { data, mutate } = useSWR('/api/deployments');

async function triggerDeploy() {
  // Natychmiast pokaż stan „wdrażanie"
  mutate(
    { ...data, status: 'building' },
    false  // Nie rewaliduj jeszcze
  );

  // Następnie faktycznie uruchom
  await fetch('/api/deploy', { method: 'POST' });

  // Rewaliduj, aby uzyskać rzeczywisty stan
  mutate();
}

Subtelne stany ładowania

/* Ładowanie szkieletowe - bez spinnerów */
.skeleton {
  background: linear-gradient(
    90deg,
    var(--bg-200) 0%,
    var(--bg-100) 50%,
    var(--bg-200) 100%
  );
  background-size: 200% 100%;
  animation: shimmer 1.5s infinite;
  border-radius: var(--radius-md);
}

@keyframes shimmer {
  0% { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}

Stany przycisków

.button {
  transition: background 100ms ease, transform 100ms ease;
}

.button:hover {
  background: var(--fg-100);
}

.button:active {
  transform: scale(0.98);
}

/* Bez długich przejść - natychmiastowa informacja zwrotna */

Optymalizacje wydajności (oparte na designie)

Redesign dashboardu Vercel obejmował decyzje projektowe, które poprawiły wydajność:

Użyte techniki: - Preconnecting do API, Assets i Avatar origins - Krytyczne wywołania API otrzymują wyższy priorytet przeglądarki - Memoizacja komponentów React (useMemo, useCallback) - ReactDOM.unstable_batchedUpdates zmniejszył ponowne renderowanie o 20% - SWR dla efektywnych aktualizacji danych w czasie rzeczywistym

Kluczowy wniosek: Wydajność JEST designem. Wolny dashboard z pięknymi animacjami jest gorszy niż szybki dashboard bez nich.


Lekcje dla naszej pracy

1. Tryb ciemny jako domyślny

Gdy twoi użytkownicy pracują w ciemnym otoczeniu (terminale, IDE), tryb ciemny nie jest funkcją—to szacunek.

2. Status w każdym rogu

Ikony kart, tytuły stron, wskaźniki na osi czasu: status powinien być widoczny bez zmiany fokusa.

3. Domyślnie optymistyczny

Pokaż oczekiwany stan natychmiast. Aktualizuj z rzeczywistością w tle.

4. Developerzy nienawidzą czekać

Żadnych spinnerów ładowania, jeśli można tego uniknąć. Stany szkieletowe, optymistyczne aktualizacje, prefetching.

5. Puste stany to instrukcje

Nie pokazuj ładnej ilustracji. Pokaż komendę, którą muszą uruchomić.


Najczęściej zadawane pytania

Dlaczego Vercel używa czystej czerni (#000000) zamiast ciemnej szarości jako tła?

Czysta czerń zapewnia maksymalny kontrast dla białego tekstu, tworząc optymalną czytelność. Pasuje również do estetyki terminali i edytorów kodu, których developerzy już używają, sprawiając, że dashboard czuje się jak natywna część ich przepływu pracy. Ciemnoszare tła często wyglądają „łagodniej", ale zmniejszają kontrast i mogą wyglądać na wyblakłe na wyświetlaczach high-DPI.

Jak działają wskaźniki statusu w kartach Vercel?

Vercel dynamicznie aktualizuje favicon przeglądarki na podstawie statusu deploymentu: spinner dla budowania, zielony znacznik dla gotowy, czerwony X dla błędu. Tytuł strony również aktualizuje się z prefiksami emoji (▶, ✓, ✕). Oznacza to, że developerzy mogą monitorować wiele deploymentów w różnych kartach bez przełączania fokusa—status jest widoczny na pierwszy rzut oka na pasku kart przeglądarki.

Jakie jest podejście Vercel do stanów ładowania?

Vercel unika tradycyjnych spinnerów ładowania na rzecz optymistycznego UI i ekranów szkieletowych. Gdy uruchamiasz deployment, UI natychmiast pokazuje stan „budowanie" zanim serwer potwierdzi. Biblioteka SWR obsługuje rewalidację w tle. Dzięki temu akcje czują się natychmiastowe, nawet gdy żądania sieciowe zajmują 200-500ms.

Czym jest Geist i dlaczego Vercel stworzył własny krój pisma?

Geist to rodzina krojów pisma, którą Vercel zaprojektował specjalnie dla interfejsów developerskich. Obejmuje Geist Sans dla tekstu UI i Geist Mono dla kodu. Design jest zoptymalizowany dla małych rozmiarów (12-14px) powszechnych w dashboardach, zawiera liczby tabelaryczne dla wyrównanych kolumn danych i ma wyraźne kształty znaków, aby zapobiec pomyleniu podobnych glifów (l, 1, I).

Jak Vercel obsługuje puste stany inaczej niż inne produkty?

Puste stany Vercel pokazują wykonalne komendy, nie dekoracyjne ilustracje. Pusta strona deploymentów wyświetla git push origin main w monospace (łatwe do skopiowania) zamiast rysunku z ogólnym przyciskiem „Rozpocznij". Filozofia polega na tym, że developerzy chcą dokładnie wiedzieć, co zrobić, a nie być wizualnie uspokojeni.