¿Qué tan emocionante es el proyecto de Excel en línea?

Han pasado varios meses desde que me uní al equipo de desarrollo de Tencent Document Excel. Al principio, el código se descargó 100 + W líneas. La cantidad de código es muy grande, pero el diseño del módulo y la calidad del código son mucho mejores de lo que pensaba. Hoy compartiré con ustedes el próximo proyecto de Excel. Qué divertido puede ser.

Desafíos de la edición colaborativa en tiempo real

Cuando se trata de las dificultades de la edición colaborativa en tiempo real, la primera reacción de todos es básicamente el manejo colaborativo de conflictos.

Manejo de conflictos

Las soluciones de resolución de conflictos son en realidad relativamente maduras, que incluyen:

  1. Bloqueo de edición : cuando alguien está editando un documento, el sistema bloqueará el documento para evitar que otros lo editen al mismo tiempo.

  2. diff-patch : basado en la idea similar de Git y otra gestión de versiones, operaciones como la comparación de diferencias y la fusión de contenido, incluido GNU diff-patch, diff-patch de Myer y otros programas.

  3. Realización de la consistencia final : incluida la transformación operativa (OT), el tipo de datos replicados sin conflictos (CRDT, denominado tipo de datos replicados sin conflictos).

La implementación del bloqueo de edición es simple y grosera, pero afectará directamente la experiencia del usuario. diff-patch puede fusionar conflictos de autoservicio o entregarlo a los usuarios para que lo manejen cuando se produzcan conflictos. El algoritmo OT es el esquema adoptado en Google Docs y el editor Atom usa CRDT.

OT y CRDT

La similitud entre los métodos OT y CRDT es que proporcionan la máxima consistencia. La diferencia radica en su funcionamiento:

  • OT hace esto cambiando las operaciones

    • OT dividirá y convertirá las operaciones de edición para lograr el efecto de manejo de conflictos

    • OT no incluye implementación específica, por lo que el proyecto debe implementarse por sí mismo, pero el manejo de conflictos de alta precisión se puede realizar de acuerdo con las necesidades del proyecto.

  • CRDT hace esto cambiando el estado

    • Básicamente, CRDT es una estructura de datos, cuando se usa el mismo conjunto de operaciones para la actualización, incluso si estas operaciones se aplican en un orden diferente, siempre convergerán en la misma representación.

    • CRDT tiene dos métodos: basado en operaciones y basado en estado

OT se utiliza principalmente para texto, que suele ser complejo y no escalable. La implementación de CRDT es muy simple, pero Google, Microsoft, CKSource y muchas otras compañías confían en OT por una razón: el estado actual de la investigación de CRDT respalda la colaboración en dos tipos principales de datos: texto plano y estructura JSON arbitraria.

Para estructuras más avanzadas, como la edición de texto enriquecido, OT intercambia la complejidad por la realización de las expectativas de los usuarios, mientras que CRDT presta más atención a las estructuras de datos. A medida que aumenta la complejidad de las estructuras de datos, la complejidad de tiempo y espacio del algoritmo también se volverá Un aumento exponencial traerá desafíos de rendimiento. Por lo tanto, la mayor parte de la edición colaborativa en tiempo real ahora se basa en algoritmos OT.

Gestión de versiones

En un escenario de colaboración de varias personas, para garantizar la experiencia del usuario, el algoritmo diff-patch / OT generalmente se usa para manejar conflictos. Para garantizar que cada operación del usuario se pueda actualizar de acuerdo con el tiempo correcto, es necesario mantener un número de versión que aumente automáticamente, y cada vez que haya una nueva modificación, el número de versión se actualizará.

Actualización de la versión de datos

La versión de datos se puede actualizar de manera ordenada como se esperaba, y se requieren varios requisitos previos:

  • La versión de datos colaborativos se actualiza normalmente

  • La versión de datos faltantes se ha parcheado correctamente

  • Versión creciente ordenada de los datos enviados

¿Cómo entender estas premisas? Pongamos un ejemplo.

Xiao Ming abre un documento y la versión de datos del documento extraído del servidor es 100. En este momento, el servidor envió un mensaje diciendo que alguien había actualizado la versión a 101, por lo que Xiaoming necesitaba actualizar los datos de esta versión 101 en la interfaz. Esta es la actualización normal de la versión de datos colaborativos .

Xiao Ming editó en base a la última versión 101 y generó nuevos datos de operación. Cuando Xiao Ming envió estos datos al servidor, el servidor vio que los datos de Xiao Ming se basaban en la versión 101 y le dijo a Xiao Ming que la última versión ahora es 110. Xiao Ming solo puede ir al servidor y retirar la versión 102 a 110. Este es el parche exitoso de la versión de datos faltantes .

Después de que se retira la versión de datos de 102-110, los datos de la operación anterior de Xiaoming deben estar en conflicto con estas versiones de datos y, finalmente, se obtienen datos de operación basados ​​en la versión 110. En este momento, Xiao Ming volvió a enviar los datos al servidor, el servidor aceptó y asignó la versión 111 de Xiao Ming, por lo que Xiao Ming actualizó su versión de datos locales a la versión 111, que es un aumento ordenado de la versión de datos enviada .

Mantener la cola de tareas de datos

Para administrar estas versiones, necesitamos mantener una cola de datos para que las operaciones del usuario envíen datos de manera ordenada. Las responsabilidades de esta cola incluyen:

  • Los datos de operación del usuario ingresan a la cola normalmente

  • La tarea de cola normalmente se envía a la capa de acceso

  • Vuelva a intentarlo después de que la tarea en cola se envíe de forma anormal

  • La tarea en cola se elimina después de confirmar que el envío se realizó correctamente.

Dicha cola también puede enfrentar la posibilidad de que el usuario cierre repentinamente la página. También necesitamos mantener los datos en caché. Cuando el usuario abre la página nuevamente, los datos editados pero no enviados se vuelven a enviar al servidor. Además de la situación en la que el navegador está cerrado, también hay una interrupción de la red causada por los cambios de estado de la red del usuario durante el proceso de edición. En este caso, también necesitamos desconectar la operación del usuario al local y continuar cargando cuando se restablezca la red.

Gestión de habitaciones

Debido a la necesidad de colaboración entre varias personas, en comparación con las páginas web normales, hay más espacio y administración de usuarios. Se puede considerar que los usuarios del mismo documento están en la misma sala. Además de ver quién está en la misma habitación, podemos recibir mensajes unos de otros En la escena del documento, cada operación del usuario puede considerarse como un mensaje.

Sin embargo, la diferencia entre el documento y el chat de sala normal es que la operación del usuario no se puede perder y también se requiere un orden estricto de versiones. El contenido de la operación del usuario puede ser muy grande, por ejemplo, el usuario copia y pega un contenido de formulario de 10 W, 20 W, obviamente un mensaje de este tipo no se puede transmitir de una vez. En este caso, además de considerar la necesidad de compresión de datos como Websocket (el propio HTTP admite la compresión), también necesitamos implementar nuestra propia lógica de fragmentación. Cuando se trata de la fragmentación de datos, también se explica cómo fragmentar y cómo lidiar con la pérdida de datos fragmentados.

Múltiples métodos de comunicación

Hay muchos métodos de comunicación de front-end y back-end, los más comunes incluyen HTTP short polling (polling), Websocket, HTTP long polling (long polling), SSE (eventos enviados por el servidor), etc.

También podemos ver que los métodos de comunicación utilizados por diferentes equipos de documentación en línea no son consistentes. Por ejemplo, Google Docs usa Ajax para datos ascendentes y sondeo largo HTTP para datos descendentes; Graphite Docs usa Ajax para datos ascendentes y SSE para datos descendentes; Jinshan Docs, Feishu Docs y Tencent Docs usan transmisión Websocket.

Cada método de comunicación tiene sus propias ventajas y desventajas, incluida la compatibilidad, el consumo de recursos y el rendimiento en tiempo real. También puede estar relacionado con la propia arquitectura back-end del equipo empresarial. Por lo tanto, al diseñar la capa de conexión, consideramos la escalabilidad de la interfaz y deberíamos reservar soporte para varios métodos.

Cada cuadrícula es un editor de texto enriquecido

De hecho, además de la edición colaborativa en tiempo real, los proyectos de Excel también enfrentan muchos otros desafíos. Todo el mundo sabe que el editor de texto enriquecido tiene problemas, pero en Excel, cada cuadro es un editor de texto enriquecido.

Texto rico

En general, existen varios métodos de procesamiento para la edición de texto enriquecido:

  • Un simple aumento de div en contenteditablepropiedad, execCommandejecución nativa del navegador

  • div + monitoreo de eventos para mantener un conjunto de estados del editor (incluido el estado del cursor)

  • textarea + monitoreo de eventos mantiene un conjunto de estados del editor

Para que las contenteditablepropiedades sean la operación del texto seleccionado (por ejemplo, cursiva, color), es necesario determinar la ubicación del cursor, donde el rango está determinado por el texto seleccionado, y este texto se considera que no ha sido procesado, es necesario cubrirlo o eliminarlo. Mantenga el efecto original, hay más hoyos aquí y a menudo ocurren problemas de compatibilidad. En términos generales, los editores complejos como Atom y VSCode implementan funciones satisfactorias por sí mismos, utilizando la supervisión de eventos div +. El editor Ace, el documento Jinshan, etc.usan un área de texto oculta para recibir la entrada y convertirla en div para lograr el efecto de edición.

copiar y pegar

En términos generales, cuando se selecciona y copia una sola celda o varias celdas, lo que podemos obtener son los datos originales de la cuadrícula, por lo que se requieren dos pasos: Convertir los datos en texto enriquecido (tabla de empalme / tr / td y otros elementos) Y luego escriba en el portapapeles .

El proceso de pegado también requiere: obtener el contenido del portapapeles , luego convertir el contenido en datos de celda y enviar los datos de la operación . También puede implicar la carga de imágenes y el análisis de varios textos enriquecidos. Cada celda puede tener una línea recta de complejidad debido a algunos atributos establecidos (incluidas celdas combinadas, altura de fila y ancho de columna, filtrado, funciones, etc.) subir.

Los módulos de función relacionados con copiar y pegar se pueden dividir en dos tipos según los escenarios de uso:

  1. Copie y pegue el interior .

  2. Copie y pegue externamente .

Copiar y pegar internos se refiere a copiar y pegar en sus propios productos. Dado que un proceso de copiar y pegar implica una gran cantidad de cálculos y análisis, la función de copiar y pegar internamente puede considerar si escribir directamente los datos de la celda en el portapapeles. Al pegar, puede hacerlo directamente La obtención de datos ahorra los pasos que requieren mucho tiempo y recursos de convertir datos en texto enriquecido y analizar texto enriquecido en datos de celda.

Copiar y pegar externos se trata más de la compatibilidad de varios productos de edición de Excel similares y la compatibilidad del formato de contenido del portapapeles del sistema, y ​​la implementación del código es particularmente complicada.

¿Qué tan complicado es el renderizado de la tabla?

En términos generales, existen dos esquemas de implementación para dibujar tablas:

  1. Dibujo DOM .

  2. Dibujo en lienzo .

La bien conocida biblioteca de código abierto handsontable en la industria se basa en DOM para lograr el renderizado, pero es obvio que el renderizado DOM de cien mil un millón de celdas causará mayores problemas de rendimiento. Por lo tanto, hoy en día, muchas versiones web de implementaciones de hojas de cálculo se basan en lienzo + DOM superpuesto. El uso del lienzo también debe tener en cuenta el área visible, las operaciones de desplazamiento y la jerarquía del lienzo. También hay algunos problemas de rendimiento que enfrenta el lienzo, incluido el aspecto del lienzo. Proceda directamente y así sucesivamente.

La representación de tablas implica varios escenarios, como la combinación de celdas, la selección, el zoom, la congelación, el texto enriquecido y el ajuste automático de líneas. Veamos lo complicado que es.

Ajuste de línea

En términos generales, el ajuste de línea automático de una celda se refleja en el almacenamiento de datos, que solo incluye: contenido de la celda + atributo de ajuste de línea. Pero cuando es necesario procesar dichos datos, se enfrentan a algunos cálculos de ajuste de línea automático:

Necesitamos encontrar el ancho de columna de la columna y luego ramificar la capa de renderizado de acuerdo con el contenido de la celda. Como se muestra en la figura, dicha cadena de texto se dividirá en tres líneas de acuerdo con el cálculo de la lógica de la rama. Después del ajuste de línea automático, también puede implicar el ajuste de la altura de la fila en la que se encuentra la celda. El ajuste de la altura de la fila también puede afectar los resultados de representación de algunas propiedades de centrado de otras celdas en la fila y es necesario recalcularlo.

Por lo tanto, cuando configuramos el ajuste de línea automático para una columna de cuadrículas, puede causar un recálculo y renderizado a gran escala, lo que también implicará un mayor consumo de rendimiento.

Área congelada

La función de congelación puede dividir nuestra mesa en cuatro áreas, y las áreas izquierda y derecha y arriba y abajo se dividen en áreas congeladas y no congeladas. La complejidad del área congelada radica principalmente en el procesamiento de algunos casos especiales del límite, incluida la selección del área y el corte de la imagen. Veamos una imagen:

Como se muestra en la figura, para una imagen, aunque se coloca directamente en toda la tabla, cuando cae en la capa de datos, en realidad solo pertenece a una determinada cuadrícula. En la edición del área congelada, necesitamos segmentarla, pero no importa qué área esté seleccionada, aún necesitamos mostrar su imagen original:

Esto significa que cuando obtenemos la posición del clic del mouse en el lienzo, también necesitamos calcular si la cuadrícula correspondiente en la que se hizo clic pertenece a la cobertura de la imagen.

Alineación y desbordamiento celular

En general, hay tres tipos de alineación horizontal de una celda: alineación a la izquierda, alineación al centro y alineación a la derecha. Cuando la celda no está configurada para ajustarse y su contenido excede el ancho de la cuadrícula, cubrirá otras cuadrículas:

En otras palabras, cuando dibujamos una cuadrícula, también necesitamos calcular si la cuadrícula cercana se ha desbordado a la cuadrícula actual. Si hay desbordamiento, necesitamos dibujar en esta cuadrícula. Además, cuando una columna de cuadrículas está oculta, es posible que sea necesario ajustar y actualizar la lógica de desbordamiento.

Las listas anteriores son solo algunos de los puntos más detallados, y la representación de la tabla también implica varias lógicas, como ocultar, arrastrar, hacer zoom y seleccionar celdas, filas y columnas, así como algunos cálculos complejos para los bordes de las celdas. Además, debido a que la representación del lienzo es una pantalla de contenido, el desplazamiento de la página, la actualización de datos colaborativos, etc. también pueden causar actualizaciones frecuentes del lienzo.

Problemas de gestión de datos

Cuando cada cuadrícula admite contenido de texto enriquecido, en el escenario de ciento mil un millón de celdas, el almacenamiento de datos colocados en el disco y el cambio de datos de las operaciones del usuario también plantean desafíos no pequeños.

Manipulación atómica

De manera similar a las transacciones de bases de datos, para las hojas de cálculo, podemos dividir las operaciones del usuario en operaciones atómicas indivisibles. ¿Por qué haces eso? De hecho, es principalmente para facilitar el procesamiento de conflictos del algoritmo OT, que puede realizar el cálculo y conversión de conflictos lógicos específicos para cada operación atómica indivisible, y finalmente ponerlo en el almacenamiento.

Por ejemplo, insertamos una subtabla, tal operación, además de la operación de insertarse, puede necesitar mover otras subtablas. Luego, para una subtabla, nuestras operaciones pueden incluir:

  • insertar

  • Rebautizar

  • móvil

  • Eliminar

  • actualizar contenido

  • ...

Siempre que la división sea lo suficientemente cuidadosa, para todos los comportamientos de usuario de la subtabla, estas operaciones se pueden combinar en el efecto final Estas operaciones que ya no se pueden dividir son las operaciones atómicas finales. Por ejemplo, copiar y pegar una subtabla se puede dividir en 插入-重命名-更新内容; cortar una subtabla se puede dividir en 插入-更新内容-删除-移动其他子表. Al analizar el comportamiento del usuario, podemos extraer estas operaciones básicas y mirar un ejemplo específico:

Como se muestra en la figura, para el servidor, finalmente se agregan dos nuevas subtablas, una es la "Hoja de trabajo 2" de Zhang San y la otra es la "Hoja de trabajo 2" de Li Si (renombrada automáticamente).

En la implementación, la función de transformación se usa generalmente para manejar operaciones concurrentes. Esta función acepta dos operaciones que se han aplicado al mismo estado de documento (pero en diferentes clientes) y calcula que se puede aplicar después de la segunda operación y retener la primera. El cambio esperado de la nueva operación de la operación.

Los nombres de las funciones OT utilizadas en diferentes sistemas OT pueden ser diferentes, pero se pueden dividir en dos categorías:

  • transformación de inclusión / transformación hacia adelante: como se expresa IT(opA,opB), opApara comprender una opBforma efectiva de influir en las operaciones en otra operación opB'.

  • transformación de exclusión / transformación hacia atrás: como se expresa ET(opA,opB), opAde manera efectiva de opBimpacto negativo , la operación se convierte en otra operación opB''.

Algunos sistemas de TO usan funciones de TI y ET, y algunos solo usan funciones de TI. La complejidad del diseño de la función OT depende de muchos factores: si el sistema OT admite un mantenimiento constante, si admite Deshacer / Rehacer, qué atributos de conversión cumplir, si usar ET, si el modelo operativo OT es universal y los datos de cada operación se basan en Los caracteres (objetos individuales) todavía están en cadenas de caracteres (secuencias de objetos), estructuras jerárquicas u otras, etc.

Excepto que el cliente necesita realizar el manejo de conflictos locales después de recibir el mensaje colaborativo del servidor, el servidor también puede realizar el manejo de conflictos después de recibir dos mensajes basados ​​en la misma versión. Existe un conjunto de lógica de manejo de conflictos consistente en el local y el servidor para asegurar la consistencia final del algoritmo.

Revertir / rehacer la versión

Para la mayoría de los editores, Deshacer / Rehacer es la habilidad más básica y la edición de documentos no es una excepción. Anteriormente mencionamos el concepto de colaboración en tiempo real con versiones, y la operación de cada usuario puede dividirse en múltiples operaciones atómicas.

En tal escenario, Deshacer / Rehacer implica no solo la recuperación de los datos colocados en el disco, sino también el manejo de los conflictos encontrados durante la restauración de las operaciones del usuario. En un escenario de colaboración de varias personas, si se reciben los datos de operación de otra persona durante el proceso de edición, ¿se retirará la operación de la otra persona durante Deshacer?

El algoritmo basado en OT es un hecho de deshacer idea relativamente simple, típicamente implementado para cada uno de los invert()métodos de operación atómica correspondiente , la operación inversa de la operación atómica para generar una nueva operación y aplicación atómica.

Anteriormente, presentamos que la función de transformación se puede dividir en TI y ET, y Deshacer se puede implementar de dos maneras:

  • Inv & IT: inversión + transformación de inclusión

  • ET & IT: transformación de exclusión + transformación de inclusión

Independientemente del algoritmo, la idea básica de OT para deshacer es convertir la operación inversa de la operación (la operación a deshacer) en una nueva forma de acuerdo con los efectos de las operaciones realizadas después de la operación, de modo que la operación inversa convertida se pueda implementar correctamente. Deshacer la influencia. Pero si el usuario recibe una nueva operación colaborativa al editar, cuando el usuario está realizando Deshacer, la operación atómica generada por la operación inversa también debe entrar en conflicto con estos nuevos mensajes colaborativos para asegurar la consistencia final.

datos

Para las celdas que admiten texto enriquecido, además de algunas de sus propias configuraciones de propiedades, incluida la verificación del formato de datos, cálculo de funciones, ancho y alto, bordes, colores de relleno, etc., cada celda también debe mantener el formato de texto enriquecido y la asociación en la celda. Algunos datos de la imagen. Cuando estos datos se enfrentan a 100.000 o incluso millones de células, también suponen grandes desafíos para la transmisión y el almacenamiento de datos.

La versión y restauración de los registros de revisión, cómo optimizar la memoria, cómo optimizar el tamaño de los datos, cómo usar los datos de manera eficiente y cómo reducir el tiempo computacional y la complejidad del espacio se han convertido en algunos de los problemas que enfrenta la capa de datos.

FIN

La lista anterior solo representa una pequeña parte de todo el proyecto de Excel. Además, hay Trabajadores, barras de menú y varias funciones de características, como formatos de datos, funciones, imágenes, gráficos, filtrado, clasificación y arrastre inteligente. Arrastrar, importar y exportar, permisos regionales, buscar y reemplazar, cada función enfrentará varios desafíos debido a la complejidad del proyecto.

Además, el desacoplamiento funcional entre varios módulos, cómo organizar y estructurar el código 100W +, cómo optimizar el proceso de carga del código, los problemas causados ​​por la colaboración entre varias personas, la mantenibilidad / legibilidad del proyecto y la optimización del rendimiento son todos nuestros. Preguntas que a menudo requieren reflexión.

Observaciones finales

Al participar en un proyecto de este tipo, la sensación más grande es que no hay necesidad de rascarse la cabeza para pensar en qué otros aspectos destacados se pueden hacer en un proyecto, porque hay muchas cosas que se pueden hacer. Para muchas empresas, la calidad del código, la capacidad de mantenimiento y la legibilidad a menudo se ignoran. Debido a las limitaciones del proyecto en sí (relativamente simple), a menudo no podemos encontrar un punto en el que podamos profundizar, por lo que al final, solo podemos mejorar la eficiencia tanto como sea posible a través de la automatización y la configuración, pero lo que podemos hacer en realidad es muy limitado. Por tanto, su propio crecimiento es limitado.

La gente a menudo se burla de que el techo en la parte delantera es demasiado bajo y que se enfrentan a la eliminación a la edad de 35 años. Sin tener en cuenta los intereses personales, el entusiasmo y los cuellos de botella, a menudo se debe a que las condiciones no están permitidas y los escenarios comerciales son relativamente simples, por lo que no existe un escenario en el que pueda jugar sus habilidades. Solía ​​pensar que está bien estudiar después del trabajo, pero si vas a trabajar y haces lo que te gusta, ¿no mataría dos pájaros de un tiro?

Finalmente, dé la bienvenida a todo tipo de discusiones e intercambios ~

PD: Nuestro equipo todavía está contratando ~~

Sobre AlloyTeam

AlloyTeam es uno de los equipos de front-end más influyentes de China, con miembros principales del antiguo equipo de front-end de WebQQ.

AlloyTeam ha sido responsable de proyectos web a gran escala como WebQQ, grupos QQ, tribus de interés y documentos Tencent, y ha acumulado una gran cantidad de experiencia en desarrollo web rica y valiosa.

El ambiente técnico aquí es bueno, el liderazgo es agradable y el Qian Jing es bueno. Si eres un ingeniero experimentado o un recién llegado que está a punto de ingresar a la sociedad desde la escuela, siempre que te gusten los desafíos y esperes que la tecnología de punta y nuestra rápida mejora, esto sea lo mejor El lugar adecuado para ti.

Para unirse a nosotros, envíe su currículum a [email protected]



Supongo que te gusta

Origin blog.csdn.net/Tencent_TEG/article/details/111306051
Recomendado
Clasificación