Troika: [troika-three-text] Probleme beim Laden von iOS Safari

Erstellt am 21. Nov. 2020  ·  47Kommentare  ·  Quelle: protectwise/troika

Hallo!

Zunächst einmal möchte ich sagen, dass dieses Paket VIEL einfacher zu verwenden war als andere Dinge in der Vergangenheit. Also vielen Dank für die Veröffentlichung!

Wie auch immer, ich habe dies kürzlich auf eine Website gestellt, an der ich noch arbeite, und einige Inkonsistenzen auf dem Handy festgestellt. Manchmal wurde alles geladen, aber manchmal fehlten Dinge oder waren unvollständig. Screenshots unten.

Weißt du zufällig, was los sein könnte? Oder wenn ich etwas falsch mache?

Die große Schrift mit "Willkommen" als Text ist eine .otf-Datei (restgold.otf)
Der kleine Text mit "Hi my name is..." als Text ist eine .ttf-Datei (Raleway-Medium.ttf)
Wenn Sie die Schriftdateien benötigen, lassen Sie es mich wissen!

Gerät: iPhone7
iOS: 14.1
Browser: Safari

Paketdetails:
"drei": "^0.122.0",
"troika-three-text": "^0.35.0",
"troika-three-utils": "^0.35.0",

IMG_1509
IMG_1510
IMG_1511
IMG_1512

Alle 47 Kommentare

Danke, dass du das gemeldet hast! Sie sind nicht der Erste, der solche Probleme in iOS Safari beschreibt, aber ich konnte es zuvor nicht reproduzieren. Ich werde es mit Ihrer Website versuchen und hoffentlich in der Lage sein, sie zu reproduzieren.

Benutzt du es zufällig über drei ? Oder direkt?

Hey @lojjic Ich verwende dieses Paket direkt mit three.js. Und der Grund, warum ich three-utils habe, ist, dass ich in einigen Fällen auch Ihre createDerivedMaterial-Funktion verwende.

Danke, dass du das überprüft hast!

Ich konnte die Probleme beim Laden Ihrer Website auf einem iPhone 8 reproduzieren. Ich hatte noch keine Zeit, mit dem Debuggen zu beginnen, aber ich wollte nur bestätigen, dass der Fehler reproduzierbar ist.

@atlmtw @lojjic Ich hatte das gleiche Problem auf Safari bei einem Projekt, das mehrere Schriftarten verwendete. Die einzige Lösung, die ich gefunden habe, war die Verwendung einer eindeutigen Schriftart auf der gesamten Website für diesen Browser.

+1
Mehrere Schriftarten pro Szene = einige Schriftarten erscheinen nie auf dem iPhone X, iPhone SE

Ich versuche, dieses Problem zu untersuchen, und habe jetzt Probleme, es zu reproduzieren. Gleiches iPhone 8 wie zuvor. Ich kann es auf designsdalena.com nicht mehr reproduzieren, aber es ist möglich, dass diese Seite geändert wurde, um troika-three-text nicht mehr zu verwenden, oder es auf andere Weise umgangen hat.

Ich versuche also, einen minimalen Testfall mit mehreren Schriftarten zu erstellen, und kann es nicht zum Scheitern bringen:

https://uqgxq.csb.app/

Kann jemand anderes dies irgendwo reproduzieren, wo ich es zum Testen/Debuggen verwenden könnte?

Hallo @lojjic

Zur Bestätigung bin ich auf etwas anderes umgestiegen. Obwohl ich die Erfahrung mit Troika mehr genieße.

@atlmtw Danke für die Bestätigung. Ich nehme nicht an, dass Sie eine alte Version Ihrer Site in der Quellcodeverwaltung haben, die Sie mir schicken könnten? Ich habe Mühe, dies zu reproduzieren, und Ihre schien eine zuverlässige Repro zu sein.

Hallo @lojjic
Glück damit? Ich habe dies auch gesehen, wenn > 1 Schriftarten auf einem iPhone verwendet werden (funktioniert auf iPad und MacOS). Seltsamerweise ist dies nicht immer reproduzierbar, passiert nur 1-2/10 Mal und nur beim ersten Laden. Bezieht sich vielleicht auf das Herunterladen von Schriftdateien?

Übrigens, ich liebe die Arbeit :100:

@ amitrajput1992 Nein, ich konnte immer noch keinen reproduzierbaren Testfall erstellen. Hast du eine, die ich gebrauchen könnte?

@lojjic
Versuchen Sie dies ?
Wenn Sie auf einem Desktop öffnen, sollten Sie 6 verschiedene Texte sehen, die mit unterschiedlichen Farben gedruckt sind.
Ich habe diesen Link auf ein paar Geräten bei mir und ein paar auf BrowserStack getestet, alle zeigen das Rendering-Problem. Wenn Sie den Link ein paar Mal aktualisieren, funktioniert es, was sehr seltsam ist.

Das ist, was ich auf BrowserStack sehe. Dies ist auf Iphone 8 + Safari v13
Screenshot from 2021-06-10 19-01-09

Dieses auf meinem iPhone 11 + Safari 14
E81012E6-0B7F-44CE-8E52-03729D73BD28

Könnte es etwas damit zu tun haben, dass Schriftdateien im Web-Worker heruntergeladen werden? Wir wissen, dass Safari für Webworker ein Problem sein kann

@ amitrajput1992 Danke, ich kann das Problem tatsächlich auf dieser Seite replizieren. Ich werde sehen, ob ich von dort aus debuggen und/oder es in einem minimierten lokalen Testfall replizieren kann.

Wir wissen, dass Safari für Webworker ein Problem sein kann

Ich habe das auch von anderen gehört, und die Verwendung eines Arbeiters ist definitiv ein plausibler Schuldiger, aber ich konnte keine Details zu bekannten Fehlern mit Arbeitern in Safari finden. Haben Sie dort Einzelheiten, die Sie teilen können?

@lojjic
Das klingt gut. Lassen Sie mich wissen, wenn ich irgendwie helfen kann. In der Zwischenzeit werde ich weiter debuggen und versuchen, das Problem auch auf meiner Seite einzugrenzen.

Ich habe das auch von anderen gehört, und die Verwendung eines Arbeiters ist definitiv ein plausibler Schuldiger, aber ich konnte keine Details zu bekannten Fehlern mit Arbeitern in Safari finden. Haben Sie dort Einzelheiten, die Sie teilen können?

Ich kenne die genauen Probleme hier nicht, teilweise weil ich diese nirgendwo finden kann (oder die Leute diese nicht protokollieren), aber das ist etwas, das ich beim Herumbasteln bemerkt habe. React360, früher React-vr (jetzt aufgegeben), führte den gesamten Reaktionscode in einem Webworker aus, und die Aktualisierungen des Hauptthreads waren zu verdammt langsam. Es würde leicht eine Klickaktion irgendwo zwischen 300 ms und 500 ms dauern, um an meinen Klick-Listener im Worker-Thread weitergegeben zu werden, und oft würden auch ein paar Klicks fehlen.
Ich betreue ein Repo, das ein GIF-Renderer für drei ist, der anfänglich mit Offscreen-Leinwand versucht wurde, aber die Ergebnisse waren schrecklich und führten zu einer Überblendung von Texturen in aufeinanderfolgenden Frames. Das Verschieben des Ganzen in den Hauptthread verbesserte es drastisch.

Ich denke, dies könnte etwas mit dem strukturierten Klonalgorithmus zu tun haben, der verwendet wird, wenn Informationen vom Worker zum Hauptthread übertragen werden. Obwohl ich keinen soliden Beweis für diese Einschränkung unter iOS finden konnte

Ich denke, ich sollte mich zuerst auf diese Artefakte konzentrieren, die nicht immer erscheinen, aber manchmal:

Image from iOS

In diesen Fällen werden das Layout und die SDF-Generierung offensichtlich abgeschlossen und kehren zum Hauptthread zurück, aber einige der SDFs scheinen stellenweise Innen-/Außenfüllungen vertauscht zu haben. Ich kann sehen, wie das passieren könnte, wenn die Pfaddaten für diese Zeichen unvollständig sind, z. B. wenn nur die Hälfte der Pfadsegmente vorhanden sind.

Wenn während des Ladens der Schriftart etwas passiert, bei dem der Arraybuffer der Schriftart abgeschnitten oder beschädigt ist, könnte dies meines Erachtens möglicherweise zu diesem beobachteten Symptom führen. Ebenso kann es zu völlig leeren Ergebnissen kommen, wenn an bestimmten Stellen abgeschnitten wird.

Ich werde das als Möglichkeit untersuchen (vielleicht gibt XHR eine teilweise Arraybuffer-Antwort?), aber der erste Schritt besteht darin, dies in einen reproduzierbaren Testfall zu bringen, den ich modifizieren und lokal ausführen kann.

Das macht Sinn. Arraybuffer-Korruption könnte hier ein Übeltäter sein.
Ich habe eine andere Diskussion darüber gesehen, wie dieser ganze Prozess im Hauptthread ausgeführt werden soll. Steht das auf der Roadmap?

Wenn es hilft, verwende ich Troika mit drei mit den folgenden Versionen:
@React-Three/Faser: 6.2.3
@react-three/drei: 6.0.1
Troika: 0.42.0
drei: 0,129,0

Das Ausführen im Haupt-Thread ist möglich, würde jedoch zu einer ziemlich beschissenen Erfahrung führen, die den Haupt-Thread für möglicherweise mehrere Sekunden blockiert. Das sollte nur der letzte Ausweg sein.

Hat sich Ihre Testseite geändert? Es scheint, als würde jetzt nur noch eine einzige Schriftart für all die verschiedenen Textobjekte verwendet, zumindest unter iOS ...? Manchmal sehe ich jedoch immer noch verstümmelte SDFs mit dieser einzelnen Schriftart, was bedeutet, dass dies durch mehrere Schriftarten verschlimmert werden kann, aber nicht darauf beschränkt ist.

Ich habe ein Fallback für iOS-Geräte hinzugefügt, um nur eine einzige Schriftart für die gesamte App zu verwenden. Das ist meine Produktionsumgebung, also kann dort nichts kaputt gegangen sein.
Ich werde ein weiteres Beispiel in meiner Staging-Umgebung erstellen und hier so schnell wie möglich einen Link versenden.

Es ist mühsam herauszufinden, dass dies auch bei einer einzelnen Schriftart immer noch passiert :facepalm:

Hmm, es scheint tatsächlich so, als ob ich den Fehler nur mit Ihrer neuen einzelnen Schriftart auftreten kann, wenn Sie mit Safari-Entwicklungstools verbunden sind, und es ist dann ziemlich konstant fehlerhaft. Ich bin mir nicht sicher, ob uns das einen Hinweis gibt oder nicht.

Nun, ein bisschen mehr Fortschritt ... Ich habe verifiziert, dass ich in der Lage bin, die gleichen partiellen Glyphenartefakte wie oben zu erzwingen, indem ich die Pfadbefehle für einzelne Glyphen abschneide. Ich konnte noch nicht feststellen, ob dies daran liegt, dass die ursprünglichen Schriftartdaten unvollständig sind (ich denke, das würde nur eine teilweise Glyphe verursachen, nicht viele, also scheint es unwahrscheinlich) oder ob etwas die for-Schleifen dazu veranlasst vorzeitig beenden (dies scheint unmöglich, aber vielleicht gibt es einen seltsamen JIT-Fehler).

In jedem Fall bleibe ich mit den USB-Verbindungs-Entwicklungstools von Safari hängen, die keine Haltepunkte im relevanten Code festlegen können. @amitrajput1992 Wäre es überhaupt möglich, Ihre Test-App als Quelldateien zu erhalten, die ich lokal erstellen/ausführen kann, damit ich versuchen kann, den Troika-Code zum Debuggen auszutauschen?

@lojjic Ich kann den ursprünglichen App-Code zwar nicht freigeben, aber lassen Sie mich ein Storybook-Repository mit einer ähnlichen Struktur einrichten, die ich in meiner Produktions-App verwende, und ein Testrendering dafür hinzufügen. Werde den Link in Kürze rüberschicken.

@lojjic
Ich habe hier ein einfaches Repro mit einer ähnlichen Struktur wie meine Produktions-App eingerichtet: https://github.com/amitrajput1992/r3f-experiments
Ich kann das gleiche Problem damit auf meinem iPhone 11 und auf BrowserStack replizieren.
Veröffentlichen Sie das Storybook auch hier für einfachen Zugriff https://amitrajput1992.github.io/r3f-experiments

@amitrajput1992 Danke für den Testfall! Ich kann es dort replizieren, nachdem ich die CORS-Fehler beim Laden der Schriftarten von Ihrer Gmetri-Site behoben habe, indem ich sie aus dem Storybook bereitstelle.

Allerdings ... dann stürzen meine Safari-Entwicklungstools beim Versuch, eine Verbindung herzustellen, einfach voll ab! 🤦🤦🤦🤦🤦🤦 Also kann ich nicht einmal console.log-Anweisungen hinzufügen und sie sehen. Dieser Fehler will wirklich nicht behoben werden, oder?

Sich frustriert fühlen; Ich werde versuchen, morgen mit einem frischeren Geist darauf zurückzukommen. Lassen Sie mich wissen, wenn Sie irgendwelche Ideen haben.

Hey @lojjic , ich habe gerade kein Mac-System dabei, aber ich habe dies auf Browserstack mit lokaler Weiterleitung getestet. Sieht so aus, als ob die sdf-Daten, die im Web-Worker-vs-Hauptthread protokolliert werden, unterschiedlich sind. Dies könnte auf den Serialisierungs-Deserialisierungsprozess zwischen der Threadkommunikation zurückzuführen sein, ist sich jedoch nicht ganz sicher. Ich werde das weiter debuggen.
Sie können Crossbrowser-Tests ausprobieren, wenn die Safari-Entwicklungstools für Sie nicht funktionieren. Sie bieten eine 100-minütige Testversion an, die hilfreich sein könnte.

Haltepunkte im entsprechenden Code nicht setzen können

Dummer Vorschlag, nach jeder Codezeile eine Nachricht vom Webworker zu werfen und sie in console.log zu protokollieren, da Sie den Fehler reproduzieren können.

Bild auf meinem iPhone 6/11:

Dummer Vorschlag, nach jeder Codezeile eine Nachricht vom Webworker zu werfen und sie mit console.log zu protokollieren

Gar kein blöder Vorschlag! Und genau das habe ich versucht, aber die Devtools von Safari stürzen sofort ab, wenn sie auf eine lokale bearbeitbare Instanz zeigen, sodass ich nicht einmal die Ausgabe von console.log sehen kann. :(

Versuchen Sie, eine Localhost -URL im verbundenen iPhone zu öffnen? Wie funktioniert die Portweiterleitung in diesem Fall?

Versuchen Sie, eine Localhost-URL im verbundenen iPhone zu öffnen? Wie funktioniert die Portweiterleitung in diesem Fall?

Ich greife vom iPhone über die IP-Adresse des lokalen Netzwerks auf den Entwicklungsserver zu. Ich habe auch versucht, es über https://localhost.run zu leiten. In beiden Fällen stürzt Safari devtools ab, sobald ich es öffne. Die Seite selbst wird gut gerendert (wenn auch manchmal mit dem Fehler).

Ich habe in einigen Blogs gelesen, dass dies in 2 Szenarien passieren kann:

  1. wenn der Akku des Telefons zu 100 % geladen ist
  2. beim Debuggen über Netzwerk und nicht über Kabelverbindung

Dies ist ein lang andauernder Thread mit ähnlichen Linien, aber ohne Auflösung https://developer.apple.com/forums/thread/92290

aber die Devtools von Safari stürzen sofort ab, wenn ich auf eine lokal bearbeitbare Instanz verweise, sodass ich nicht einmal die Ausgabe von console.log sehen kann. :(

Es ist möglich, die Standardfunktion console.log durch so etwas zu ersetzen

console.log = (msg) => document.getElementById("my_ios_console").innerHTML += msg;

aber Sie müssen dieses div auf einer HTML-Seite oder aus einem JS-Skript erstellen

<div id="my_ios_console" style="position: absolute; top:0; left: 0; background: white"></div>

Dies sollte alle Konsolenmeldungen im Hauptthread anzeigen

Danke @munrocket , das könnte funktionieren, ich werde es versuchen.

Hallo zusammen,

Tut mir leid, dass ich mich so von diesem Thread entfernt habe. Idk, wenn dies beim Debuggen helfen würde, aber der Simulator der letzten Xcode 13-Versionen (in der Beta) konnte mein 3D-Localhost-Zeug gut ausführen! Ich bin auf die Probleme gestoßen, über die Sie alle zuvor gesprochen haben, bei denen es mit früheren Versionen immer wieder abstürzte.

@lojjic Glück damit?

Glück damit?

Nein, leider konnte ich dem in letzter Zeit nicht viel Zeit widmen.

Gibt es eine Möglichkeit, Webworker auszuschalten? nur zur Kontrolle

Hallo, alle miteinander,

Ich bin in einem Projekt auf dasselbe Problem gestoßen (für das ich leider keinen Code freigeben kann) und habe schließlich meinen Weg zu diesem Problemticket genau hier gefunden. Da das letzte Update dazu vor mehr als einem Monat stattfand, habe ich heute beschlossen, mit dem Abhängigkeitscode meines Projekts herumzuspielen, um hoffentlich herauszufinden, was genau passiert und welche Codezeilen zu diesem UX-Desaster beitragen.

Bevor ich weiter gehe, möchte ich betonen, dass die folgenden Informationen und Optimierungen in keiner Weise empfohlen werden und hier nur geteilt werden, um bei der Suche nach einer tatsächlichen Lösung zu helfen. Die folgenden Informationen sind KEINE Lösung. Du wurdest gewarnt.

Zuerst. Ja, wie bereits erwähnt, scheint dies tatsächlich der Fehler des WebWorker in iOS Safari zu sein. Firefox (win10), Chrome (win10), Opera (win10), Safari (macOS big sur) und andere zeigen dieses Problem nicht und die Schriftarten werden zu 100 % richtig geladen. Safari (iOS) gerät jedoch in eine Art Race-Condition zwischen mehreren WebWorkern (ich habe nicht herausgefunden, ob dies vollständig zutrifft oder welche asynchronen Aufrufe sich gegenseitig stören).

Sekunde. Diese angebliche Race-Condition (oder was auch immer es ist) führt dazu, dass der Puffer, der die zu ladenden Schriftdaten enthält, einige NaN-Werte erzeugt, wenn über die readShort-Funktion in Troikas Typr -Abhängigkeit darauf zugegriffen wird. Liegt das Problem also tatsächlich in Typr? Vielleicht. Ich bin nicht sicher. Diese wenigen NaN-Werte kaskadieren jedoch den Aufrufstapel nach oben, ruinieren buchstäblich alles und führen schließlich dazu, dass die Glyphe völlig falsch angezeigt wird.

Dritter. Nachdem ich den genauen Speicherort ermittelt hatte, den ich brauchte (diese readShort-Funktion in Typr/bin.s ), habe ich einiges daran angepasst, um zu verstehen, was vor sich geht.

        readShort : function(buff, p)
    {
        //if(p>=buff.length) throw "error";
        var a = Typr._bin.t.uint8;
        a[1] = buff[p]; a[0] = buff[p+1];
        return Typr._bin.t.int16[0];
    },

Wenn ich einfach eine console.log(Typr._bin.t.int16[0]) verwendet habe, würde die Anwendung ein paar NaN drucken, die niemals sein sollten (vorsichtig beim Ausprobieren, da die gesamte Anwendung beim Drucken hängen bleiben kann - diese Funktion wird aufgerufen Tausende Male, je nach Anwendungsfall). Wie erwartet führt jedoch das Anhalten der Anwendung an einer beliebigen Stelle innerhalb dieser Funktion (mit dem Debugger-Schlüsselwort oder Haltepunkt oder sogar beim Zugriff auf die Konsole) dazu, dass sich der Wert selbst korrigiert und kein NaN erzeugt (was mich an eine Race-Bedingung glauben ließ). Das bedeutet, dass Sie das Problem nicht auf herkömmliche Weise mit einem Debugger untersuchen können.

Vierter und letzter. Von diesem Teil rate ich ab, wenn es nicht darum geht, die eigentliche Lösung für dieses Problem zu finden. Beachten Sie, dass ich oben geschrieben habe, dass die NaN verschwinden, wenn sogar die Konsole innerhalb der readShort-Funktion verwendet wird. Meine geniale Hacker-Denkweise kam also auf die geniale Idee, dieses Snippet vor die Return-Anweisung von readShort einzufügen:

if (Number.isNaN(Typr._bin.t.int16[0])) {
    console.log()
}

Und es hat funktioniert! Der gesamte Text wird jetzt in iOS Safari sowie in allen anderen Browsern, die ich zuvor getestet habe, einwandfrei angezeigt. Problem gelöst~... irgendwie, auf die schlimmste Art und Weise. Es stellt sich heraus, dass das kurze Fenster, das die Anwendung für den Zugriff auf die Konsole erstellt, die angebliche Race-Condition auflöst. Beachten Sie, dass dies nur bei Verbindung mit der Konsole der Fall ist.

Abschließend. Hier bin ich. Die schreckliche Problemumgehung funktioniert, aber ich suche immer noch nach einer tatsächlichen Lösung dafür, so wie es jeder hier auch tun sollte. Es stellte sich heraus, dass das Problem in Troika liegen könnte oder auch nicht, da es die ganze Zeit in Typr oder sogar in der iOS-Implementierung von WebWorker (wer weiß) gewesen sein könnte. Auf jeden Fall hoffe ich, dass all diese Informationen bei der Untersuchung helfen und wir alle diese Sache bis zum Ende durchziehen.

Referenz-Callstack:
Typr/bin.js - readShort
Typr/glyf.js - _parseGlyf
Typr/Typr.U.js - _drawGlyf
Typr/Typr.U.js - glyphToPath
Troika/FontParser_Typr.js - (Anonym) forEachGlyph
Troika/FontParser_Typr.js - wrapFontObj
Troika/FontParser_Typr.js - analysieren
...Arbeiterkram

Und @lojjic bezüglich der Fehlerbehebung beim Debuggen von iOS Safari über USB mit MacOS Safari:
Ich rate Ihnen, zu versuchen, die Verbindung zum lokalen Netzwerk oder Ihrem Telefon zu trennen und wieder herzustellen, wenn MacOS Safari DevTools darauf besteht, auf unbestimmte Zeit geladen zu werden oder eine Meldung anzeigt, dass die Seite abgestürzt ist oder keine Skripte lädt oder was auch immer. Entweder das, oder versuchen Sie, DevTools ein paar Mal zu schließen und erneut zu öffnen. Und dann natürlich die Webseite am Telefon aktualisieren. Ich sage das, weil mir das heute ein paar Mal passiert ist (Schmerz) und ich es so gelöst habe (Verbindung zwischen MacOS Big Sur und iOS 15.0.1).

OMG @malulleybovo Ich bin aus dem Urlaub zurückgekehrt und habe deine Ergebnisse gesehen und wow, das war eine wunderbare Überraschung! 😃 Vielen Dank, dass du dich damit befasst hast.

Allein zu wissen, dass readShort NaNs produziert, ist ein _großer_ Schritt vorwärts, um vielleicht endlich dieses Problem zu verstehen, an dem ich, wie Sie wissen, schon seit geraumer Zeit feststeckte. Es half nicht, dass ich den Job gewechselt und den Zugriff auf das von mir verwendete iOS-Gerät verloren hatte.

Meine nächste Frage wäre, können wir feststellen, _warum_ der gelesene Typr._bin.t.int16[0] eine NaN erzeugt? Es scheint, dass es einen falschen Wert in einem der Puffer erhalten muss (entweder buff der Schriftart oder das Dienstprogramm Typr._bin.t.buff ), aber es würde helfen, genau zu wissen, was die Werte von buff/uint8/int16 sind sind zu diesem Zeitpunkt im Vergleich zu dem, was sie sein sollten.

Die Tatsache, dass Sie dort die console.log() einfügen können, um den Fehler zu vermeiden, ist merkwürdig. Ich bin mir nicht sicher, ob dies auf eine Race-Bedingung hinweist oder ob der Zugriff auf die Konsole den JIT-Modus verlässt. Ich würde auf Ersteres hoffen, da das leichter zu erkennen und zu umgehen klingt.

@lojjic Glückwunsch zum Jobwechsel!

Ich habe mich gerade etwas weiter mit diesem Thema beschäftigt und habe weitere interessante und seltsame Neuigkeiten darüber erhalten. Zurück zu dem readShort-Code-Snippet, das ich zuvor geteilt habe, habe ich versucht, einen Blick auf die Array-Werte (mit gemeinsam genutztem Array-Puffer) zu werfen und fand das Bizarrste, was ich in meiner bisherigen Karriere als Softwareentwickler gesehen habe.

        readShort : function(buff, p)
    {
        //if(p>=buff.length) throw "error";
        var a = Typr._bin.t.uint8;
        a[1] = buff[p]; a[0] = buff[p+1];
        /***** Right here, I peeked at Typr._bin.t.int16, Typr._bin.t.int8, and Typr._bin.t.uint8 ******/
        return Typr._bin.t.int16[0];
    },

Beim ersten Vorkommen von NaN in readShort in meiner Anwendung habe ich herausgefunden, dass buff[p]=255 und buff[p+1]=6 (beides gültige uint8-Werte). Vor diesem Hintergrund habe ich mir die Werte von Typr._bin.t.uint8 angesehen und festgestellt, dass es wie erwartet [6, 255, 0, ...] hatte. Dann habe ich bei Typr._bin.t.int16 nachgesehen und das fehlerhafte [NaN, 0, ...] statt [-250, 0, ...] gefunden. Zuletzt habe ich mir Typr._bin.t.int8 angesehen und ... es war auch falsch ... es war [6, NaN, 0, ...] anstelle von [6, -1, 0, ...] .

Die Typr-Glyf-Bibliothek verwendet einen gemeinsam genutzten ArrayBuffer für mehrere Arrays unterschiedlichen Typs (Uint8Array, Int8Array, Int16Array usw.). Dieser Vorfall hat mir gezeigt, dass (nur) in iOS Safari nach dem Ändern eines dieser Arrays die Werte der anderen möglicherweise nicht sofort aktualisiert werden. Keine Ahnung warum, aber ich habe in der jüngeren Geschichte einen behobenen Fehlerbericht mit ArrayBuffer in iOS Safari gefunden, der dies glaubwürdiger macht ... sich einmal als fehlerhaft erwiesen hat, kann sich durchaus zweimal als fehlerhaft erwiesen haben (ref: (https://bugs.webkit .org/show_bug.cgi?id=194268)[https://bugs.webkit.org/show_bug.cgi?id=194268]).

Nachdem ich dies entdeckt hatte, beschloss ich, eine alternative Implementierung der (uint8,uint8) to int16 -Konvertierung auszuprobieren. Diesmal mit bitweisen Operationen. Der Code, den ich verwendet habe, ist der folgende:

        readShort : function(buff, p)
    {
        var a = buff[p + 1] + (buff[p] << 8);
        if (a > 0b0111111111111111) {
            a = (~a) + 1;
        }
        a = (a < 0 ? -1 : 1) * (a & 0b1111111111111111);
        return a;
    },

Und da haben Sie es. Der gesamte Text mit der Schriftart wird jetzt immer korrekt angezeigt (auch ohne Verbindung zu devtools – siehe meinen vorherigen Kommentar zum Thema „console.log“, um diesen Haftungsausschluss zu verstehen). Diese alternative Lösung hat das Problem in iOS Safari behoben (getestet auf iOS 15.0.2). , und funktioniert weiterhin in den vorherigen Browsern, die ich zuvor getestet habe, wie zuvor, wie Chrome v95.0.4638.54 (win10), Firefox v93.0 (win10), Opera v80.0.4170.63 (win10) und MacOS Safari (MacOS Big Sur v11.3.1).

*Falls jemand mein obiges Code-Snippet optimieren kann, bitte gerne~

Am Ende sieht es für mich so aus, als ob dieses Problem nicht von Troika verursacht wird. Troika scheint tatsächlich unter den Folgen eines tieferen Problems zu leiden. Daher würde ich dieses Problem persönlich stattdessen nach Typr verschieben. Aber was weiß ich ... testen Sie es selbst und lassen Sie uns darüber streiten, ob dies wirklich die Wurzel des Problems ist. ;)

Ich denke, @malulleybovo verdient eine Auszeichnung oder so etwas! 🥳

Das ist erstaunlich, es einzugrenzen und eine alternative Implementierung zu entwickeln, die das Problem vermeidet! Vielen Dank!

Gerne integriere ich Ihre readShort Lösung, als Local Override in troika und/oder Upstream in Typr. Vielleicht möchten wir auch alternative Implementierungen für die anderen readFoo-Methoden?

Es scheint, als ob mit dem Typed-Arrays-Sharing-a-Buffer-Muster im Allgemeinen etwas falsch/gefährlich ist. Es ist ein ziemlich seltsames Muster, wenn ich jetzt darüber nachdenke. Es scheint, als ob DataView genau für den Zweck gedacht ist, verschiedene Zahlenformate aus Binärdateien zu lesen, ohne eine seltsame Wertkonvertierung zwischen uints und JS-Zahlen oder Endian-Inkonsistenzen ... Ich frage mich, ob das auch das Problem lösen würde? So etwas vielleicht? https://gist.github.com/lojjic/94d7b5f5f374598fe0e9761be45ebb2b

Danke für das Kompliment @lojjic~ Ich bin froh, dass ich hilfreich war.

Ihre vorgeschlagene Lösung schien vielversprechend, also habe ich sie gerade getestet und wissen Sie was, sie funktioniert auch (auf allen Browsern, die ich zuvor aufgelistet habe)!
Wenn Sie mich fragen, scheint die Verwendung von DataView eine prägnante und geeignete Methode zu sein, dies in JS zu implementieren. Schön.

Meine Anwendung hängt vom glyf-Skript von Typr ab, das readInt8, readShort, readUshort und readBytes von Typr verwendet. Obwohl ich Ihre vollständige Lösung zu Testzwecken eingebunden habe, habe ich sie nur auf diese Funktionen getestet. Und alles funktioniert so wie es aussieht.

Für einen eingehenderen Blick auf die Effektivität dieser Lösung würde ich die anderen Szenarien testen. Aber mir fehlen konkrete Beispiele, um diese zu testen (außer nur Unit-Tests).

Ich glaube, dass readFixed, readF2dot14, readUshorts, readUint64, readASCII, readUnicode, readUTF8, readBytes und readASCIIArray von bin.js von Typr nicht geändert werden müssten, da sie die typisierten Arrays nicht direkt verwenden. Es müssten also nur die Funktionen in Ihrem Kern in Typr geändert werden. Außerdem werden mit dieser Änderung der gemeinsam genutzte ArrayBuffer und die typisierten Arrays von Typr obsolet.

Wenn mehr Entwickler dies testen und genehmigen können, werden wir noch mehr Vertrauen in die Lösung haben. Dies liegt daran, dass mir nur eine begrenzte Anzahl von Testfällen und Testgeräten zur Verfügung steht und die Wahrscheinlichkeit gering ist, dass das Testergebnis verzerrt ist.

Ihre vorgeschlagene Lösung schien vielversprechend, also habe ich sie gerade getestet und wissen Sie was, sie funktioniert auch (auf allen Browsern, die ich zuvor aufgelistet habe)!
Wenn Sie mich fragen, scheint die Verwendung von DataView eine prägnante und geeignete Methode zu sein, dies in JS zu implementieren. Schön.

Tolle!!! Ich kann es kaum glauben. 🎉 🥳

Ich werde dies noch etwas testen, um zu sehen, ob ich die anderen Funktionen validieren kann, und einen grundlegenden Leistungsvergleich durchführen. Wenn nichts Böses auftaucht, werde ich es so schnell wie möglich integrieren. Ich bin ziemlich zuversichtlich, dies in eine Troika-Drei-Text-Veröffentlichung aufzunehmen, damit die Leute es ausprobieren können; Die Community wird uns informieren, wenn Probleme damit auftreten. Sobald es ein bisschen in freier Wildbahn war, werde ich es stromaufwärts bei Typr einreichen.

Die Leistung scheint vergleichbar, in einigen Fällen sogar etwas schneller. Zusatzgewinn! 😄

Ich habe überprüft, dass die anderen Funktionen auch funktionieren. Ich musste den Helfer _view leicht modifizieren, um Fälle in CFF-Schriftarten zu behandeln, in denen Typr buff als einfaches JS-Array und nicht als Uint8Array übergibt.

Ich habe die Troika-Three-Test-Version 0.43.1-alpha.0 mit dem darin enthaltenen DataView-Fix veröffentlicht (derzeit wird ein privater Fork von Typr verwendet - relevanter Commit ).

Jeder, der in der Lage ist (@amitrajput1992? @strangerintheq? @atlmtw?), ich würde es sehr schätzen, mit dieser Version zu testen, um zu überprüfen, ob sie das Problem in Ihren spezifischen Anwendungen behebt. Ich werde versuchen, dasselbe entweder mit Browserstack zu tun oder ein iPhone zum Ausleihen zu finden. Vielen Dank im Voraus!

Hey @lojjic , ​​es ist gut zu hören, dass es dafür eine Lösung gibt. Lassen Sie mich das schnell testen und mich bei Ihnen melden.

@amitrajput1992 Hi, hattest du schon Gelegenheit, die Alpha zu testen? Ich möchte dies veröffentlichen und würde die zusätzliche Validierung lieben. :)

@lojjic Hey, ich hatte gerade Zeit, das auszuprobieren. Scheint jetzt zu funktionieren!!

Überprüfen Sie die Änderungen hier: https://amitrajput1992.github.io/r3f-experiments/?path=/story/testers --text-tester

Ich habe die Version 0.44.0 mit der Lösung für diesen bösen Fehler veröffentlicht. Ich bin so froh, das endlich behoben zu haben! Vielen Dank an alle für die Unterstützung und insbesondere an @malulleybovo , dass Sie tief gegraben haben, wo ich nicht konnte, und die Grundursache gefunden haben. Ich bin sehr dankbar! 🥳

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen

Verwandte Themen

arpu picture arpu  ·  43Kommentare

stephencorwin picture stephencorwin  ·  39Kommentare

lojjic picture lojjic  ·  11Kommentare

Ocelyn picture Ocelyn  ·  13Kommentare

asbjornlystrup picture asbjornlystrup  ·  7Kommentare