Code Velocity
Zana za Waendelezaji

Utendaji wa Mistari ya Tofauti: Juhudi za GitHub Kuboresha

·7 dakika kusoma·GitHub·Chanzo asili
Shiriki
Mchoro unaoonyesha maboresho ya utendaji katika mistari ya tofauti ya GitHub, ukisisitiza kupungua kwa nodi za DOM na 'JavaScript heap' katika mwonekano ulioboreshwa.

Juhudi za GitHub: Kuboresha Mistari ya Tofauti kwa Utendaji Bora

'Pull requests' ndio kiini chenye uhai cha GitHub, ambapo wahandisi wengi hujitolea sehemu kubwa ya maisha yao ya kikazi. Kutokana na ukubwa mkubwa wa GitHub, kushughulikia 'pull requests' zinazotoka marekebisho madogo ya mstari mmoja hadi mabadiliko makubwa yanayohusu maelfu ya faili na mamilioni ya mistari, uzoefu wa ukaguzi lazima ubaki haraka sana na wenye mwitikio. Uzinduzi wa hivi karibuni wa uzoefu mpya unaotegemea React kwa kichupo cha Files changed, sasa kikiwa ndicho cha msingi kwa watumiaji wote, uliashiria uwekezaji muhimu katika kuhakikisha utendaji thabiti, hasa kwa 'pull requests' hizi kubwa zenye changamoto. Ahadi hii ilihusisha kushughulikia mara kwa mara matatizo magumu kama vile uwasilishaji ulioboreshwa, ucheleweshaji wa mwingiliano, na matumizi ya kumbukumbu.

Kabla ya maboresho haya, wakati watumiaji wengi walifurahia uzoefu wenye mwitikio, 'pull requests' kubwa zilisababisha kupungua kwa utendaji unaoonekana. Kesi kali zilionyesha JavaScript heap ikizidi 1 GB, idadi ya nodi za DOM ikipita 400,000, na mwingiliano wa ukurasa ukawa mzito sana au hata kutoweza kutumika. Metriki muhimu za mwitikio kama Mwingiliano hadi Rangi Inayofuata (INP) zilipanda juu ya viwango vinavyokubalika, na kusababisha hisia inayoonekana ya kuchelewa kwa ingizo kwa watumiaji. Makala haya yanaangazia safari ya kina ambayo GitHub ilifanya ili kuboresha kwa kiasi kikubwa metriki hizi kuu za utendaji, ikibadilisha uzoefu wa ukaguzi wa tofauti.

Kushughulikia Vikwazo vya Utendaji: Mbinu ya Mikakati Nyingi

Wakati wa kuanzisha uchunguzi wa utendaji kwa kichupo cha Files changed, ilionekana haraka kuwa suluhisho moja la "risasi ya fedha" halingetosha. Mbinu zilizoundwa kuhifadhi kila kipengele na tabia asili ya kivinjari mara nyingi zilifikia kikomo na mizigo mikubwa ya data. Kinyume chake, hatua za kupunguza matatizo zilizolenga tu kuzuia matukio mabaya zaidi zinaweza kuanzisha mabadilishano yasiyofaa kwa ukaguzi wa kila siku.

Badala yake, timu ya uhandisi ya GitHub iliendeleza seti kamili ya mikakati, kila moja ikiwa imeundwa kwa uangalifu kushughulikia ukubwa na ugumu maalum wa 'pull requests'. Mikakati hii ilijengwa juu ya mada kuu tatu:

  1. Maboresho Yanayolengwa kwa Vijenzi vya Mistari ya Tofauti: Kuongeza ufanisi wa uzoefu wa msingi wa tofauti kwa 'pull requests' nyingi. Hii ilihakikisha ukaguzi wa kati na mkubwa unabaki haraka bila kuathiri utendaji unaotarajiwa kama vile utafutaji wa asili wa ukurasa.
  2. Upungufu wa Taratibu na Utumizi wa 'Virtualization': Kuhakikisha matumizi kwa 'pull requests' kubwa zaidi kwa kuipa kipaumbele mwitikio na utulivu, na kupunguza kwa akili kinachowasilishwa kwa wakati wowote.
  3. Uwekezaji katika Vijenzi vya Msingi na Maboresho ya Uwasilishaji: Kutekeleza maboresho yanayotoa manufaa yanayoongezeka katika kila ukubwa wa 'pull request', bila kujali hali maalum ya mtumiaji ya kutazama.

Nguzo hizi za kimkakati ziliongoza juhudi za timu, zikiwaruhusu kushughulikia kwa utaratibu mizizi ya matatizo ya utendaji na kuandaa mazingira kwa maboresho ya usanifu yaliyofuata.

Kuchambua V1: Gharama ya Mstari wa Tofauti wa Gharama Kubwa

Utekelezaji wa awali wa GitHub unaotegemea React, unaorejelewa kama v1, uliweka msingi kwa mwonekano wa kisasa wa tofauti. Toleo hili lilikuwa juhudi za dhati kuhamisha mwonekano wa kawaida wa Rails kwenda React, ukipeana kipaumbele uundaji wa vijenzi vidogo, vinavyoweza kutumika tena vya React na kudumisha muundo wazi wa mti wa DOM. Hata hivyo, mbinu hii, ingawa ilikuwa na mantiki hapo mwanzo, ilijithibitisha kuwa kikwazo kikubwa kwa kiwango kikubwa.

Katika v1, uwasilishaji wa kila mstari wa tofauti ulikuwa operesheni ya gharama kubwa. Mstari mmoja katika mwonekano uliounganishwa kwa kawaida ulitafsiriwa kuwa vipengele takriban 10 vya DOM, huku mwonekano uliogawanywa ukihitaji karibu 15. Idadi hii ingeongezeka zaidi kwa uainishaji wa sintaksia, ikianzisha <span> tags nyingi zaidi. Katika tabaka la React, tofauti zilizounganishwa zilikuwa na angalau vijenzi nane kwa kila mstari, na maoni yaliyogawanywa angalau 13. Hizi zilikuwa idadi za msingi, na hali za ziada za UI kama vile maoni, 'hover', na 'focus' zikiongeza vijenzi zaidi.

Usanifu wa v1 pia uliteseka kutokana na kuongezeka kwa 'React event handlers'. Ingawa zilionekana zisizo na madhara kwa kiwango kidogo, mstari mmoja wa tofauti ungeweza kubeba vishughulikiaji vya matukio 20 au zaidi. Vinapozidishwa katika maelfu ya mistari katika 'pull request' kubwa, hii iliongezeka haraka, na kusababisha mzigo mkubwa na kuongezeka kwa matumizi ya JavaScript heap. Ugumu huu hauathiri tu utendaji bali pia ulifanya maendeleo na matengenezo kuwa magumu zaidi. Ubunifu wa awali, ufanisi kwa data yenye mipaka, ulijitahidi sana ulipokabiliana na asili isiyo na mipaka ya ukubwa mbalimbali wa 'pull request' za GitHub.

Kwa muhtasari, kwa kila mstari wa tofauti wa v1, mfumo ulikuwa na:

  • Angalau vipengele 10-15 vya mti wa DOM
  • Angalau Vijenzi 8-13 vya React
  • Angalau Vishughulikiaji 20 vya Matukio vya React
  • Vijenzi Vidogo, Vinavyoweza Kutumika Tena vya React vingi

Usanifu huu ulihusisha moja kwa moja ukubwa mkubwa wa 'pull requests' na INP polepole na kuongezeka kwa matumizi ya JavaScript heap, na hivyo kuhitaji tathmini na ubunifu upya wa kimsingi.

Kuleta Mapinduzi katika Uwasilishaji: Athari za Maboresho ya V2

Mabadiliko kuelekea v2 yaliashiria marekebisho makubwa ya usanifu, yakilenga mabadiliko madogo lakini yenye athari kubwa. Timu ilikubali falsafa kwamba "hakuna mabadiliko madogo sana linapokuja suala la utendaji, hasa kwa kiwango kikubwa." Mfano mkuu ulikuwa kuondolewa kwa <code> tags zisizo za lazima kutoka seli za namba za mistari. Ingawa kuondoa nodi mbili za DOM kwa kila mstari wa tofauti kunaweza kuonekana kidogo, katika mistari 10,000, hii mara moja ililingana na nodi 20,000 chache kwenye DOM, ikionyesha jinsi maboresho yaliyolengwa, ya nyongeza yanavyotoa maboresho makubwa.

Ulinganisho wa kuona hapa chini unaangazia kupungua kwa ugumu kutoka v1 hadi v2 katika kiwango cha vijenzi:

Vijenzi vya Tofauti vya V1 na HTML. Tulikuwa na vijenzi 8 vya React kwa mstari mmoja wa tofauti. Vijenzi vya Tofauti vya V2 na HTML. Tulikuwa na vijenzi 3 vya React kwa mstari mmoja wa tofauti.

Usanifu Rahisi wa Vijenzi

Ubunifu mkuu katika v2 ulihusisha kurahisisha mti wa vijenzi. Timu ilihama kutoka vijenzi nane vya React kwa kila mstari wa tofauti hadi viwili. Hili lilifanikishwa kwa kuondoa miti ya vijenzi iliyoingiliana sana na kuunda vijenzi maalum kwa kila mstari wa tofauti uliogawanywa na uliounganishwa. Ingawa hii ilileta kurudia msimbo kidogo, ilirahisisha kwa kiasi kikubwa ufikiaji wa data na kupunguza ugumu wa jumla. Ushughulikiaji wa matukio pia uliwekwa kati, sasa ukisimamiwa na kishughulikiaji kimoja cha kiwango cha juu kwa kutumia thamani za data-attribute, ikichukua nafasi ya vishughulikiaji vingi vya kibinafsi vya matukio vya v1. Mbinu hii iliboresha kwa kiasi kikubwa msimbo na utendaji.

Usimamizi Akili wa Hali na Ufikiaji wa Data wa O(1)

Labda mabadiliko yenye athari kubwa zaidi yalikuwa kuhamisha hali ngumu ya programu, kama vile kutoa maoni na menyu za muktadha, hadi kwenye vijenzi vya watoto vilivyowasilishwa kwa masharti. Katika mazingira kama GitHub, ambapo 'pull requests' zinaweza kuzidi maelfu ya mistari, si ufanisi kwa kila mstari kubeba hali ngumu ya kutoa maoni wakati ni sehemu ndogo tu ndiyo itakuwa na maoni. Kwa kuhamisha hali hii kwenye vijenzi vilivyoingiliana, jukumu kuu la kijenzi cha mstari wa tofauti likawa uwasilishaji wa msimbo pekee, likilingana na Kanuni ya Wajibu Mmoja.

Zaidi ya hayo, v2 ilishughulikia suala la utafutaji wa O(n) na useEffect hooks nyingi kupita kiasi zilizoisumbua v1. Timu ilipitisha mkakati wa sehemu mbili: kuzuia kabisa matumizi ya useEffect kwenye kiwango cha juu cha faili za tofauti na kuanzisha sheria za 'linting' kuzuia kuanzishwa kwake tena katika vijenzi vya kufunga mstari. Hii ilihakikisha 'memoization' sahihi na tabia inayotabirika. Wakati huo huo, mashine za hali za kimataifa na za tofauti zilibuniwa upya kutumia utafutaji wa O(1) usiobadilika kwa kutumia vitu vya JavaScript Map. Hii iliruhusu 'selectors' za haraka na thabiti kwa operesheni za kawaida kama vile uteuzi wa mstari na usimamizi wa maoni, ikiongeza kwa kiasi kikubwa ubora wa msimbo, kuboresha utendaji, na kupunguza ugumu kwa kudumisha miundo ya data iliyopambwa, iliyopangwa. Mbinu hii makini ya kuboresha mitiririko ya kazi ya waendelezaji na usanifu wa msingi inahakikisha mfumo imara na unaoweza kupanuka.

Athari Inayopimika: V2 Inaleta Manufaa Yanayopimika

Maboresho ya usanifu na kiwango cha msimbo yaliyotekelezwa kwa uangalifu katika v2 yalileta maboresho makubwa, yanayopimika katika metriki muhimu za utendaji. Mfumo mpya unafanya kazi haraka zaidi, na kupungua kwa kiasi kikubwa kwa matumizi ya JavaScript heap na alama za INP. Jedwali lifuatalo linaonyesha maboresho makubwa yaliyozingatiwa kwenye 'pull request' wakilishi yenye mabadiliko ya mistari 10,000 katika mpangilio wa tofauti uliogawanywa:

Metrikiv1v2Uboreshaji
JavaScript Heap1GB+250MB75%
Nodi za DOM400,000+80,00080%
INP p951000ms+100ms90%

Takwimu hizi zinasisitiza mafanikio ya mkakati wa pande nyingi wa GitHub. Upungufu wa 75% katika ukubwa wa JavaScript heap na upungufu wa 80% wa nodi za DOM hautafsiri tu kuwa alama ndogo ya kivinjari bali pia huchangia moja kwa moja kwenye kiolesura thabiti na chenye mwitikio zaidi. Uboreshaji unaovutia zaidi, upungufu wa 90% katika INP p95 (asilimia ya 95 ya ucheleweshaji wa mwingiliano), unamaanisha kuwa 95% ya mwingiliano wa mtumiaji sasa unakamilika ndani ya milisekunde 100 tu, karibu kuondoa ucheleweshaji wa ingizo uliokuwa ukisumbua 'pull requests' kubwa katika v1. Hii inaboresha kwa kiasi kikubwa uzoefu wa mtumiaji, na kufanya ukaguzi mkubwa wa msimbo uhisiwe kuwa rahisi na wenye mwitikio kama wale wadogo.

Ahadi ya GitHub ya uboreshaji endelevu, inayoonekana kupitia uchunguzi huu wa kina wa uboreshaji wa mistari ya tofauti, ni ushahidi wa kujitolea kwao kutoa jukwaa la waendelezaji la kiwango cha dunia. Kwa kuchambua kwa uangalifu vikwazo vya utendaji na kutekeleza suluhisho za usanifu zilizolengwa, hawajatatua tu masuala muhimu ya upanuzi bali pia wameweka kiwango kipya cha mwitikio katika bidhaa yao kuu. Kuzingatia huku utendaji kunahakikisha kwamba wahandisi wanaweza kujishughulisha kwa ufanisi katika kazi muhimu kama vile ukaguzi wa msimbo, hatimaye kusababisha ubora wa msimbo na usalama wa hali ya juu na mazingira ya maendeleo yenye tija zaidi.

Maswali Yanayoulizwa Mara kwa Mara

What is the 'Files changed' tab in GitHub pull requests and why was its performance critical?
The 'Files changed' tab is a core component of GitHub's pull request workflow, allowing engineers to review code modifications. Its performance is critical because it's where developers spend significant time, and slowdowns, especially with large pull requests, can severely impede productivity and user experience. GitHub prioritized its optimization to ensure responsiveness across all scales of code changes, from minor fixes to extensive refactorings, which can involve millions of lines across thousands of files. Maintaining a smooth and efficient review process is paramount for collaborative development.
What were the primary performance challenges GitHub faced with large pull requests in the v1 architecture?
In its initial React-based architecture (v1), GitHub encountered significant performance degradation when handling large pull requests. Key issues included the JavaScript heap exceeding 1 GB, DOM node counts soaring past 400,000, and page interactions becoming extremely sluggish or even unusable. The Interaction to Next Paint (INP) metric, which measures responsiveness, showed unacceptably high values. These problems stemmed from an inefficient rendering strategy where each diff line was resource-intensive, with too many DOM elements, React components, and event handlers, particularly in cases involving thousands of lines of code.
How did GitHub approach solving the complex performance issues, moving beyond a 'silver bullet' solution?
Recognizing that no single solution would address the diverse range of pull request sizes and complexities, GitHub adopted a multi-faceted strategic approach. They focused on three core themes: targeted optimizations for diff-line components to keep medium and large reviews fast, graceful degradation with virtualization to maintain usability for the largest pull requests by limiting rendered content, and investing in foundational components and rendering improvements to yield compounding benefits across all pull request sizes. This comprehensive strategy allowed them to tailor solutions to specific problem areas.
What were the key limitations of the 'v1' diff rendering architecture that made it unsustainable for scale?
The v1 architecture, while initially sensible for smaller diffs, proved unsustainable for large-scale pull requests. Each diff line was costly, requiring 10-15 DOM elements, 8-13 React components, and over 20 event handlers. This was compounded by deep component nesting, excessive `useEffect` hooks, and O(n) data lookups, leading to unnecessary re-renders and increased complexity. The abstraction layers, meant to share code, inadvertently added overhead by carrying logic for both split and unified views, even when only one was active. This design led to a significant increase in JavaScript heap, DOM count, and poor INP scores for larger diffs.
What specific architectural changes were implemented in 'v2' to drastically improve diff line performance?
The v2 architecture introduced several critical changes. It streamlined the component tree, reducing React components per diff line from eight to two by creating dedicated components for split and unified views, even with some code duplication. Event handling was centralized to a single top-level handler using `data-attribute` values, replacing numerous individual handlers. Complex app state, such as commenting features, was moved into conditionally rendered child components, ensuring that diff lines primarily focused on rendering code. Furthermore, v2 restricted `useEffect` hooks to top-level diff files and adopted O(1) constant-time data access using `JavaScript Map` for efficient state lookups, significantly reducing re-renders and improving data management.
How did the GitHub engineering team achieve quantifiable improvements in JavaScript heap, DOM nodes, and INP metrics with v2?
The cumulative effect of v2's architectural changes led to substantial quantifiable improvements. For a pull request with 10,000 line changes, the JavaScript heap size was reduced from 1GB+ to 250MB, a 75% improvement. DOM nodes decreased from 400,000+ to 80,000, an 80% reduction. The Interaction to Next Paint (INP) p95 (95th percentile) saw an astounding 90% improvement, dropping from 1000ms+ to just 100ms. These results were achieved through meticulous optimization, including removing extraneous DOM elements, simplifying the React component structure, centralizing event handling, and optimizing state management and data access patterns, leading to a much faster and more responsive user experience.
What is Interaction to Next Paint (INP) and why is its improvement significant for GitHub's user experience?
Interaction to Next Paint (INP) is a crucial web performance metric that assesses a page's responsiveness by measuring the latency of all interactions made by a user with the page. It records the time from when a user interacts (e.g., click, tap, keypress) until the next frame is painted to the screen, reflecting the visual feedback of that interaction. For GitHub, a high INP meant users experienced noticeable input lag, making the platform feel slow and unresponsive. By reducing INP p95 from over 1000ms to 100ms in v2, GitHub significantly enhanced the perceived speed and fluidity of the 'Files changed' tab, ensuring a smoother and more satisfying developer experience, especially during code review.

Baki na Habari

Pokea habari za hivi karibuni za AI kwenye barua pepe yako.

Shiriki