
Code-Aufteilung. Code-Aufteilung ist überall. Aber warum? Nur weil es heutzutage zu viel Javascript gibt und nicht alle zum gleichen Zeitpunkt verwendet werden.
JS ist eine sehr schwere Sache. Nicht für Ihr iPhone Xs oder Ihren brandneuen i9-Laptop, sondern für Millionen (wahrscheinlich Milliarden) langsamer Gerätebesitzer. Oder zumindest für Ihre Uhren.
Also - JS ist schlecht, aber was würde passieren, wenn wir es einfach deaktivieren - das Problem wäre weg ... für einige Sites und "mit Sites" für die reaktionsbasierten. Aber trotzdem - es gibt Websites, die ohne JS funktionieren könnten ... und es gibt etwas, das wir daraus lernen sollten ...
Code-Aufteilung
Heute haben wir zwei Wege, zwei Wege, um es besser zu machen oder um es nicht schlechter zu machen:
1. Schreiben Sie weniger Code
Das ist das Beste, was du tun kannst. Mit React Hooks
Sie zwar etwas weniger Code Svelte
, und mit Lösungen wie Svelte
Sie nur weniger Code als gewöhnlich generieren. Svelte
ist jedoch nicht so einfach.
Es geht nicht nur um den Code, sondern auch um die Funktionalität - um den Code "kompakt" zu halten, muss er "kompakt" bleiben. Es gibt keine Möglichkeit, das Anwendungspaket klein zu halten, wenn es so viele Dinge tut (und in 20 Sprachen ausgeliefert wurde).
Es gibt Möglichkeiten, Kurz- und Soundcode zu schreiben, und es gibt Möglichkeiten, die entgegengesetzte Implementierung zu schreiben - das blutige Unternehmen . Und beide sind echt.

Aber das Hauptproblem - der Code selbst. Eine einfache Reaktionsanwendung könnte leicht "empfohlene" 250 KB umgehen. Und Sie könnten einen Monat damit verbringen, es zu optimieren und zu verkleinern. "Kleine" Optimierungen sind gut dokumentiert und sehr nützlich - holen Sie sich einfach einen bundle-analyzer
mit size-limit
und machen Sie sich wieder fit.
Es gibt viele Bibliotheken, die um jedes Byte kämpfen und versuchen, Sie an Ihre Grenzen zu bringen - predigen und speichern , um nur einige zu nennen.
Unsere Anwendung ist jedoch etwas jenseits von 200 KB. Es ist näher an 100 MB . Das Entfernen von Kilobyte macht keinen Sinn. Selbst das Entfernen von Megabyte macht keinen Sinn.
Nach einiger Zeit ist es unmöglich, Ihre Anwendung klein zu halten. Es wird mit der Zeit größer werden.
2. Versenden Sie weniger Code
Alternativ kann der code split
. Mit anderen Worten - kapitulieren . Nehmen Sie Ihr 100-MB-Bundle und machen Sie daraus 20 5-MB-Bundles. Ehrlich gesagt - das ist die einzig mögliche Möglichkeit, mit Ihrer Anwendung umzugehen, wenn sie groß wird - erstellen Sie daraus ein Paket kleinerer Apps.
Eines sollten Sie jedoch im Moment wissen: Unabhängig von der gewählten Option handelt es sich um ein Implementierungsdetail, während wir nach etwas Zuverlässigerem suchen.
Die Wahrheit über das Aufteilen von Code
Die Wahrheit über das Aufteilen von Code ist, dass es Natur ist, ZEITTRENNUNG . Sie teilen Ihren Code nicht nur auf, sondern teilen ihn so auf, dass Sie zu einem bestimmten Zeitpunkt so wenig wie möglich verwenden.
Versenden Sie nur nicht den Code, den Sie gerade nicht benötigen. Werde es los.

Einfach zu sagen, schwer zu tun. Ich habe ein paar schwere, aber nicht ausreichend geteilte Anwendungen, bei denen jede Seite wie 50% von allem geladen wird. Manchmal code splitting
zur code separation
, ich meine - Sie können den Code in die verschiedenen Blöcke verschieben, aber trotzdem alles verwenden. Erinnern Sie sich daran, dass " Versenden Sie einfach nicht den Code, den Sie gerade nicht benötigen" - ich 50% des Codes benötigte, und das war das eigentliche Problem.
Manchmal reicht es nicht aus, hier und da nur import
hinzuzufügen. Bis es keine Zeittrennung ist, sondern nur Raumtrennung - es spielt überhaupt keine Rolle.
Es gibt drei gängige Methoden zum Codieren:
- Nur dynamischer
import
. Heutzutage kaum noch alleine benutzt. Es geht mehr um Probleme bei der Verfolgung eines Zustands . Lazy
Component, wenn Sie das Rendern und Laden einer React Component verschieben können. Wahrscheinlich 90% der "React Code Splitting" in diesen Tagen.- Lazy
Library
, die eigentlich .1
, aber Sie erhalten einen Bibliothekscode über React Render Requisiten. Implementiert in reaktionsimportierten und ladbaren Komponenten . Sehr nützlich, aber nicht bekannt.
Code-Aufteilung auf Komponentenebene
Dieser ist der beliebteste. Als Code-Aufteilung pro Route oder Code-Aufteilung pro Komponente. Es ist nicht so einfach, dies zu tun und dadurch gute Wahrnehmungsergebnisse zu erzielen. Es ist der Tod durch Flash of Loading Content
.
Die guten Techniken sind:
- Laden Sie
js chunk
und data
für eine Route parallel. - Verwenden Sie ein
skeleton
, um etwas Ähnliches wie die Seite vor dem Laden der Seite anzuzeigen (z. B. Facebook). prefetch
Chunks prefetch
abrufen, können Sie für eine bessere Vorhersage sogar rate-js verwenden.- Verwenden Sie einige Verzögerungen, Ladeindikatoren,
animations
und Suspense
(in der Zukunft), um Übergänge zu mildern.
Und das ist alles über Wahrnehmungsleistung .

Bild von verbessertem UX mit Ghost Elements
Das hört sich nicht gut an
Wissen Sie, ich könnte mich als Experte für Code-Splitting bezeichnen - aber ich habe meine eigenen Fehler.
Manchmal konnte ich die Bündelgröße nicht reduzieren. Manchmal konnte ich die resultierende Leistung nicht verbessern, solange the _more_ code splitting you are introducing - the more you spatially split your page - the more time you need to _reassemble_ your page back
*. Es heißt Ladewellen .
- ohne SSR oder Pre-Rendering. Die richtige SSR verändert derzeit das Spiel.

Letzte Woche habe ich zwei Fehler:
- Ich habe in einem Bibliotheksvergleich verloren , solange meine Bibliothek besser war, aber VIEL größer als eine andere. Ich habe es nicht geschafft, "1. weniger Code zu schreiben" .
- Optimieren Sie eine kleine Site, die meine Frau in React erstellt hat. Es wurde eine routenbasierte Komponententeilung verwendet, aber die
header
und footer
wurden im footer
beibehalten, um Übergänge "akzeptabler" zu machen. Nur ein paar Dinge, die eng miteinander verbunden sind, stiegen bis zu 320 KB (vor gzip) in die Höhe. Es gab nichts Wichtiges und nichts, was ich wirklich entfernen konnte. Ein Tod durch tausend Schnitte . Ich konnte nicht weniger Code versenden .
React-Dom war 20%, Core-js war 10%, React-Router, jsLingui, React-Powerplug ... 20% des eigenen Codes ... Wir sind bereits fertig.

Die Lösung
Ich habe angefangen darüber nachzudenken, wie ich mein Problem lösen kann und warum gängige Lösungen für meinen Anwendungsfall nicht richtig funktionieren.
Was habe ich gemacht Ich habe alle wichtigen Speicherorte aufgelistet, ohne die die Anwendung überhaupt nicht funktionieren würde, und versucht zu verstehen, warum ich den Rest habe.
Es war eine Überraschung. Aber mein Problem war in CSS. Im Vanille-CSS-Übergang.
Hier ist der Code
Ich würde dieses Stück gerne als Ganzes codieren, aber das konnte ich aus zwei Gründen nicht tun:
- Die Informationen sollten bei Bedarf sofort und unverzüglich sichtbar sein. Eine Geschäftsanforderung.
- Die Information "Chrome" sollte vorher vorhanden sein, um den Übergang der Eigenschaft zu handhaben.
Dieses Problem könnte teilweise mit CSSTransitionGroup oder einer Überholung gelöst werden. Aber, wissen Sie, das Korrigieren eines Codes und das Hinzufügen eines anderen Codes klingt seltsam, selbst wenn es tatsächlich ausreicht . Ich meine, das Hinzufügen von mehr Code könnte helfen, noch mehr Code zu entfernen. Aber ... aber ...
Es sollte einen besseren Weg geben!
TL; DR - hier gibt es zwei wichtige Punkte:
DisplayData
muss gemountet werden und ist zuvor im DOM vorhanden.FocusLock
sollte auch vorher vorhanden sein, um keine erneute Bereitstellung von DisplayData zu bewirken, aber sein Gehirn wird am Anfang nicht benötigt .
Also lasst uns unser mentales Modell ändern
Batman und Robin
Nehmen wir an, unser Code ist Batman und Robin. Batman kann mit den meisten Bösen umgehen, aber wenn er nicht kann, kommt sein Kumpel Robin zur Rettung.
Wieder einmal würde Batman in die Schlacht ziehen, Robin wird später eintreffen.
Das ist Batman:
+<FocusLock - enabled={componentControl.value} +> - {componentControl.value && <PageTitle title={componentControl.value.title}/>} + <DisplayData + data={componentControl.value} + visible={componentControl.value !== null} + /> +</FocusLock>
Dies ist sein Kumpel, Robin ::
-<FocusLock + enabled={componentControl.value} -> + {componentControl.value && <PageTitle title={componentControl.value.title}/>} - <DisplayData - data={componentControl.value} - visible={componentControl.value !== null} - /> -</FocusLock>
Batman und Robin könnten ein TEAM bilden , aber sie sind tatsächlich zwei verschiedene Personen.
Und vergessen Sie nicht - wir sprechen immer noch über Code-Splitting . Und wo ist der Sidekick in Bezug auf die Code-Aufteilung? Wo ist Robin?

in einem Beiwagen. Robin wartet in einem Beiwagenstück .
Beiwagen
Batman
hier ist alles visuelle Zeug, das Ihr Kunde so schnell wie möglich sehen muss. Idealerweise sofort.Robin
hier alles Logik und ausgefallene interaktive Funktionen, die eine Sekunde später verfügbar sein können, aber nicht am Anfang.
Es wäre besser, dies eine vertikale Code-Aufteilung zu nennen , bei der Code-Zweige parallel existieren, im Gegensatz zu einer üblichen horizontalen Code-Aufteilung, bei der Code-Zweige geschnitten werden .
In einigen Ländern war dieses Trio als replace reducer
oder als andere Methode zur replace reducer
Redux-Logik und der Nebenwirkungen bekannt.
In einigen anderen Ländern wird es als "3 Phased" code splitting
.
Es ist nur eine weitere Trennung von Bedenken, die nur für Fälle gilt, in denen Sie das Laden eines Teils einer Komponente verschieben können, nicht jedoch eines anderen Teils.

Bild vom Erstellen des neuen facebook.com mit React, GraphQL und Relay , wobei importForInteractions
oder importAfter
das sidecar
.
Und es gibt eine interessante Beobachtung: Während Batman
für einen Kunden wertvoller ist, ist er immer in Form, solange es etwas ist, das der Kunde sieht ... Während Robin
, wissen Sie, ein bisschen übergewichtig ist und viel mehr Bytes benötigt leben.
Infolgedessen - Batman allein ist für einen Kunden sehr erträglich - bietet er mehr Wert zu geringeren Kosten. Du bist mein Held Bat!
Was könnte zu einem Beiwagen bewegt werden:
- Mehrheit von
useEffect
, componentDidMount
und Freunden. - wie alle Modal- Effekte. Dh
focus
und scroll
. Sie können zuerst ein Modal anzeigen und erst dann Modal modal machen , dh die Aufmerksamkeit des Kunden "sperren". - Formulare Verschieben Sie alle Logik und Validierungen in einen Beiwagen und blockieren Sie die Formularübermittlung, bis diese Logik geladen ist. Der Kunde könnte das Formular ausfüllen, ohne zu wissen, dass es sich nur um
Batman
. - Einige Animationen. Eine ganze
react-spring
in meinem Fall. - Einige visuelle Sachen. Wie benutzerdefinierte Bildlaufleisten , die eine Sekunde später möglicherweise ausgefallene Bildlaufleisten anzeigen.
Vergessen Sie auch nicht - Jeder Code, der in einen Beiwagen ausgelagert wird, entlädt auch Dinge wie Core-Js Poly- und Ponyfills, die vom entfernten Code verwendet werden.
Das Aufteilen von Code kann intelligenter sein als heute in unseren Apps. Wir müssen erkennen, dass es zwei Arten von Code gibt , die aufgeteilt werden müssen: 1) visuelle Aspekte 2) interaktive Aspekte. Letzteres kann einige Momente später kommen. Sidecar
können die beiden Aufgaben nahtlos aufgeteilt werden, sodass die Wahrnehmung entsteht, dass alles schneller geladen wird . Und es wird.
Der älteste Weg, um Code zu teilen
Obwohl es immer noch nicht ganz klar ist, wann und was ein sidecar
ist, werde ich eine einfache Erklärung geben:
Sidecar
ist ALLE IHRE SCRIPTS . Beiwagen ist die Art und Weise, wie wir vor all dem Frontend-Zeug, das wir heute haben, Codesplit machen .
Ich spreche von Server Side Rendering ( SSR ) oder einfach nur HTML , wir alle waren erst gestern daran gewöhnt. Sidecar
macht die Dinge so einfach wie früher, als Seiten, die HTML und Logik enthielten, getrennt in einbettbaren externen Skripten gelebt wurden (Trennung von Bedenken).
Wir hatten HTML plus CSS plus einige Skripte inline plus den Rest der Skripte, die in eine .js
Datei extrahiert wurden.
HTML
+ CSS
+ inlined-js
waren Batman
, während externe Skripte Robin
waren und die Site ohne Robin und ehrlich gesagt teilweise ohne Batman funktionieren konnte (er wird den Kampf mit beiden Beinen fortsetzen (Inline-Skripte) gebrochen). Das war erst gestern und viele "nicht moderne und coole" Seiten sind heute gleich.
Wenn Ihre Anwendung SSR unterstützt, versuchen Sie , js zu deaktivieren, damit es ohne SSR funktioniert. Dann wäre klar, was in einen Beiwagen gebracht werden könnte.
Wenn Ihre Anwendung nur ein clientseitiges SPA ist, stellen Sie sich vor, wie es funktionieren würde, wenn SSR vorhanden wäre.
Zum Beispiel - theurge.com , geschrieben in React, ist voll funktionsfähig, ohne dass js aktiviert ist .
Es gibt viele Dinge, die Sie in einen Beiwagen auslagern können. Zum Beispiel:
- Kommentare. Sie können Code versenden,
display
Kommentare display
, aber nicht answer
, solange möglicherweise mehr Code (einschließlich WYSIWYG-Editor) erforderlich ist, der anfangs nicht erforderlich ist. Es ist besser, ein Kommentarfeld zu verzögern oder das Laden von Code hinter der Animation zu verbergen, als eine ganze Seite zu verzögern. - Videoplayer. Versende "Video" ohne "Steuerelemente". Laden Sie sie eine Sekunde später, damit der Kunde versucht, mit ihm zu interagieren.
- Bildergalerie, wie
slick
. Es ist keine große Sache, es zu zeichnen , aber viel schwieriger zu animieren und zu verwalten. Es ist klar, was in einen Beiwagen gebracht werden könnte.
Denken Sie nur daran, was für Ihre Anwendung wichtig ist und was nicht ganz ...
Implementierungsdetails
(DI) Aufteilung des Komponentencodes
Die einfachste Form des sidecar
ist einfach zu implementieren. Verschieben Sie einfach alles in eine Unterkomponente. Sie können den Code auf "alte" Weise aufteilen. Es ist fast eine Trennung zwischen Smart- und Dumb-Komponenten, aber dieses Mal setzt Smart keine Dumb-Komponenten fort - es ist das Gegenteil.
const SmartComponent = React.lazy( () => import('./SmartComponent')); class DumbComponent extends React.Component { render() { return ( <React.Fragment> <SmartComponent ref={this} /> // <-- move smart one inside <TheActualMarkup /> // <-- the "real" stuff is here </React.Fragment> } }
Dazu muss auch der Initialisierungscode in einen dummen Code verschoben werden. Sie können jedoch weiterhin den schwersten Teil eines Codes in Code aufteilen.
Können Sie jetzt ein parallel
oder vertical
Code-Aufteilungsmuster sehen?
useSidecar
Das hier bereits erwähnte Erstellen des neuen facebook.com mit React, GraphQL und Relay hatte ein Konzept von loadAfter
oder importForInteractivity
, das dem Sidecar-Konzept ziemlich ähnlich ist.
Gleichzeitig würde ich nicht empfehlen, so etwas wie useSidecar
zu verwenden, solange Sie absichtlich versuchen, hooks
Inneren zu verwenden, aber das Aufteilen von Code in dieser Form würde gegen die Hook- Regel verstoßen .
Bitte bevorzugen Sie eine deklarativere Komponente. Möglicherweise verwenden Sie hooks
in der SideCar
Komponente.
const Controller = React.lazy( () => import('./Controller')); const DumbComponent = () => { const ref = useRef(); const state = useState(); return ( <> <Controller componentRef={ref} state={state} /> <TheRealStuff ref={ref} state={state[0]} /> </> ) }
Prefetching
Vergessen Sie nicht - Sie können Ladeprioritätshinweise verwenden, um den sidecar
vorzuladen oder vorzuholen und den Versand transparenter und unsichtbarer zu machen.
Wichtige Dinge - das Vorabrufen von Skripten würde es über das Netzwerk laden, aber nicht ausführen (und CPU ausgeben), es sei denn, es ist tatsächlich erforderlich.
SSR
Im Gegensatz zur normalen Codeaufteilung ist für SSR keine spezielle Aktion erforderlich. Sidecar
möglicherweise nicht Teil des SSR-Prozesses und werden vor dem hydration
nicht benötigt. Es könnte "von Natur aus" verschoben werden.
Verwenden Sie also React.lazy
(idealerweise etwas ohne Suspense
, Sie benötigen hier keine Failback-Indikatoren (Laden)) oder eine andere Bibliothek mit, aber besser ohne SSR-Unterstützung, um Seitenwagen-Chunks während des SSR-Prozesses zu überspringen .
Die schlechten Teile
Aber es gibt ein paar schlechte Teile dieser Idee
Batman ist kein Produktionsname
Während Batman
/ Robin
ein gutes Konzept sein könnte und der sidecar
perfekt zur Technologie selbst maincar
gibt es keinen "guten" Namen für den maincar
. Es gibt kein maincar
, und offensichtlich dürfen Batman
, Lonely Wolf
, Solitude
, Driver
und Solo
nicht verwendet werden, um ein Nicht-Beiwagen-Teil zu benennen.
Facebook hat display
und interactivity
, und das könnte die beste Option für uns alle sein.
Wenn Sie einen guten Namen für mich haben - lassen Sie es in den Kommentaren
Baum zittern
Es geht mehr um die Trennung von Bedenken aus Sicht der Bündler . Stellen wir uns vor, Sie haben Batman
und Robin
. Und stuff.js
Anschließend können Sie versuchen, Komponentenkomponentencode aufzuteilen, um einen Beiwagen zu implementieren
Kurz gesagt - der obige Code würde funktionieren, erledigt aber nicht "den Job".
- Wenn Sie nur
batman
von stuff.js
, würde das Schütteln von stuff.js
nur das behalten. - Wenn Sie nur
robin
von stuff.js
- Baumschütteln würde nur es behalten. - Wenn Sie jedoch beide verwenden, auch in unterschiedlichen
stuff.js
, werden beide beim ersten Auftreten von stuff.js
, dh dem stuff.js
, gebündelt .
Das Schütteln von Bäumen ist nicht Code-Splitting-freundlich. Sie müssen Bedenken nach Dateien trennen.
Import aufheben
Eine andere Sache, die von allen vergessen wird, sind die Kosten für Javascript. In der jQuery-Ära, der Ära der jsonp
Nutzdaten, war es durchaus üblich, das Skript (mit json
Nutzdaten) zu laden, die Nutzdaten jsonp
und das Skript zu entfernen .
Heutzutage import
wir alle import
und sie werden für immer importiert, auch wenn sie nicht mehr benötigt werden.
Wie ich bereits sagte - es gibt zu viel JS, und früher oder später werden Sie bei kontinuierlicher Navigation alles laden. Wir sollten einen Weg finden, den Import zu entfernen, keinen Block mehr zu benötigen, alle internen Caches zu löschen und Speicher freizugeben, um das Web zuverlässiger zu machen und Anwendungen nicht mit Ausnahme von Speichermangel zu zerstören.
Wahrscheinlich ist die Möglichkeit zum Aufheben un-import
(Webpack könnte dies tun ) einer der Gründe, warum wir bei der komponentenbasierten API bleiben sollten, solange wir die Möglichkeit haben, das Aufheben der Bereitstellung zu handhaben.
Bisher haben ESM-Modulstandards nichts mit solchen Dingen zu tun - weder mit der Cache-Steuerung noch mit dem Umkehren der Importaktion.
Erstellen einer Sidecar-fähigen Bibliothek
Bis heute gibt es nur einen Weg, eine sidecar
fähige Bibliothek zu erstellen:
- Teilen Sie Ihre Komponente in Teile
- Stellen Sie einen
main
und einen connected
Teil (um die API nicht zu beschädigen) über den index
- Legen Sie einen
sidecar
über einen separaten Einstiegspunkt frei. - Im Zielcode - Importieren Sie das
main
und das sidecar
- Baumschütteln sollte ein connected
Teil schneiden.
Dieses Mal sollte das Baumschütteln richtig funktionieren, und das einzige Problem ist, wie man den main
benennt.
export const Main = ({sidecar, ...props}) => ( <div> {sidecar} .... </div> );
import Main from './Component'; import Sidecar from './Sidecar'; export const Connected = props => ( <Main sidecar={<Sidecar />} {...props} /> );
export * from './Main'; export * from './Connected';
import * from './Sidecar';
Kurz gesagt, die Änderung könnte durch einen kleinen Vergleich dargestellt werden
Theoretisch könnte ein dynamic import
innerhalb von node_modules verwendet werden, um den Assemblierungsprozess transparenter zu machen.
Wie auch immer - es ist nichts weiter als ein children
/ slot
Muster, das in React so häufig vorkommt.
Die Zukunft
Facebook
bewiesen, dass die Idee richtig ist. Wenn Sie das Video noch nicht gesehen haben, machen Sie es jetzt. Ich habe gerade die gleiche Idee aus einem etwas anderen Blickwinkel erklärt (und eine Woche vor der F8-Konferenz angefangen, diesen Artikel zu schreiben).
Im Moment müssen einige Codeänderungen auf Ihre Codebasis angewendet werden. Es erfordert eine explizitere Trennung der Bedenken, um sie tatsächlich zu trennen, und die Codeaufteilung erfolgt nicht horizontal, sondern vertikal, wodurch weniger Code für eine größere Benutzererfahrung ausgeliefert wird.
Sidecar
ist wahrscheinlich die einzige Möglichkeit, mit Ausnahme der SSR der alten Schule, mit BIG-Codebasen umzugehen. Letzte Chance, eine minimale Menge an Code zu versenden, wenn Sie viel davon haben.
Es könnte eine BIG-Anwendung kleiner und eine SMALL-Anwendung noch kleiner machen.
Vor 10 Jahren war die mittlere Website in 300 ms "fertig" und einige Millisekunden später wirklich fertig. Heute sind Sekunden und sogar mehr als 10 Sekunden die gebräuchlichen Zahlen. Was für eine Schande.
Machen wir eine Pause und überlegen, wie wir das Problem lösen und UX wieder großartig machen können ...

Insgesamt
- Das Aufteilen von Komponentencode ist ein äußerst leistungsfähiges Tool, mit dem Sie etwas vollständig aufteilen können. Es ist jedoch mit Kosten verbunden. Möglicherweise wird für eine Weile nur eine leere Seite oder ein Skelett angezeigt. Das ist eine horizontale Trennung.
- Die Aufteilung des Bibliothekscodes könnte hilfreich sein, wenn die Aufteilung der Komponenten dies nicht tun würde. Das ist eine horizontale Trennung.
- Code, der in einen Beiwagen abgeladen wird, vervollständigt das Bild und ermöglicht Ihnen möglicherweise eine weitaus bessere Benutzererfahrung. Würde aber auch einen gewissen technischen Aufwand erfordern. Das ist eine vertikale Trennung.
Lassen Sie uns ein Gespräch darüber führen .
Hör auf! Was ist also mit den Problemen, die Sie zu lösen versucht haben?
Nun, das war nur der erste Teil. Wir sind jetzt im Endspiel , es würde noch einige Wochen dauern, bis der zweite Teil dieses Vorschlags aufgeschrieben ist. In der Zwischenzeit ... steigen Sie in den Beiwagen!