Ky është postimi # 14 i serisë kushtuar eksplorimit të JavaScript dhe komponentëve të tij të ndërtimit. Në procesin e identifikimit dhe përshkrimit të elementeve thelbësore, ne ndajmë gjithashtu disa rregulla të përgjithshme që përdorim kur ndërtojmë "SessionStack", një aplikacion JavaScript që duhet të jetë i fuqishëm dhe me performancë të lartë për të ndihmuar përdoruesit të shohin dhe riprodhojnë realisht defektet e aplikacionit të tyre në internet. koha.

Nëse keni humbur kapitujt e mëparshëm, mund t'i gjeni këtu:

  • Një përmbledhje e motorit, koha e funksionimit dhe grupi i thirrjeve
  • "Brenda motorit V8 të Google + 5 këshilla se si të shkruani kodin e optimizuar"
  • "Menaxhimi i kujtesës + si të trajtoni 4 rrjedhje të zakonshme të kujtesës"
  • "Cakulli i ngjarjeve dhe rritja e programimit Async + 5 mënyra për të koduar më mirë me async/prit"
  • "Hyni thellë në WebSockets dhe HTTP/2 me SSE + si të zgjidhni rrugën e duhur"
  • Një krahasim me WebAssembly + pse në raste të caktuara është më mirë ta përdorni mbi JavaScript
  • "Blloqet e ndërtimit të Web Workers + 5 raste kur duhet t'i përdorni"
  • "Punonjësit e shërbimit, cikli i tyre jetësor dhe rastet e përdorimit"
  • "Mekanika e Njoftimeve Push në Ueb"
  • "Ndjekja e ndryshimeve në DOM duke përdorur MutationObserver"
  • "Motori i renderimit dhe këshilla për të optimizuar performancën e tij"
  • "Brenda shtresës së rrjetit + Si të optimizoni performancën dhe sigurinë e tij"
  • "Nën kapuçin e animacioneve CSS dhe JS + si të optimizoni performancën e tyre"

Vështrim i përgjithshëm

Ne të gjithë e dimë se si gjërat mund të bëhen të çrregullta duke përfunduar në një pikë të madhe JavaScript. Jo vetëm që kjo pjesë e kodit duhet të transferohet në rrjet, por gjithashtu duhet të analizohet, kompilohet në bytecode dhe në fund të ekzekutohet. Në postimet e mëparshme, ne diskutuam tema të tilla si motori JS, koha e ekzekutimit dhe grupi i thirrjeve, si dhe motori V8 që përdoret kryesisht nga Google Chrome dhe NodeJS. Ata të gjithë luajnë një rol jetik në të gjithë procesin e ekzekutimit të JavaScript. Tema që po planifikojmë të prezantojmë sot nuk është më pak e rëndësishme: do të shohim se si shumica e motorëve JavaScript e analizojnë tekstin në diçka kuptimplote për makinën, çfarë ndodh më pas dhe se si ne si zhvillues ueb mund ta kthejmë këtë njohuri në avantazhin tonë.

Si funksionojnë gjuhët e programimit

Pra, le të bëjmë një hap prapa dhe të shohim se si funksionojnë gjuhët e programimit në radhë të parë. Pavarësisht se çfarë gjuhe programimi po përdorni, gjithmonë do t'ju duhet një pjesë e softuerit që mund të marrë kodin burimor dhe ta bëjë kompjuterin të bëjë diçka në të vërtetë. Ky softuer mund të jetë ose një përkthyes ose një përpilues. Pavarësisht nëse jeni duke përdorur një gjuhë të interpretuar (JavaScript, Python, Ruby) ose një të përpiluar (C#, Java, Rust), gjithmonë do të ketë një pjesë të përbashkët: analizimi i kodit burimor si tekst i thjeshtë në një strukturë të dhënash të quajtur pema e sintaksës abstrakte (AST). Jo vetëm që AST-të e paraqesin kodin burim në një mënyrë të strukturuar, por ato gjithashtu luajnë një rol kritik në analizën semantike ku përpiluesi vërteton korrektësinë dhe përdorimin e duhur të programit dhe elementeve gjuhësore. Më vonë, AST-të përdoren për të gjeneruar bytekodin aktual ose kodin e makinës.

aplikimet AST

AST-të nuk përdoren vetëm në përkthyesit dhe përpiluesit e gjuhës. Ata kanë shumë aplikacione në botën e kompjuterit. Një nga mënyrat më të zakonshme për t'i përdorur ato është për të analizuar kodin statik. Analizuesit statikë nuk ekzekutojnë kodin që i jepet hyrjes së tyre. Megjithatë, ata duhet të kuptojnë strukturën e kodit. Për shembull, mund të dëshironi të zbatoni një mjet që gjen struktura të zakonshme kodi, në mënyrë që t'i rifaktoroni ato për të reduktuar dyfishimin. Ju mund të jeni në gjendje ta bëni këtë duke përdorur krahasimin e vargjeve, por zbatimi do të jetë shumë themelor dhe i kufizuar. Natyrisht, nëse jeni të interesuar të zbatoni një mjet të tillë, nuk keni nevojë të shkruani analizuesin tuaj. Ka shumë zbatime me burim të hapur të cilat janë plotësisht në përputhje me specifikimet e Ecmascript. Esprima dhe Acorn, për të përmendur një çift. Ka gjithashtu shumë mjete që mund të ndihmojnë me daljen e prodhuar nga analizuesi, përkatësisht AST-të. AST-të përdoren gjithashtu gjerësisht në zbatimin e transpiluesve të kodit. Kështu, për shembull, mund të dëshironi të implementoni një transpilues që konverton kodin Python në JavaScript. Ideja bazë është që ju do të përdorni një transpilues Python për të gjeneruar një AST të cilin do ta përdorni më pas për të gjeneruar kodin e mbrapsht JavaScript. Ju mund të pyesni se si është e mundur kjo. Puna është se AST-të janë thjesht një mënyrë e ndryshme për të përfaqësuar një gjuhë. Para analizës ai përfaqësohet si tekst i cili ndjek disa rregulla që përbëjnë një gjuhë. Pas analizimit ai përfaqësohet si një strukturë peme e cila përmban saktësisht të njëjtin informacion si teksti hyrës. Prandaj, ne mund të bëjmë gjithmonë hapin e kundërt dhe të kthehemi te një paraqitje tekstuale.

Parsing JavaScript

Pra, le të shohim se si ndërtohet një AST. Ne kemi një funksion të thjeshtë JavaScript si shembull:

Analizuesi do të prodhojë AST-in e mëposhtëm.

Vini re se për qëllime vizualizimi, ky është një version i thjeshtuar i asaj që analizuesi do të prodhonte. AST aktual është shumë më kompleks. Ideja këtu, megjithatë, është të kuptojmë se cila do të ishte gjëja e parë që do t'i ndodhte kodit burimor përpara se të ekzekutohet. Nëse dëshironi të shihni se si duket AST aktual, mund të kontrolloni AST Explorer. Është një mjet online në të cilin kaloni disa JavaScript dhe nxjerr AST për atë kod.

Pse më duhet të di se si funksionon analizuesi JavaScript, mund të pyesni. Në fund të fundit, duhet të jetë përgjegjësia e shfletuesit që ta bëjë atë të funksionojë. Dhe ke të drejtë, disi. Grafiku i mëposhtëm tregon ndarjen totale të kohës për hapat e ndryshëm në procesin e ekzekutimit të JavaScript. Hidhini një sy nga afër dhe shikoni nëse gjeni ndonjë gjë interesante.

A keni parë atë? Hidhni një vështrim më të afërt. Mesatarisht, një shfletuesi i duhet afërsisht 15% deri në 20% të kohës totale të ekzekutimit për të analizuar JavaScript. Unë nuk dola me numrat. Këto janë statistika nga aplikacionet dhe faqet e internetit të botës reale që përdorin JavaScript në një mënyrë ose në një tjetër. Tani 15% mund të mos ju duket shumë, por më besoni, është. Një SPA tipike ngarkon rreth 0,4 MB JavaScript dhe shfletuesit i duhen afërsisht 370 ms për ta analizuar atë. Përsëri, ju mund të thoni, mirë, kjo nuk është aq shumë. Nuk është shumë në vetvete. Megjithatë, kini parasysh se kjo është vetëm koha e nevojshme për të analizuar kodin JavaScript në AST. Kjo nuk përfshin vetë ekzekutimin ose ndonjë nga proceset e mbetura që ndodhin gjatë një ngarkimi të faqes, si p.sh. "CSS dhe HTML rendering". Dhe e gjithë kjo i referohet vetëm desktopit. Sapo hyjmë në celular, gjërat shpejt bëhen më të ndërlikuara. Koha e shpenzuar për analizim shpesh mund të jetë dy deri në pesë herë më shumë në telefon sesa në desktop.

Grafiku i mësipërm tregon kohën e analizimit të paketës 1 MB të JavaScript-it në pajisjet mobile dhe desktop të klasave të ndryshme.

Për më tepër, aplikacionet e uebit po bëhen më komplekse çdo minutë, pasi më shumë logjikë biznesi po shkon drejt klientit për të prezantuar një përvojë më të ngjashme me përdoruesit. Mund ta kuptoni lehtësisht se sa po ndikon kjo në aplikacionin/faqen tuaj të internetit. E tëra çfarë ju duhet të bëni është të hapni veglat e zhvillimit të shfletuesit dhe ta lini të masë sasinë e kohës së shpenzuar për analizimin, përpilimin dhe gjithçka tjetër që po ndodh në shfletues derisa faqja të ngarkohet plotësisht.

Fatkeqësisht, nuk ka mjete zhvilluese në shfletuesit celularë. Megjithatë, pa shqetësime. Kjo nuk do të thotë se nuk mund të bëni asgjë për këtë. Kjo është arsyeja pse ekzistojnë mjete si "DeviceTiming". Mund t'ju ndihmojë të matni kohën e analizimit dhe ekzekutimit për skriptet në një mjedis të kontrolluar. Ai funksionon duke mbështjellë skriptet lokale me kodin e instrumenteve, në mënyrë që sa herë që faqet tuaja goditen nga pajisje të ndryshme, të mund të matni në nivel lokal kohën e analizimit dhe ekzekutimit.

E mira është se motorët JavaScript bëjnë shumë për të shmangur punën e tepërt dhe për t'u optimizuar më shumë. Këtu janë disa gjëra që bëjnë motorët nëpër shfletuesit kryesorë.

V8 për shembull bën transmetimin e skriptit dhe ruajtjen e kodeve në memorie. Transmetimi i skriptit do të thotë që skriptet e asinkronizuara dhe të shtyra analizohen në një temë të veçantë sapo të fillojë shkarkimi. Kjo tregon se analizimi është bërë pothuajse menjëherë pasi të shkarkohet skripti. Rezulton që faqet të ngarkohen rreth 10% më shpejt.

Kodi JavaScript zakonisht përpilohet në bytecode në çdo vizitë të faqes. Ky bajtkod, sidoqoftë, më pas hiqet pasi përdoruesi të lundrojë në një faqe tjetër. Kjo ndodh sepse kodi i përpiluar varet shumë nga gjendja dhe konteksti i makinës në kohën e përpilimit. Këtu Chrome 42 prezanton memorien e memories së bytekodit. Është një teknikë që ruan kodin e përpiluar në nivel lokal, kështu që kur përdoruesi kthehet në të njëjtën faqe, të gjithë hapat si shkarkimi, analizimi dhe përpilimi mund të anashkalohen. Kjo i lejon Chrome të kursejë rreth 40% në kohën e analizimit dhe përpilimit. Plus, kjo gjithashtu rezulton në kursimin e jetëgjatësisë së baterisë së pajisjeve celulare.

Në Opera, motori Carakan mund të ripërdorë daljen e përpiluesit nga një program tjetër që është kompiluar së fundmi. Nuk ka asnjë kërkesë që kodi të jetë nga e njëjta faqe apo edhe domeni. Kjo teknikë e ruajtjes në memorie është në të vërtetë shumë efektive dhe mund të anashkalojë plotësisht hapin e përpilimit. Ai mbështetet në sjelljen tipike të përdoruesit dhe skenarët e shfletimit: sa herë që përdoruesi ndjek një udhëtim të caktuar përdoruesi në aplikacion/faqe, i njëjti kod JavaScript ngarkohet. Sidoqoftë, motori Carakan është zëvendësuar prej kohësh nga V8 i Google.

Motori SpiderMonkey i përdorur nga Firefox nuk ruan çdo gjë. Ai mund të kalojë në një fazë monitorimi ku numëron sa herë është duke u ekzekutuar një skenar i caktuar. Bazuar në këtë numërim, ai përcakton se cilat pjesë të kodit janë të nxehta dhe duhet të optimizohen.

Natyrisht, disa marrin vendimin të mos bëjnë asgjë. Maciej Stachowiak, zhvilluesi kryesor i Safari, deklaron se Safari nuk bën asnjë memorie të bajtkodit të përpiluar. Është diçka që ata e kanë konsideruar, por nuk e kanë zbatuar pasi gjenerimi i kodit është më pak se 2% e kohës totale të ekzekutimit.

Këto optimizime nuk ndikojnë drejtpërdrejt në analizimin e kodit burimor JavaScript, por ato patjetër bëjnë çmos për ta anashkaluar plotësisht atë. Çfarë mund të jetë një optimizim më i mirë sesa të mos e bësh plotësisht?

Ka shumë gjëra që mund të bëjmë për të përmirësuar kohën fillestare të ngarkimit të aplikacioneve tona. Ne mund të minimizojmë sasinë e JavaScript që dërgojmë: më pak skript, më pak analizim, më pak ekzekutim. Për ta bërë këtë, ne mund të dorëzojmë vetëm kodin e kërkuar në një rrugë specifike në vend që të ngarkojmë një pikë të madhe të gjithçkaje. Për shembull, modeli PRPL predikon këtë lloj shpërndarjeje kodi. Përndryshe, ne mund të kontrollojmë varësitë tona dhe të shohim nëse ka ndonjë gjë të tepërt që mund të mos bëjë asgjë më shumë, veçse të fryjë bazën tonë të kodit. Megjithatë, këto gjëra meritojnë një temë më vete.

Qëllimi i këtij artikulli është të diskutojë se çfarë ne si zhvillues të uebit mund të bëjmë për të ndihmuar analizuesin JavaScript të bëjë punën e tij më shpejt. Dhe ka. Analizuesit modernë JavaScript përdorin heuristikë për të përcaktuar nëse një pjesë e caktuar e kodit do të ekzekutohet menjëherë ose ekzekutimi i tij do të shtyhet për ca kohë në të ardhmen. Bazuar në këto heuristika, analizuesi do të bëjë analizimin e etur ose dembel. Analizimi i etur kalon përmes funksioneve që duhet të përpilohen menjëherë. Ai bën tre gjëra kryesore: ndërton AST, ndërton hierarkinë e fushës dhe gjen të gjitha gabimet sintaksore. Analiza dembel, nga ana tjetër, përdoret vetëm për funksionet që nuk kanë nevojë të përpilohen ende. Nuk ndërton një AST dhe nuk i gjen të gjitha gabimet sintaksore. Ai ndërton vetëm hierarkinë e fushës së veprimit e cila kursen rreth gjysmën e kohës në krahasim me vlerësimin e etur.

Është e qartë se ky nuk është një koncept i ri. Edhe shfletuesit si IE 9 mbështesin një lloj të tillë optimizimi, megjithëse në një mënyrë mjaft rudimentare në krahasim me mënyrën se si funksionojnë analizuesit e sotëm.

Pra, le të shohim një shembull se si funksionon kjo. Thuaj se kemi disa JavaScript që ka copëzimin e kodit të mëposhtëm:

Ashtu si në shembullin e mëparshëm, kodi futet në analizuesin i cili bën analizën sintaksore dhe nxjerr një AST. Pra, ne kemi diçka në vijat e:

Deklarata e funksionit të foo e cila pranon një argument (x). Ka një deklaratë kthimi. Funksioni kthen rezultatin e veprimit + mbi x dhe 10.

Deklarata e funksionit të bar që pranon dy argumente (x dhe y). Ka një deklaratë kthimi. Funksioni kthen rezultatin e veprimit + mbi x dhe y.

Bëni një thirrje funksioni në shirit me dy argumente 40 dhe 2.

Bëni një thirrje funksioni në console.log me një argument rezultatin e thirrjes së mëparshme të funksionit.

Pra, çfarë ndodhi vetëm? Analizuesi pa një deklaratë të funksionit foo, një deklaratë të funksionit të shiritit, një thirrje të funksionit të shiritit dhe një thirrje të funksionit console.log. Por prisni një minutë… ka një punë shtesë të bërë nga analizuesi që është krejtësisht i parëndësishëm. Ky është analizimi i funksionit foo. Pse është e parëndësishme? Sepse funksioni foo nuk thirret kurrë (ose të paktën jo në atë moment në kohë). Ky është një shembull i thjeshtë dhe mund të duket si diçka e pazakontë, por në shumë aplikacione të botës reale, shumë nga funksionet e deklaruara nuk thirren kurrë.

Këtu në vend që të analizojmë funksionin foo, mund të vërejmë se është deklaruar pa specifikuar se çfarë bën. Analiza aktuale bëhet kur është e nevojshme, pak para se funksioni të ekzekutohet. Dhe po, analizimi dembel ende duhet të gjejë të gjithë trupin e funksionit dhe të bëjë një deklaratë për të, por kaq. Nuk ka nevojë për pemën e sintaksës sepse nuk do të përpunohet ende. Plus, ai nuk shpërndan memorie nga grumbulli i cili zakonisht merr një sasi të mjaftueshme të burimeve të sistemit. Me pak fjalë, kapërcimi i këtyre hapave sjell një përmirësim të madh të performancës.

Pra, në shembullin e mëparshëm, analizuesi në të vërtetë do të bënte diçka si më poshtë.

Vini re se deklarata e funksionit foo pranohet, por kaq. Asgjë më shumë nuk është bërë për të hyrë në trupin e vetë funksionit. Në këtë rast, trupi i funksionit ishte vetëm një deklaratë e vetme kthimi. Megjithatë, si në shumicën e aplikacioneve të botës reale, ai mund të jetë shumë më i madh, duke përmbajtur deklarata të shumëfishta kthimi, kushte, unaza, deklarata të variablave dhe madje edhe deklarata të funksioneve të ndërlidhura. Dhe e gjithë kjo do të ishte një humbje e plotë e kohës dhe burimeve të sistemit pasi funksioni nuk do të thirret kurrë.

Është një koncept mjaft i thjeshtë, por në realitet, zbatimi i tij nuk është aspak i thjeshtë. Këtu treguam një shembull që nuk është padyshim i vetmi rast. E gjithë metoda zbatohet për funksionet, unazat, kushtet, objektet, etj. Në thelb, gjithçka që duhet të analizohet.

Për shembull, këtu është një model mjaft i zakonshëm për zbatimin e moduleve në JavaScript.

Ky model njihet nga shumica e analizuesve modernë të JavaScript dhe është një sinjal se kodi brenda duhet të analizohet me padurim.

Pra, pse analizuesit nuk analizojnë gjithmonë me dembelizëm? Nëse diçka analizohet me dembelizëm, ajo duhet të ekzekutohet menjëherë, dhe kjo në fakt do ta bëjë atë më të ngadaltë. Do të bëjë një analizë të vetme dembel dhe një analizë tjetër të etur menjëherë pas të parës. Kjo do të rezultojë në një ngadalësim prej 50% në krahasim me analizimin e tij me padurim.

Tani që kemi një kuptim bazë të asaj që po ndodh në prapaskenë, është koha të mendojmë se çfarë mund të bëjmë për t'i dhënë dorën analizuesit. Ne mund ta shkruajmë kodin tonë në atë mënyrë që funksionet të analizohen në kohën e duhur. Ekziston një model që njihet nga shumica e analizuesve: mbështjellja e një funksioni në kllapa. Ky është pothuajse gjithmonë një sinjal pozitiv për analizuesin që funksioni do të ekzekutohet menjëherë. Nëse analizuesi sheh një kllapa hapëse dhe menjëherë pas kësaj një deklaratë funksioni, ai do ta analizojë me padurim funksionin. Ne mund ta ndihmojmë analizuesin duke deklaruar në mënyrë eksplicite një funksion si të tillë që do të ekzekutohet menjëherë.

Le të themi se kemi një funksion të quajtur foo.

Meqenëse nuk ka asnjë shenjë të dukshme që funksioni do të ekzekutohet menjëherë, shfletuesi do të bëjë një analizë dembel. Megjithatë, ne jemi të sigurt se kjo nuk është e saktë, kështu që ne mund të bëjmë dy gjëra.

Së pari, ne e ruajmë funksionin në një variabël:

Vini re se emrin e funksionit e kemi lënë midis fjalës kyçe të funksionit dhe kllapave hapëse përpara argumenteve të funksionit. Kjo nuk është e nevojshme, por rekomandohet pasi në rastin e një përjashtimi të hedhur, stacktrace do të përmbajë emrin aktual të funksionit në vend që thjesht të thotë ‹anonim›.

Analizuesi ende do të bëjë një analizë dembel. Kjo mund të parandalohet duke shtuar një detaj të vogël: mbështjelljen e funksionit në kllapa.

Në këtë pikë, kur analizuesi sheh kllapat e hapjes përpara fjalës kyçe të funksionit, ai do të bëjë menjëherë një analizë të etur.

Kjo mund të jetë mjaft e vështirë për t'u menaxhuar me dorë pasi ne do të duhet të dimë se në cilat raste analizuesi do të vendosë të analizojë kodin me përtesë ose me padurim. Gjithashtu, do të na duhet të kalojmë kohë duke menduar nëse një funksion i caktuar do të thirret menjëherë apo jo. Ne me siguri nuk duam ta bëjmë këtë. E fundit, por jo më pak e rëndësishme, kjo do ta bëjë kodin tonë më të vështirë për t'u lexuar dhe kuptuar. Për të na ndihmuar ta bëjmë këtë, mjete si Optimize.js vijnë në shpëtim. Qëllimi i tyre i vetëm është të optimizojnë kohën fillestare të ngarkimit të kodit burimor JavaScript. Ata bëjnë analiza statike të kodit tuaj dhe e modifikojnë atë në atë mënyrë që funksionet që duhet të ekzekutohen së pari të mbështillen në kllapa, në mënyrë që shfletuesi të mund t'i analizojë me padurim dhe t'i përgatisë për ekzekutim.

Pra, ne po kodojmë si zakonisht dhe ka një pjesë kodi që duket si ky:

Gjithçka duket mirë, funksionon siç pritej dhe është e shpejtë sepse ka një kllapa hapëse përpara deklarimit të funksionit. E madhe. Sigurisht, përpara se të hyjmë në prodhim, ne duhet të minimizojmë kodin tonë për të kursyer bajt. Kodi i mëposhtëm është dalja e minifikuesit:

Duket në rregull. Kodi funksionon si më parë. Megjithatë diçka mungon. Minifikuesi ka hequr kllapat që mbështjellin funksionin dhe në vend të kësaj ka vendosur një pikëçuditëse të vetme përpara funksionit. Kjo do të thotë që analizuesi do ta kapërcejë këtë dhe do të bëjë një analizë dembel. Në krye, për të qenë në gjendje të ekzekutojë funksionin, do të bëjë një analizë të etur menjëherë pas atij dembel. E gjithë kjo e bën kodin tonë të funksionojë më ngadalë. Për fat të mirë, ne kemi mjete si Optimize.js që bëjnë punën e vështirë për ne. Kalimi i kodit të minifikuar përmes Optimize.js do të prodhojë daljen e mëposhtme:

Kjo është më shumë si ajo. Tani kemi më të mirën nga të dy botët: kodi është minimizuar dhe analizuesi po identifikon siç duhet se cilat funksione duhet të analizohen me padurim dhe cilat me dembelizëm.

Përpilimi paraprak

Por pse nuk mund ta bëjmë gjithë këtë punë nga ana e serverit? Në fund të fundit, është shumë më mirë ta bëni atë një herë dhe t'i shërbeni rezultatet klientit në vend që të detyroni çdo klient të bëjë punën çdo herë. Epo, ekziston një diskutim i vazhdueshëm nëse motorët duhet të ofrojnë një mënyrë për të ekzekutuar skriptet të parapërpiluara në mënyrë që kjo kohë të mos harxhohet në shfletues. Në thelb, ideja është që të kemi një mjet nga ana e serverit që mund të gjenerojë bytekod të cilin do të na duhet vetëm ta transferojmë përmes telit dhe ta ekzekutojmë në anën e klientit. Atëherë do të shihnim disa ndryshime të mëdha në kohën e fillimit. Mund të tingëllojë joshëse, por nuk është aq e thjeshtë. Kjo mund të ketë efektin e kundërt pasi do të ishte më i madh dhe me shumë mundësi do të duhej të nënshkruante kodin dhe ta përpunonte atë për arsye sigurie. Ekipi V8, për shembull, po punon në shmangien e brendshme të riparimit, në mënyrë që përgatitja paraprake të mos jetë aq e dobishme.

Disa këshilla që mund të ndiqni për t'i shërbyer aplikacionit tuaj përdoruesve sa më shpejt që të jetë e mundur

  • Kontrolloni varësitë tuaja. Hiqni qafe gjithçka që nuk është e nevojshme.
  • Ndani kodin tuaj në copa më të vogla në vend që të ngarkoni një pikë të madhe.
  • Shtyjeni ngarkimin e JavaScript kur është e mundur. Mund të ngarkoni vetëm pjesët e kërkuara të kodit bazuar në itinerarin aktual.
  • Përdorni mjetet e devijimit dhe DeviceTiming për të zbuluar se ku është pengesa.
  • Përdor mjete si Optimize.js për të ndihmuar analizuesin të vendosë se kur të analizojë me padurim dhe kur me dembelizëm.

SessionStack është një mjet që rikrijon vizualisht gjithçka që u ndodhi përdoruesve fundorë në kohën kur ata përjetuan një problem gjatë ndërveprimit me një aplikacion ueb. Mjeti nuk e riprodhon seancën si një video aktuale, por simulon të gjitha ngjarjet në një mjedis me sandbox në shfletues. Kjo sjell disa implikime, për shembull në skenarë ku baza e kodit të faqes së ngarkuar aktualisht bëhet e madhe dhe komplekse.

Teknikat e mësipërme janë diçka që ne kohët e fundit filluam të inkorporojmë në procesin e zhvillimit të SessionStack. Optimizime të tilla na lejojnë të ngarkojmë SessionStack më shpejt. Sa më i shpejtë SessionStack mund të lirojë burimet e shfletuesit, aq më e qetë dhe më e natyrshme do të jetë përvoja e përdoruesit që mjeti do të ofrojë kur ngarkoni dhe shikoni seancat e përdoruesit.

Ekziston një plan falas nëse dëshironi të "provoni SessionStack".

Burimet