Tous les projets

Document Editor & Pagination Engine

J'ai diagnostiqué un bug de pagination qui provoquait des coupures de page erronées et des blocages sur les longs documents, corrigé le problème de timing des reconstructions, puis forké, documenté et publié ma propre version maintenue du package.

Client
Produit d'écriture de scénarios
Rôle
Correction d'un bug de pagination et fork du package
Durée
~1 mois
Année
2025
Voir le projet en ligne
300+
Pages gérées par document
npm
Fork publié et documenté

01

Le défi

Un scénario n'est pas un document continu, c'est une suite de pages, et le nombre de pages est déterminant : selon la convention du métier, une page mise en forme équivaut à environ une minute d'écran, ce qui permet aux scénaristes d'estimer la durée.

J'ai rejoint ce produit avec un package de pagination TipTap/ProseMirror existant qui lâchait sur les longs documents. Les coupures de page étaient mal calculées sous charge — certaines pages accumulaient bien plus de contenu que prévu, d'autres s'affichaient vides — et l'éditeur se figeait au-delà de quelques centaines de pages. Les deux symptômes avaient la même cause : comment et quand la reconstruction de la pagination s'exécutait.

02

Mon rôle

J'ai diagnostiqué et corrigé un bug de pagination dans une extension TipTap/ProseMirror existante — je n'ai pas conçu le package d'origine.

Une approche de reconstruction incrémentale n'a pas suffi ; j'ai donc changé la façon dont les reconstructions de la pagination étaient planifiées et dont les mesures du DOM étaient gérées sous charge. J'ai forké le package, documenté les changements et publié ma version maintenue sur npm.

J'ai aussi construit le suivi de page en direct pour l'interface de l'éditeur et l'extraction du nombre de pages lors de l'upload de fichiers, y compris les changements de backend et d'état nécessaires aux deux.

03

L'ingénierie

Trouver la vraie solution

Le package existant reconstruisait la pagination d'une manière qui ne tenait pas sous charge : le timing et la fréquence des reconstructions, combinés à une mesure du DOM peu sûre, provoquaient à la fois des coupures de page erronées et une latence de saisie sur les longs documents.

Ma première tentative a été une reconstruction incrémentale — ne recalculer que la zone touchée par un changement plutôt que tout le document. Elle fonctionnait sur les petits documents, mais lâchait de nouveau quand le nombre de pages et de mots augmentait : le même blocage revenait, simplement à un seuil plus élevé.

Je l'ai remplacée par trois changements : limiter la fréquence d'exécution des reconstructions, reporter le travail non urgent aux moments d'inactivité, et sécuriser la mesure du DOM pour qu'elle cesse de s'entremêler avec les changements de mise en page. Cette combinaison a tenu sur les longueurs de document qui comptaient vraiment.

Suivi de page en direct

J'ai construit un hook de suivi de page qui repère les nœuds de page dans le document, calcule quelle page est visible au scroll, applique un debounce aux mises à jour et écrit la page courante dans le store d'état de l'éditeur — affichée dans le pied de l'éditeur sous la forme « page courante sur total ».

Nombre de pages à l'import

Créer un fichier à partir d'un upload exigeait de connaître son nombre de pages dès le départ. J'ai ajouté une extraction du nombre de pages qui lit les uploads PDF avec pdfjs-dist et les uploads Final Draft (FDX) avec le parser FDX existant du produit, puis transmet ce nombre dans le parcours de création de fichier pour l'enregistrer sur la fiche du fichier.

Backend et gestion de l'état

J'ai étendu les helpers d'enregistrement de fichiers d'Express pour que la page courante puisse persister, et étendu l'état côté client et le CSS de l'éditeur pour que la mise en page de la pagination tienne de bout en bout.

04

Ce que j'ai livré

  • Diagnostic et correction d'un bug de pagination provoquant des coupures de page erronées et des blocages sur les longs documents.
  • Fork, documentation et publication sur npm d'un package de pagination maintenu, en remplacement de la dépendance d'origine.
  • Suivi en direct de la page courante dans l'interface de l'éditeur.
  • Extraction du nombre de pages à l'upload, en lisant les PDF avec pdfjs-dist et Final Draft avec le parser existant du produit.
  • Travail de backend et d'état pour persister et soutenir le suivi de page, plus le CSS de l'éditeur pour préserver la mise en page de la pagination.

05

Résultats

  • La correction a tenu sur les longueurs de document qu'un scénario atteint réellement (plus de 300 pages), là où la tentative de reconstruction incrémentale avait échoué.
  • Les scénaristes obtiennent des nombres de pages exacts à l'upload et la position de page en direct pendant l'édition, sans les blocages ni les coupures erronées de l'ancienne implémentation.
  • Mon package forké et documenté a remplacé la dépendance d'origine et reste aujourd'hui une dépendance active du produit.

06

Stack

Éditeur
  • TipTap
  • ProseMirror
  • React
  • TypeScript
État et backend
  • Zustand
  • Express
Import
  • pdfjs-dist
Distribution
  • npm

Analyse suivante

Role-based LMS

Une plateforme d'apprentissage et de développement de carrière pour les équipes, qui réunit cours, échelles de carrière, évaluations de compétences et reporting, avec des expériences distinctes pour les apprenants et les managers.