Ich arbeite kürzlich an einigen Arbeiten zur Website-Optimierung und beginne mit der Code-Aufteilung im Webpack, indem ich die folgende import-Anweisung verwende:
import(/* webpackChunkName: 'pageB-chunk' */ './pageB')
Was die pageB-chunk.js korrekt erstellt, sagen wir jetzt, ich möchte diesen Chunk in pageA vorab abrufen. Ich kann dies tun, indem ich diese Anweisung in pageA hinzufüge:
import(/* webpackChunkName: 'pageB-chunk' */ /* webpackPrefetch: true */ './pageB')
Was zu einem führen wird
<link rel="prefetch" href="pageB-chunk.js">
Wenn der Browser an den Kopf von HTML angehängt wird, wird er vom Browser vorab abgerufen, soweit so gut.
Das Problem ist die Importanweisung , die ich hier verwende, um nicht nur die js-Datei vorab abzurufen, sondern auch die js-Datei auszuwerten. Dies bedeutet, dass der Code dieser js-Datei analysiert und zu Bytecodes kompiliert wird. Der Code der obersten Ebene dieses JS wird ausgeführt.
Dies ist ein sehr zeitaufwändiger Vorgang auf einem mobilen Gerät, und ich möchte ihn optimieren. Ich möchte nur den Prefetch- Teil und nicht den Evaluate & Execute- Teil, da ich später, wenn einige Benutzerinteraktionen stattfinden, die Analyse auslösen werde & bewerte mich
↑↑↑↑↑↑↑↑ Ich möchte nur die ersten beiden Schritte auslösen. Die Bilder stammen von https://calendar.perfplanet.com/2011/lazy-evaluation-of-commonjs-modules/ ↑↑↑↑↑↑↑ ↑↑
Natürlich kann ich dies tun, indem ich den Prefetch-Link selbst hinzufüge, aber dies bedeutet, dass ich wissen muss, welche URL ich in den Prefetch-Link einfügen soll. Webpack kennt diese URL definitiv. Wie kann ich sie aus dem Webpack erhalten?
Hat Webpack eine einfache Möglichkeit, dies zu erreichen?
quelle
if (false) import(…)
- Ich bezweifle, dass Webpack eine Dead-Code-Analyse durchführt.import
Code hingehen.Antworten:
AKTUALISIEREN
Sie können das Preload-Webpack-Plugin mit dem HTML-Webpack-Plugin verwenden , mit dem Sie definieren können, was in der Konfiguration vorgeladen werden soll, und automatisch Tags einfügen, um Ihren Chunk vorzuladen
Hinweis: Wenn Sie ab sofort Webpack v4 verwenden, müssen Sie dieses Plugin mit installieren
preload-webpack-plugin@next
Beispiel
UPDATE 2
Wenn Sie nicht alle asynchronen Blöcke vorladen möchten, sondern nur bestimmte, können Sie dies auch tun
Entweder können Sie das Babel-Plugin von Migcoder verwenden oder
preload-webpack-plugin
wie folgtZuerst müssen Sie diesen asynchronen Block anhand eines
webpack magic comment
Beispiels benennenund dann in der Plugin-Konfiguration diesen Namen wie verwenden
Lassen Sie uns zunächst das Verhalten des Browsers sehen, wenn wir
script
Tag oderlink
Tag zum Laden des Skripts angebenscript
Tag stößt , lädt er es, analysiert es und führt es sofort ausasync
unddefer
Tag nur bis zumDOMContentLoaded
Ereignis verzögernlink
).Jetzt gibt es eine andere nicht empfohlene Art und Weise, wie Sie Ihr gesamtes Skript versenden und
string
odercomment
(da die Auswertungszeit für Kommentare oder Zeichenfolgen fast vernachlässigbar ist) und wenn Sie eine Ausführung benötigen, die Sie verwenden könnenFunction() constructor
odereval
beide nicht empfohlen werdenEin anderer Approach Service Worker: (Dadurch bleibt das Cache-Ereignis nach dem erneuten Laden der Seite erhalten oder der Benutzer wird nach dem Laden des Caches offline geschaltet.)
In modernen Browsern können Sie
service worker
einen Rückgriff (JavaScript, Bild, CSS) abrufen und zwischenspeichern. Wenn der Hauptthread diesen Rückgriff anfordert, können Sie diese Anforderung abfangen und den Rückgriff aus dem Cache zurückgeben, sodass Sie das Skript nicht analysieren und auswerten, wenn Sie laden sie in den Cache mehr über Service - Mitarbeiter lesen hierBeispiel
Wie Sie sehen können, ist dies keine Webpack-abhängige Sache. Dies liegt außerhalb des Geltungsbereichs von Webpack. Mithilfe von Webpack können Sie jedoch Ihr Bundle aufteilen, um den Service Worker besser zu nutzen
quelle
Updates: Ich füge alle Dinge in ein npm-Paket ein, schau es dir an! https://www.npmjs.com/package/webpack-prefetcher
Nach ein paar Tagen Recherche schreibe ich ein benutzerdefiniertes Babel-Plugin ...
Kurz gesagt, das Plugin funktioniert folgendermaßen:
Prefetcher ist eine Hilfsklasse, die das Manifest der Webpack-Ausgabe enthält und uns beim Einfügen des Prefetch-Links helfen kann:
Ein Anwendungsbeispiel:
Das Detail dieses Plugins finden Sie hier:
Prefetch - Übernehmen Sie die Kontrolle über das Webpack
Auch dies ist ein sehr hackiger Weg und ich mag es nicht. Wenn Sie möchten, dass das Webpack-Team dies implementiert, stimmen Sie bitte hier ab:
Feature: Dynamischer Import bei Bedarf vorab abrufen
quelle
Angenommen, ich habe verstanden, was Sie erreichen möchten, möchten Sie ein Modul nach einem bestimmten Ereignis analysieren und ausführen (z. B. auf eine Schaltfläche klicken). Sie können einfach die import-Anweisung in dieses Ereignis einfügen:
quelle