[JAVA] Eine Geschichte über das Erstellen eines Dienstes, der mithilfe einer API für maschinelles Lernen Verbesserungen an einer Website vorschlägt

Vorwort

Wir haben einen Open-Source-Webdienst ** "Visible" ** entwickelt, der Websites unter dem Gesichtspunkt der Barrierefreiheit diagnostiziert und Best Practices auf der Grundlage der mithilfe der AI-Plattform erhaltenen Informationen vorschlägt.

Visible ─ アクセシビリティー診断&修正提案

Es gibt Dienste wie Googles [Leuchtturm] und [Leuchtturm], die Websites seit langem diagnostizieren, aber es ist ein neuer Dienst, der nicht nur diagnostiziert, sondern auch Verbesserungen vorschlägt **. Darüber hinaus ist es so konzipiert, dass Sie Ihr Verständnis der Barrierefreiheit vertiefen können und die Befehlszeilenversion eigenständig ausgeführt werden kann.

Es wurde 2020 vom "Unexplored Junior" (https://jr.mitou.org/) "Unterstützungsprogramm für Grund-, Mittel- und Oberschüler mit originellen Ideen und herausragender Technologie" verabschiedet und erhielt technische und finanzielle Unterstützung. Das Meeting zum Abschlussbericht auf YouTube Live findet am 1. November statt!

Einführung von Funktionen

Durch Eingabe der URL der Website wird die Seite diagnostiziert und Verbesserungen werden automatisch vorgeschlagen.

診断結果のスクリーンショット

Nachfolgend finden Sie ein Beispiel für die vorgeschlagenen Änderungen.

alt Attribut

Es wird empfohlen, das Element "" mit dem Attribut "alt" zu versehen, um dem Bildschirmleser oder SEO-Crawler den Inhalt des Bildes zu erläutern und Untertitel mithilfe der Vision-API der Google Cloud Platform zu generieren. Wir werden Verbesserungsvorschläge machen.

image.png

lang Attribut

Wenn die Sprache der Webseite nicht explizit angegeben ist, liegt ein Problem mit dem Benutzeragenten vor, für das die Sprachinformationen erforderlich sind. Daher erkennt die Übersetzungs-API die Sprachinformationen aus dem Seiteninhalt und schlägt sie vor.

image.png

Farbkontrastverhältnis

Natürlich sind auch Verbesserungsvorschläge möglich, die kein maschinelles Lernen verwenden. Wenn das Farbkontrastverhältnis niedrig ist, ist es für Benutzer mit Farbsichtmerkmalen schwierig, es zu verwenden. Daher schlagen wir eine Korrektur vor, die den Kontrast erhöht.

コントラスト

Best Practices für Barrierefreiheit wurden von W3C unter den Namen WCAG wcag standardisiert, und es gibt einige andere auf Standards basierende Regeln.

Vorschlagsmechanismus

Zum Ausführen des Diagnoseprogramms wird Puppeteer verwendet, das Chrome kopflos ausführen kann. Das Programm, das die Checkpoint-Schnittstelle (Regel) implementiert, wird ausgeführt, und die Dateiinformationen und der Link basieren auf den von jeder Regel zurückgegebenen Werten. Es kann angehängt und schließlich als Differenz angezeigt werden.

ワークフロー。下で詳解します

Das Ganze besteht aus drei Komponenten: Kern, Plug-In und Anwendung. Die eigentliche Verarbeitung wird vom Plug-In in Form der Implementierung der minimalen Implementierung und Schnittstelle geschrieben, die im Kern verfügbar sind. Das Format des Plug-Ins basiert auf ESLint.

動作フローを図で示しています。下で詳しく説明します。

Da der Algorithmus zur Generierung von Verbesserungen und der Headless-Browser als Plug-In-ähnliche Regel erweitert werden können, können neben der Google Cloud Platform auch andere Methoden verwendet werden.

Technologie verwendet

Das Projekt wird in TypeScript entwickelt. Die Tech-Stacks sind:

** Kernteil **

** Web-Backend **

** Web-Frontend **

** Andere **

Episode während der Entwicklung

Während ich mich schon immer für die Technologie der Barrierefreiheit im Internet interessiert habe, war ich nicht gezwungen, unterstützende Technologien zu verwenden, und meine einzige Motivation für ein korrektes Markup war die Optimierung für Suchmaschinen. Trotzdem erstelle ich oft Websites, die nicht zugänglich sind, und ich dachte, es wäre schön, Software wie ESLint zu haben, die mir beibringt, wie man das Problem behebt.

Gleichzeitig liegt die Altersgrenze für die Bewerbung für unerforschte Junioren bei bis zu 17 Jahren, und zu diesem Zeitpunkt war ich bereits 17 Jahre alt, also dachte ich daran, es am Ende zu versuchen, und begann, Prototypen zu erstellen, um es zu schaffen und mich zum richtigen Zeitpunkt zu bewerben. Ich tat.

Prototyp

Ich selbst habe Programme geschrieben, seit ich ein Schüler der Mittelstufe war und Teilzeit gearbeitet habe, also habe ich viel Code geschrieben, aber es ist immer noch ziemlich schwierig, den Prototyp mit nur wenigen Monaten für die Bewerbung fertig zu stellen (ehrlich gesagt, ich habe mich mehr beworben als nach der Adoption). Ich musste mir ein klares Ziel setzen (die Bühne könnte geschäftiger gewesen sein).

Für die Anwendung selbst ist kein Prototyp erforderlich, und ich hätte ein Dokument mit dem Produkt senden sollen. Um jedoch übernommen zu werden, muss ich meine eigene Technologie zeigen und nachweisen, dass ich sie bis zum Ende fertigstellen kann. tat. Im Gegenteil, wenn Sie es zeigen können, können Sie beurteilen, was interessant ist, und die zu diagnostizierenden Elemente auf ein Minimum eingrenzen, den "Korrekturvorschlag" verwerfen und bis zu "Das Diagnoseergebnis wird bei Eingabe der URL veröffentlicht" tun. Ich habe mich dazu entschlossen. Danach schrieb ich das flauschige Konzept in mein Gehirn in ein Notizbuch, integrierte es in das Domänenmodell und begann, Code mit dem Technologie-Stack zu schreiben, mit dem ich am besten vertraut war.

Ein Prototyp, der in etwa zwei Monaten funktioniert, wurde fertiggestellt und bestand die Dokumentenprüfung. Danach sollte ich interviewt und die Mentoren online nach dem Produkt gefragt werden. Um ehrlich zu sein, ich erinnere mich nicht, was ich gesagt habe, aber ich erinnere mich, dass ich gefragt wurde, welche Ziele das Produkt selbst in Zukunft hatte, und ich konnte nur eine vage Antwort geben ...

Nach der Adoption

Nach der Einführung hatten wir bereits einen Prototyp und haben ihn agil entwickelt. Unerforschte Junioren sollen regelmäßig betreut werden. In meinem Projekt habe ich dem Mentor einmal pro Woche Fortschritte gemeldet und Feedback erhalten. Daher habe ich Meilensteine für jede Woche gesetzt und bis dahin unterteilt. Wir haben mit der Entwicklung der Funktion fortgefahren.

Die Priorität der Aufgaben, bis der Benutzer sie verwendet, lag vollständig in der Reihenfolge der starken Auswirkungen, als ich sagte "Ich kann das tun", aber jetzt denke ich darüber nach, es ist eine sehr gute Methode. Ich denke es war nicht. Dank dessen habe ich jedoch das Gefühl, dass die Geschwindigkeit gestiegen ist, ohne die Details des Frameworks übermäßig zu manipulieren, selbst wenn ich mich mit Geschäftslogik befasse.

Erster Benutzertest

Während des Zeitraums hatten unerforschte Junioren die Möglichkeit, die Bühne unmittelbar nach der Adoption zu betreten, in der Mitte und die letzten drei Male (obwohl es dieses Jahr online war), und da die Gelegenheit für die erste Präsentation kam, befindet es sich bereits im Prototyp + α-Stadium. Wurde vorgestellt.

Zu diesem Zeitpunkt haben Benutzer, die die URL freigegeben und abgehört haben, die die URL bereitgestellt hat, diese tatsächlich verwendet. Ich habe jedoch einen Fehler beim Festlegen des freigegebenen Speichers des Dockers gemacht oder synchronisiert, wo er asynchron sein soll Ich wollte antworten und der Server fiel sofort nach der Ankündigung aus, sodass ich nicht das erwartete Feedback erhalten konnte (Tohoho ~).

Interview mit A11y-Spezialisten

Nach einem Viertel des Zeitraums hatte ich in Zusammenarbeit mit den Mentoren die Möglichkeit, dem Barrierefreiheitsteam eines bestimmten Unternehmens Feedback zu geben.

Wir konnten fragen, welche Art von Prozess im Bereich der Barrierefreiheit abläuft, welche Tools verwendet werden, welche Probleme für die Teamentwicklung spezifisch sind, und in diesem Interview konnten wir die Handlung materialisieren und die Benutzerbasis eingrenzen. Es war. Ich denke, die Aufgabenpriorität ist von hier aus klarer geworden.

Nachfolgende Verbesserung

Mit der zweiten Ankündigung bei Unexplored Junior (natürlich haben wir Maßnahmen gegen die Belastung ergriffen ...) und Twitter-Followern haben wir die Rückkopplungsschleife in Unterteilungen unterteilt, in denen die Benutzer sie tatsächlich verwenden, und den Fragebogen beantwortet.

Das Feedback ist ein Formular für Feedback, das in Google Forms erstellt wurde, indem nach "So erstellen Sie eine gute Umfrage" gesucht und die oben genannte Frage gestellt wird, die als gut bezeichnet wird, sowie ein eingebettetes Google Analytics-Tag. Ich versuche es von mehreren Seiten zu bekommen.

Insbesondere legen wir Wert darauf, welche Informationen der Benutzer möchte, z. B. das Zuweisen einer URL zu einer nicht implementierten Funktion und das Priorisieren der Funktion danach, wie viel Verkehr unter dieser URL generiert wird, wird in der Entwicklung berücksichtigt. tat.

Google formのスクリーンショット

Wo es stecken bleibt

Es mag eine großartige Nische sein, aber ich werde eine Notiz über die Entwicklung schreiben.

AST kann nicht mit Informationen zugeordnet werden, die vom CSS-DOM abgerufen werden können

Quellcode wie HTML und CSS wird nach dem Parsen durch den Browser in DOM konvertiert und über JavaScript verfügbar gemacht. Welche Datei oder Deklaration wird jedoch aus den CSS-Informationen angewendet, die mit Methoden wie "getComputedStlye" abgerufen werden können. Ich weiß nicht, ob es fertig ist.

Aus diesem Grund habe ich mich für [Chrome Devtools Protocol] CDP entschieden, die API der Google Chrome-Entwicklertools. Da CDP die Informationen des Stylesheets aus dem Ereignis [CSS.styleSheetAdded] styleSheetAdded abrufen kann, wird bei Erkennung eines Problems die entsprechende CSS-Datei anhand der Knoten-ID und der entsprechenden CSS-Eigenschaft durchsucht und auf AST von PostCSS gesetzt. Ich konnte es konvertieren und handhaben.

Die Frage, wo das ORM in Clean Architecture platziert werden soll

In diesem Buch wird erläutert, dass "die Schnittstellenadapterschicht die Schicht ist, die in das für die Frameworkschicht erforderliche Datenformat konvertiert". Der Teil, der SQL-Abfragen ausgibt, ist also die Schnittstellenadapterschicht und das Framework, das sie mit einem konkreten RDBMS ausführt. Obwohl es als Ebene behandelt wird, ist die Grenze zwischen diesen beiden Prozessen in ORM nicht eindeutig, und selbst wenn Sie es googeln, scheinen verschiedene Personen zu sagen, dass sie völlig unterschiedlich sind.

TypeORM ist eine Abstraktion, deren RDBMS verwendet werden soll (obwohl es natürlich Grenzen gibt), und sie wird schließlich von "ormconfig" festgelegt. Wenn Sie also die Details nicht erwähnen, können Sie sie in die Schnittstellenadapterschicht aufteilen. Ich habe mich für DAL entschieden.

Abgesehen davon behält der Präsentator, der das Domänenmodell in die Form einer API konvertiert, auch die Richtung der Abhängigkeit bei, indem er den auf der Präsentatorseite definierten Typ verwendet, anstatt die GraphQL-Definition direkt zu behandeln.

Docker in Monorepo (Garnarbeitsbereich) zu machen ist zu schmerzhaft

Ich denke, dass Module bei Mikrodiensten nicht so stark voneinander abhängen, aber wenn Sie Yarn Workspace und Docker in einem Fall verwenden möchten, in dem Pakete vom Front-End und Back-End gemeinsam genutzt werden, jedes Paket Ich kann keine Sperrdatei erstellen, oder da das folgende node_modules ein symbolischer Link ist, funktioniert es nicht, selbst wenn ich es einfach kopiere und es hängen bleibt.

Im Moment habe ich eine [unordentliche Problemumgehung] [Docker-Datei] geschrieben und sie funktioniert. Garn v2 (Beere) bietet eine Funktion namens [Garnarbeitsbereich-Fokus] [Fokus], und es scheint, dass Sie nur die Abhängigkeiten des gewünschten Pakets installieren und unabhängig voneinander ausführen können, daher möchte ich schnell vorankommen. Ich habe es jedoch noch nicht angefasst, da ich die Umgebung von Plug'n'Play nicht vollständig verstehe.

gestylte Komponenten sind scharf

Zum ersten Mal habe ich eine UI-Komponente wie ein Design-System richtig erstellt, aber wenn eine Komponente mehrere Varianten zu haben scheint (siehe unten), war die Lesbarkeit bei gestylten Komponenten am schlechtesten und ich bin schließlich zu Tailwind geflüchtet.

const Button = styled.button`
  font-size: 12px;

  ${
    (props) => props.variant === 'primary'
      ? css`
        color: ${props.theme.primaryFgColor};
        background-color: ${props.theme.primaryBgColor};
      `
      : css`
        color: ${props.theme.secondaryFgColor};
        background-color: ${props.theme.secondaryBgColor}
      `;
  }
`;

Details: https://qiita.com/rigarashi/private/5c97be5ed8fb15ea2d96

Es scheint ein gestyltes System oder xstyled zu geben, das Utilify-first in CSS-in-JS importiert hat, aber ich habe es aufgegeben, weil der Thementyp nicht statisch angehängt war.

Parallelverarbeitung mit Puppenspieler

Die Bibliothek mit dem Namen Puppeteer-Cluster schien nett zu sein, aber sie scheint nicht gepflegt zu sein und es ist einfach, eine Instanz einer Seite als Rückruf zu erhalten. Ich konnte es nur tun und habe es gestoppt, weil es für diesen Anwendungsfall wie die Konvertierung in Observable schwierig war.

Stattdessen verwaltet das sogenannte Object Pooling ausgelastete und nicht ausgelastete Instanzen und wirft die Verarbeitung auf diejenigen, die scheinbar frei sind. .. Ich denke, es ist wahrscheinlich besser, den Worker-Prozess zu verzweigen, aber es machte nicht viel Sinn, da er bereits beim Start von Puppeteer vom Chromium-Prozess getrennt war und zur Quelle des GraphQL-Abonnements wurde. Es ist nur eine Tonne, und Sie können dem Browser nichts sagen, es sei denn, Sie rufen ihn im selben Prozess auf, ohne Redis einzuschließen.

Nachwort

Verzeihen Sie mir den etwas minenähnlichen Titel, wenn ich darüber nachdenke, wie ich die Aufmerksamkeit der Menschen mit der oft verachteten Zugänglichkeit erregen kann.

Darüber hinaus haben wir die Webversion usw. veröffentlicht. Probieren Sie es aus und bitten Sie um ** Feedback **.

ähnliche Links

Recommended Posts

Eine Geschichte über das Erstellen eines Dienstes, der mithilfe einer API für maschinelles Lernen Verbesserungen an einer Website vorschlägt
Die Geschichte der Schaffung eines Dienstes, der die Geschichte des Portfolios erzählt, indem er sich allein entwickelt
Eine Geschichte, der ich beim Testen der API mit MockMVC verfallen war
Erstellen Sie mit Grape einen RESTful-API-Service
Eine Geschichte, die Zeit brauchte, um eine Verbindung herzustellen
Eine Geschichte über das Erstellen eines Builders, der den Builder erbt
Die Geschichte des Versuchs, JAVA File zu bedienen
Der Weg zum Erstellen eines Webdienstes (Teil 1)
Eine Geschichte über den Versuch, mit Mockito auszukommen
Eine Geschichte über das Bemühen, JAR-Dateien zu dekompilieren
Eine Geschichte über die Reduzierung des Speicherverbrauchs auf 1/100 mit find_in_batches