title: "Rendiment de les línies Diff: L'ardu camí de GitHub per optimitzar" slug: "the-uphill-climb-of-making-diff-lines-performant" date: "2026-04-06" lang: "ca" source: "https://github.blog/engineering/architecture-optimization/the-uphill-climb-of-making-diff-lines-performant/" category: "Eines per a Desenvolupadors" keywords:
- GitHub
- Peticions d'extracció
- Optimització del rendiment
- Línies diff
- Desenvolupament amb React
- Rendiment web
- Optimització del DOM
- Heap de JavaScript
- Interaction to Next Paint (INP)
- Arquitectura de programari
- Disseny de components
- Enginyeria de front-end meta_description: "L'equip d'enginyeria de GitHub detalla el seu rigorós viatge per optimitzar el rendiment de les línies diff en les peticions d'extracció, reduint dràsticament el heap de JavaScript, els nodes DOM i millorant l'INP." image: "/images/articles/the-uphill-climb-of-making-diff-lines-performant.png" image_alt: "Diagrama que mostra les millores de rendiment a les línies diff de GitHub, destacant la reducció de nodes DOM i del heap de JavaScript en una vista optimitzada." quality_score: 94 content_score: 93 seo_score: 95 companies:
- GitHub schema_type: "NewsArticle" reading_time: 7 faq:
- question: "Què és la pestanya 'Fitxers canviats' a les peticions d'extracció de GitHub i per què era crític el seu rendiment?" answer: "La pestanya 'Fitxers canviats' és un component central del flux de treball de les peticions d'extracció de GitHub, que permet als enginyers revisar les modificacions del codi. El seu rendiment és crític perquè és on els desenvolupadors passen un temps considerable, i les ralentitzacions, especialment amb peticions d'extracció grans, poden dificultar greument la productivitat i l'experiència de l'usuari. GitHub va prioritzar la seva optimització per garantir la capacitat de resposta en totes les escales de canvis de codi, des de correccions menors fins a refactoritzacions extenses, que poden implicar milions de línies en milers de fitxers. Mantenir un procés de revisió fluid i eficient és fonamental per al desenvolupament col·laboratiu."
- question: "Quins van ser els principals reptes de rendiment que GitHub va afrontar amb peticions d'extracció grans en l'arquitectura v1?" answer: "En la seva arquitectura inicial basada en React (v1), GitHub va experimentar una degradació significativa del rendiment en gestionar peticions d'extracció grans. Els problemes clau incloïen que el heap de JavaScript superava 1 GB, el nombre de nodes DOM superava els 400.000, i les interaccions de la pàgina es tornaven extremadament lentes o fins i tot inutilitzables. La mètrica Interaction to Next Paint (INP), que mesura la capacitat de resposta, mostrava valors inacceptablement alts. Aquests problemes derivaven d'una estratègia de renderització ineficient on cada línia diff era intensiva en recursos, amb massa elements DOM, components de React i gestors d'esdeveniments, particularment en casos que implicaven milers de línies de codi."
- question: "Com va abordar GitHub la solució dels complexos problemes de rendiment, anant més enllà d'una solució 'bala de plata'?" answer: "Reconeixent que cap solució única abordaria la diversa gamma de mides i complexitats de les peticions d'extracció, GitHub va adoptar un enfocament estratègic multifacètic. Es van centrar en tres temes principals: optimitzacions dirigides als components de les línies diff per mantenir ràpides les revisions mitjanes i grans, degradació gràcil amb virtualització per mantenir la usabilitat en les peticions d'extracció més grans limitant el contingut renderitzat, i inversió en components fonamentals i millores de renderització per obtenir beneficis compostos en totes les mides de peticions d'extracció. Aquesta estratègia integral els va permetre adaptar solucions a àrees problemàtiques específiques."
- question: "Quines van ser les limitacions clau de l'arquitectura de renderització diff 'v1' que la van fer insostenible a escala?"
answer: "L'arquitectura v1, tot i ser inicialment raonable per a diffs més petits, va resultar insostenible per a peticions d'extracció a gran escala. Cada línia diff era costosa, requerint entre 10 i 15 elements DOM, entre 8 i 13 components de React, i més de 20 gestors d'esdeveniments. Això es va agreujar amb l'anidament profund de components, els hooks
useEffectexcessius i les consultes de dades O(n), que van provocar re-renderitzacions innecessàries i una complexitat augmentada. Les capes d'abstracció, destinades a compartir codi, van afegir inadvertidament sobrecàrrega en transportar lògica tant per a vistes dividides com unificades, fins i tot quan només una estava activa. Aquest disseny va comportar un augment significatiu del heap de JavaScript, el recompte de DOM i puntuacions INP deficients per a diffs més grans." - question: "Quins canvis arquitectònics específics es van implementar en 'v2' per millorar dràsticament el rendiment de les línies diff?"
answer: "L'arquitectura v2 va introduir diversos canvis crítics. Va simplificar l'arbre de components, reduint els components de React per línia diff de vuit a dos, creant components dedicats per a vistes dividides i unificades, fins i tot amb certa duplicació de codi. La gestió d'esdeveniments es va centralitzar en un únic gestor de nivell superior utilitzant valors
data-attribute, substituint nombrosos gestors individuals. L'estat complex de l'aplicació, com ara les funcions de comentaris, es va traslladar a components fills renderitzats condicionalment, garantint que les línies diff se centressin principalment en la renderització del codi. A més, la v2 va restringir els hooksuseEffectals fitxers diff de nivell superior i va adoptar l'accés a dades de temps constant O(1) utilitzantJavaScript Mapper a consultes d'estat eficients, reduint significativament les re-renderitzacions i millorant la gestió de dades." - question: "Com va aconseguir l'equip d'enginyeria de GitHub millores quantificables en el heap de JavaScript, els nodes DOM i les mètriques INP amb la v2?" answer: "L'efecte acumulatiu dels canvis arquitectònics de la v2 va comportar millores quantificables substancials. Per a una petició d'extracció amb 10.000 canvis de línia, la mida del heap de JavaScript es va reduir d'1GB+ a 250MB, una millora del 75%. Els nodes DOM van disminuir de 400.000+ a 80.000, una reducció del 80%. L'Interaction to Next Paint (INP) p95 (percentil 95) va experimentar una millora sorprenent del 90%, passant de 1000ms+ a només 100ms. Aquests resultats es van aconseguir mitjançant una optimització meticulosa, incloent l'eliminació d'elements DOM superflus, la simplificació de l'estructura de components de React, la centralització de la gestió d'esdeveniments i l'optimització de la gestió d'estats i dels patrons d'accés a dades, resultant en una experiència d'usuari molt més ràpida i responsiva."
- question: "Què és Interaction to Next Paint (INP) i per què la seva millora és significativa per a l'experiència d'usuari de GitHub?" answer: "Interaction to Next Paint (INP) és una mètrica crucial de rendiment web que avalua la capacitat de resposta d'una pàgina mesurant la latència de totes les interaccions realitzades per un usuari amb la pàgina. Registra el temps des que un usuari interactua (per exemple, clic, toc, pulsació de tecla) fins que es pinta el següent fotograma a la pantalla, reflectint la retroalimentació visual d'aquesta interacció. Per a GitHub, un INP alt significava que els usuaris experimentaven un retard notable en l'entrada, fent que la plataforma semblés lenta i poc reactiva. Reduint l'INP p95 de més de 1000ms a 100ms en la v2, GitHub va millorar significativament la velocitat percebuda i la fluïdesa de la pestanya 'Fitxers canviats', garantint una experiència de desenvolupador més fluida i satisfactòria, especialment durant la revisió de codi."
L'ardu camí de GitHub: Optimitzant les línies Diff per a un rendiment màxim
Les peticions d'extracció (pull requests) són el nucli vibrant de GitHub, on innombrables enginyers dediquen una part significativa de les seves vides professionals. Donada la immensa escala de GitHub, gestionar peticions d'extracció que van des de petites correccions d'una sola línia fins a canvis colossals que abasten milers de fitxers i milions de línies, l'experiència de revisió ha de romandre excepcionalment ràpida i responsiva. El recent llançament de la nova experiència basada en React per a la pestanya Fitxers canviats, ara per defecte per a tots els usuaris, va marcar una inversió fonamental per garantir un rendiment robust, especialment per a aquestes grans i desafiadores peticions d'extracció. Aquest compromís va implicar abordar constantment problemes difícils com la renderització optimitzada, la latència d'interacció i el consum de memòria.
Abans d'aquestes optimitzacions, mentre que la majoria dels usuaris gaudien d'una experiència responsiva, les grans peticions d'extracció inevitablement conduïen a una notable disminució del rendiment. Els casos extrems veien el heap de JavaScript superar 1 GB, el recompte de nodes DOM superar els 400.000, i les interaccions de la pàgina es tornaven severament lentes o fins i tot inutilitzables. Mètriques clau de responsivitat com Interaction to Next Paint (INP) s'elevaven per sobre dels nivells acceptables, creant una sensació tangible de retard en l'entrada per als usuaris. Aquest article s'endinsa en el viatge detallat que GitHub va emprendre per millorar dràsticament aquestes mètriques de rendiment clau, transformant l'experiència de revisió de diffs.
Navegant pels colls d'ampolla de rendiment: un enfocament multiestratègia
En iniciar la investigació de rendiment per a la pestanya Fitxers canviats, ràpidament es va fer evident que una única solució de "bala de plata" no seria suficient. Les tècniques dissenyades per preservar totes les funcions i el comportament natiu del navegador sovint topaven amb un límit amb càrregues de dades extremes. Per contra, les mesures de mitigació dirigides únicament a prevenir els pitjors escenaris podrien introduir compromisos desfavorables per a les revisions quotidianes.
En canvi, l'equip d'enginyeria de GitHub va desenvolupar un conjunt integral d'estratègies, cadascuna dissenyada meticulosament per abordar mides i complexitats de peticions d'extracció específiques. Aquestes estratègies es van construir sobre tres temes fonamentals:
- Optimitzacions focalitzades per als components de línia Diff: Millora de l'eficiència de l'experiència diff principal per a la majoria de peticions d'extracció. Això va garantir que les revisions mitjanes i grans es mantinguessin ràpides sense comprometre funcionalitats esperades com la cerca nativa a la pàgina.
- Degradació gràcil amb virtualització: Garantia de la usabilitat per a les peticions d'extracció més grans prioritzant la capacitat de resposta i l'estabilitat, i limitant intel·ligentment el que es renderitza en cada moment.
- Inversió en components fonamentals i millores de renderització: Implementació de millores que proporcionen beneficis compostos en totes les mides de peticions d'extracció, independentment del mode de visualització específic de l'usuari.
Aquests pilars estratègics van guiar els esforços de l'equip, permetent-los abordar sistemàticament les causes arrel dels problemes de rendiment i preparar l'escenari per a posteriors refinaments arquitectònics.
Desconstruint la V1: El cost d'una línia Diff costosa
La implementació inicial de GitHub basada en React, referida com a v1, va establir les bases per a la vista diff moderna. Aquesta versió va ser un esforç sincer per portar la vista clàssica de Rails a React, prioritzant la creació de components de React petits i reutilitzables i mantenint una estructura clara de l'arbre DOM. No obstant això, aquest enfocament, tot i ser lògic en el seu inici, va resultar ser un coll d'ampolla significatiu a escala.
En la v1, renderitzar cada línia diff era una operació costosa. Una sola línia en una vista unificada es traduïa típicament en uns 10 elements DOM, mentre que una vista dividida requeria prop de 15. Aquest recompte augmentaria encara més amb el ressaltat de sintaxi, introduint moltes més etiquetes <span>. A la capa de React, els diffs unificats contenien almenys vuit components per línia, i les vistes dividides un mínim de 13. Aquests eren recomptes base, amb estats d'interfície d'usuari addicionals com comentaris, "hover" i "focus" afegint encara més components.
L'arquitectura v1 també patia d'una proliferació de gestors d'esdeveniments de React. Tot i semblar inofensiu a petita escala, una sola línia diff podia contenir 20 o més gestors d'esdeveniments. Quan es multiplicava per milers de línies en una petició d'extracció gran, això s'agreujava ràpidament, provocant una sobrecàrrega excessiva i un augment de l'ús del heap de JavaScript. Aquesta complexitat no només afectava el rendiment, sinó que també feia el desenvolupament i el manteniment més desafiadors. El disseny inicial, efectiu per a dades delimitades, va patir significativament quan es va enfrontar a la naturalesa il·limitada de les diverses mides de peticions d'extracció de GitHub.
Per resumir, per a cada línia diff de la v1, el sistema tenia:
- Mínim de 10-15 elements de l'arbre DOM
- Mínim de 8-13 components de React
- Mínim de 20 gestors d'esdeveniments de React
- Nombrosos components de React petits i reutilitzables
Aquesta arquitectura va correlacionar directament les mides més grans de les peticions d'extracció amb un INP més lent i un augment de l'ús del heap de JavaScript, fent necessària una reavaluació i un redisseny fonamentals.
Revolucionant la renderització: l'impacte de les optimitzacions de la V2
La transició a la v2 va marcar una revisió arquitectònica significativa, centrant-se en canvis granulars i d'impacte. L'equip va adoptar la filosofia que "cap canvi és massa petit quan es tracta de rendiment, especialment a escala". Un exemple clar va ser l'eliminació d'etiquetes <code> innecessàries de les cel·les dels números de línia. Tot i que eliminar dos nodes DOM per línia diff pugui semblar menor, en 10.000 línies, això instantàniament va equivaldre a 20.000 nodes menys al DOM, demostrant com les optimitzacions incrementals i dirigides produeixen millores substancials.
La comparació visual a continuació destaca la complexitat reduïda de la v1 a la v2 a nivell de component:

Arquitectura de components simplificada
Una innovació clau en la v2 va ser la simplificació de l'arbre de components. L'equip va passar de vuit components de React per línia diff a dos. Això es va aconseguir eliminant els arbres de components profundament anidats i creant components dedicats per a cada línia diff dividida i unificada. Tot i que això va introduir certa duplicació de codi, va simplificar dràsticament l'accés a dades i va reduir la complexitat general. La gestió d'esdeveniments també es va centralitzar, ara gestionada per un únic gestor de nivell superior utilitzant valors data-attribute, reemplaçant els nombrosos gestors d'esdeveniments individuals de la v1. Aquest enfocament va simplificar dràsticament tant el codi com el rendiment.
Gestió intel·ligent de l'estat i accés a dades O(1)
Potser el canvi més impactant va ser la reubicació de l'estat complex de l'aplicació, com ara els comentaris i els menús contextuals, en components fills renderitzats condicionalment. En un entorn com GitHub, on les peticions d'extracció poden superar milers de línies, és ineficient que cada línia porti un estat de comentaris complex quan només una petita fracció tindrà comentaris. En traslladar aquest estat a components anidats, la responsabilitat principal del component de línia diff va passar a ser purament la renderització del codi, alineant-se amb el Principi de Responsabilitat Única.
A més, la v2 va abordar el problema de les consultes O(n) i els hooks useEffect excessius que afectaven la v1. L'equip va adoptar una estratègia de dues parts: restringir estrictament l'ús de useEffect al nivell superior dels fitxers diff i establir regles de linting per evitar la seva reintroducció en components d'embolcall de línies. Això va garantir una memoïtzació precisa i un comportament previsible. Simultàniament, les màquines d'estat globals i diff es van redissenyar per aprofitar les consultes de temps constant O(1) utilitzant objectes JavaScript Map. Això va permetre selectors ràpids i consistents per a operacions comunes com la selecció de línies i la gestió de comentaris, millorant significativament la qualitat del codi, el rendiment i reduint la complexitat mitjançant el manteniment d'estructures de dades aplanades i mapejades. Aquest enfocament meticulós per a optimitzar els fluxos de treball dels desenvolupadors i l'arquitectura subjacent garanteix un sistema robust i escalable.
L'Impacte Mesurable: la V2 Ofereix Guanyes Quantificables
Les meticuloses optimitzacions arquitectòniques i a nivell de codi implementades en la v2 van produir millores profundes i quantificables en les mètriques clau de rendiment. El nou sistema funciona significativament més ràpid, amb una reducció massiva en l'ús del heap de JavaScript i les puntuacions INP. La taula següent mostra les millores dramàtiques observades en una petició d'extracció representativa amb 10.000 canvis de línia en una configuració de diff dividit:
| Mètrica | v1 | v2 | Millora |
|---|---|---|---|
| Heap de JavaScript | 1GB+ | 250MB | 75% |
| Nodes DOM | 400.000+ | 80.000 | 80% |
| INP p95 | 1000ms+ | 100ms | 90% |
Aquestes xifres subratllen l'èxit de l'estratègia multifacètica de GitHub. Una reducció del 75% en la mida del heap de JavaScript i una disminució del 80% en els nodes DOM no només es tradueix en una petjada més lleugera al navegador, sinó que també contribueix directament a una interfície més estable i responsiva. La millora més sorprenent, una reducció del 90% en l'INP p95 (el percentil 95 de la latència d'interacció), significa que el 95% de les interaccions dels usuaris es completen ara en només 100 mil·lisegons, eliminant pràcticament el retard d'entrada que afectava les grans peticions d'extracció en la v1. Això millora significativament l'experiència de l'usuari, fent que les revisions de codi grans se sentin tan fluides i responsives com les més petites.
El compromís de GitHub amb la millora contínua, evidenciat per aquesta anàlisi profunda de l'optimització de línies diff, és un testimoni de la seva dedicació a proporcionar una plataforma de desenvolupadors de classe mundial. En analitzar rigorosament els colls d'ampolla de rendiment i implementar solucions arquitectòniques dirigides, no només han resolt problemes crítics d'escalabilitat, sinó que també han establert un nou estàndard de capacitat de resposta en el seu producte principal. Aquest enfocament en el rendiment garanteix que els enginyers puguin participar de manera eficient en tasques crucials com les revisions de codi, el que finalment condueix a una major qualitat i seguretat del codi i a un entorn de desenvolupament més productiu.
Font original
https://github.blog/engineering/architecture-optimization/the-uphill-climb-of-making-diff-lines-performant/Preguntes freqüents
What is the 'Files changed' tab in GitHub pull requests and why was its performance critical?
What were the primary performance challenges GitHub faced with large pull requests in the v1 architecture?
How did GitHub approach solving the complex performance issues, moving beyond a 'silver bullet' solution?
What were the key limitations of the 'v1' diff rendering architecture that made it unsustainable for scale?
What specific architectural changes were implemented in 'v2' to drastically improve diff line performance?
How did the GitHub engineering team achieve quantifiable improvements in JavaScript heap, DOM nodes, and INP metrics with v2?
What is Interaction to Next Paint (INP) and why is its improvement significant for GitHub's user experience?
Manteniu-vos al dia
Rebeu les últimes notícies d'IA al correu.
