Paprastas vietos plėtros vadovas

Įsivaizduokite, kad naudojate savo mėgstamą produktyvumo programą 30 000 pėdų aukštyje – nėra interneto, nėra įkeliamų suktukų, nėra užšalimo. Jūs nuolat rašote, kuriate ir redaguojate, ir viskas veikia.
Ta patirtis nėra sėkmė. tai Local-First architektūra.
Jūsų veiksmai akimirksniu išsaugomi jūsų įrenginyje. Kai ryšys grįžta, viskas sinchronizuojama automatiškai – jums nepastebėjus.


Kas yra Vietinis pirmiausia?
Palyginkime du skirtingus pasaulius.
🌍1 scenarijus: tradicinė (serveris – pirmoji) programa
Kuriate Notes programą:
Vartotojas įveda pastabą → serveriui išsiųsta užklausa → serverio išsaugojimai → atsakymas grąžinamas → UI naujinimai.
Jei tinklas lėtas arba neveikia, programa laukia. Vartotojas laukia. Produktyvumas sustoja.
🌍2 scenarijus: vietinė pirmoji programa
Ta pati užrašų programa, bet su „Local-First“:
- Vartotojas įveda pastabos pavadinimą → Nedelsiant išsaugoma įrenginio vietinėje duomenų bazėje
- UI atnaujinama nedelsiant → Vartotojas patenkintas
- Programa tyliai sinchronizuojasi su serveriu fone → Vartotojas niekada nežino
Skirtumas: vartotojas nejaučia delsimo. Programa veikia neprisijungus. Kai ryšys grįžta, jis sinchronizuojamas automatiškai.


Paprastas apibrėžimas
„Local-First“ reiškia, kad jūsų programa vietinį įrenginį (naršyklės vietinę duomenų bazę) laiko pagrindiniu tiesos šaltiniu, o ne serveriu.
Serveris vis dar svarbus – tai atsarginė kopija ir tvarko kelių įrenginių sinchronizavimą. Tačiau vartotojo įrenginys yra „pagrindinis tiesos šaltinis“.
Poveikis karjerai (paslaptis, kurios niekas tau nepasako)
Šiuolaikiniai vartotojai tikisi, kad programos veiks visur – skrydžiuose, tuneliuose, nestabiliuose tinkluose. Šiomis akimirkomis tradicinės programos tyliai sugenda. Vietinės programos to nedaro.
Tai nėra eksperimentinė architektūra. Jis jau gaminamas:
- Figma bendradarbiavimui realiuoju laiku
- Linijinis momentiniam užduočių kūrimui
- Sąvoka pirmą kartą redaguoti neprisijungus
Suprasti sistemas, pirmiausia vietoje, tampa vis vertingiau, nes įmonėms labai rūpi greita ir patikima naudotojų patirtis.
Kaip tai iš tikrųjų veikia (architektūra)
Pagalvokite apie vietinę programą, pvz., 4 sluoksnių sumuštinį:


1 sluoksnis: „React UI“ – su kuo sąveikauja vartotojai
2 sluoksnis: IndexedDB – vietinė saugykla naršyklėje (iki 50 MB ir daugiau)
3 sluoksnis: sinchronizavimo variklis – tvarko pakeitimus neprisijungus
4 sluoksnis: serveris – tvarko debesies sinchronizavimą
Duomenų srautas
Kai vartotojas sukuria užduotį:
Vartotojo veiksmas → IndexedDB ← (momentinis atnaujinimas)
↓
Reaguoti pakartotinai pateikti ← (momentinis vartotojo sąsajos atnaujinimas)
↓
Sinchronizuoti variklį ← (veikia fone)
↓
Ar programa internete?
├─ TAIP → Siųsti į serverį dabar
└─ NE → Išsaugoti sinchronizavimo eilėje
💡 Pirmieji trys žingsniai įvyksta akimirksniu.
💡 4 veiksmas įvyksta, kai tinklas yra paruoštas.
Štai kodėl programa atrodo stebuklingai greita.
Kas yra syncQueue?
The sinchronizavimo eilė yra tai, kas daro neprisijungus veikiančias funkcijas patikimas.
Kai vartotojai veikia neprisijungę, jų pakeitimai įtraukiami į eilę ir siunčiami į serverį, kai ryšys grįžta. Pagalvokite apie tai kaip apie savo programos kurjerį – ji niekada nepamiršta pristatymo, net kai kelias užblokuotas.
Įsivaizduokite, kad esate neprisijungę:
- Pridėti 1 užduotį ✓ (sinchronizuota = klaidinga, įtraukta į eilę)
- Pridėti 2 užduotį ✓ (sinchronizuota = klaidinga, įtraukta į eilę)
- Ištrinti 1 užduotį ✓ (veiksmas įtrauktas į eilę)
syncQueue atrodo taip:
(
{ veiksmas: „KURTI“, užduotis: {…}, sinchronizuota: klaidinga },
{ veiksmas: „KURTI“, užduotis: {…}, sinchronizuota: klaidinga },
{ veiksmas: „IŠTRINTI“, užduoties ID: 1, sinchronizuotas: klaidingas }
)
Be sinchronizavimo eilės:
- Pakeitimai neprisijungus gali išnykti
- Ištrinti duomenys gali vėl pasirodyti
- Įrenginiai nutoltų nuo sin
„syncQueue“ užtikrina, kad kiekvienas veiksmas neprisijungus būtų įsimenamas ir sinchronizuojamas – neprarandami duomenys, nėra netikėtumų.
Konfliktų sprendimas „Local-First Apps“.
Vietinėse programose duomenys pirmiausia išsaugomi įrenginyje, o vėliau sinchronizuojami. Konfliktai kyla, kai tie patys duomenys prieš sinchronizavimą pakeičiami keliose vietose. Žemiau pateikiamos dažniausiai pasitaikančios konfliktų sprendimo strategijos, trumpai paaiškintos realiais pavyzdžiais.
1. Paskutinio rašymo laimėjimai (LWW)
Ką tai daro:
Naujausias atnaujinimas perrašo ankstesnius.
Realaus gyvenimo pavyzdys:
Redaguojate užrašą savo telefone 10:00, o tą patį užrašą redaguojate nešiojamajame kompiuteryje 10:05. Kai sinchronizuojama, nešiojamojo kompiuterio versija pakeičia telefono versiją.
if (incoming.updatedAt > current.updatedAt) {
perrašyti ()
}
Geriausiai tinka: Paprastos programos, kuriose priimtinas retkarčiais prarasti duomenis.
2. Lauko lygio sujungimas
Ką tai daro:
Išsprendžiami tik nesuderinami laukai, o ne pakeičiamas visas įrašas.
Realaus gyvenimo pavyzdys:
Viename įrenginyje atnaujinate savo profilio nuotrauką, o kitame – biografiją. Po sinchronizavimo abu pakeitimai išsaugomi.
Geriausiai tinka: Struktūriniai duomenys, pvz., profiliai ir nustatymai.
3. Operatyvinė transformacija (OT)
Ką tai daro:
Išsaugo ir sujungia vartotojo veiksmus (operacijas), o ne galutinę duomenų būseną.
Realaus gyvenimo pavyzdys:
Du žmonės tuo pačiu metu rašo tame pačiame „Google“ dokumente. Abiejų vartotojų tekstai rodomi teisingai, vienas kito neperrašant.
Geriausiai tinka: Bendradarbiaujantys redaktoriai realiuoju laiku.
4. CRDT (bekonfliktiški pakartotiniai duomenų tipai)
Ką tai daro:
Naudoja specialias duomenų struktūras, kurios automatiškai sujungia pakeitimus be konfliktų.
Realaus gyvenimo pavyzdys:
Iš kelių įrenginių išsiųsti pokalbių neprisijungus pranešimai rodomi tinkamai, kai visi įrenginiai vėl prisijungia.
Geriausiai tinka: Pirmosios neprisijungus ir kelių įrenginių programos, kuriose duomenų praradimas yra nepriimtinas.
5. Rankinė (vartotojo valdoma) skiriamoji geba
Ką tai daro:
Vartotojas nusprendžia, kaip išspręsti konfliktą.
Realaus gyvenimo pavyzdys:
Git rodo sujungimo konfliktą ir prašo kūrėjo pasirinkti, kuriuos pakeitimus palikti.
Geriausiai tinka: Kritiniai duomenys, kai teisingumas svarbiau nei patogumas.
6. Domenui būdingos taisyklės
Ką tai daro:
Konfliktai sprendžiami naudojant verslo logiką.
Realaus gyvenimo pavyzdys:
Išlaidų programoje vadovo patvirtinimo naujinimas nepaiso darbuotojo redagavimo.
Geriausiai tinka: Verslui svarbios sistemos su aiškiomis taisyklėmis.
Raktų išsinešimas
Konfliktų sprendimas yra a dizaino pasirinkimaso ne tik techninis. Tinkama strategija priklauso nuo to, kiek svarbūs yra duomenys ir ko vartotojai tikisi dirbdami neprisijungę.
✅ Geri dalykai
1. Žaibiška vartotojo sąsaja
Jūsų naudotojai jaučia, kad programa reaguoja jiems net nepagalvojus.
2. Veikia visur
Naudotojai kuria, redaguoja ir trina užduotis neprisijungę be klaidų pranešimų, o viskas sinchronizuojama automatiškai, kai grįžta ryšys.
3. Sklandi, be trinties naudotojo patirtis
Kiekviena sąveika duoda momentinis grįžtamasis ryšystodėl visa patirtis jaučiasi nušlifuota.
4. Geresnis našumas mastu
Jūsų serveris tvarko sinchronizavimą, o ne kiekvieną paspaudimą. Tai reiškia mažesnes prieglobos išlaidas ir geresnį našumą net ir su tūkstančiais vartotojų
5. Kelių įrenginių magija
Redaguokite telefone, tęskite nešiojamajame kompiuteryje – viskas sinchronizuojama automatiškai be specialių mygtukų ar vartotojo įsikišimo
❌ Kompromisai
1. Konfliktų sprendimo sudėtingumas
Kai du įrenginiai vienu metu redaguoja tą pačią užduotį, kuri versija laimi? Tam reikia apgalvotų strategijų – štai ką aptarėme anksčiau.
2. Duomenų nuoseklumo iššūkiai
Vietiniai ir serverio duomenys gali išsiskirti, kai įrenginiai sinchronizuojami skirtingu laiku. Jūsų sinchronizavimo variklis turi patikimai sujungti šias būsenas – viename įrenginyje gali būti pasenusių duomenų, o kitame – nauji naujiniai.
3. Sandėliavimo apribojimai
„IndexedDB“ paprastai yra ~ 50 MB vienam domenui. Puikiai tinka užduotims ir pastaboms, bet ne programoms, kurioms reikia daug žiniasklaidos
4. Derinimo iššūkiai
Vartotojo duomenys yra jų įrenginyje, todėl sunkiau atkurti klaidas. Jums reikės naršyklės DevTools patirties ir nuotolinio derinimo strategijų
5. Padidėjęs sudėtingumas
Daugiau kodo, kurį reikia prižiūrėti (vietinė DB + sinchronizavimo variklis + konfliktų tvarkymas), reiškia staigesnę mokymosi kreivę. Paprastumu prekiaujate puikia UX.
Paskutinės mintys
„Pirmiausia vietinis“ nėra tik dar vienas architektūros modelis – tai mūsų mąstymo apie programinės įrangos kūrimą pokytis.
„Local-first“ moko mus vienos galingos idėjos:
programinė įranga turi būti tokia pat patikima, kaip ir įrenginys, kuriame ji veikia.
Kai programa ir toliau veikia neprisijungus, esant silpnam signalui arba esant visiškam tinklo gedimui, ji nustoja būti įrankiu ir tampa tuo, kuo naudotojai gali pasikliauti – bet kada ir bet kur.
Puikios programos užsitarnauja lojalumo ne nuolat būdamos prisijungusios, bet būdamos visada patikimas.


