diff --git a/pkg/modules/chromium/browser.go b/pkg/modules/chromium/browser.go
index 8b3a987a..adfb774c 100644
--- a/pkg/modules/chromium/browser.go
+++ b/pkg/modules/chromium/browser.go
@@ -259,7 +259,7 @@ func (b *chromiumBrowser) pdf(ctx context.Context, logger *zap.Logger, url, outp
runtime.Enable(),
disableJavaScriptActionFunc(logger, b.arguments.disableJavaScript),
extraHttpHeadersActionFunc(logger, options.ExtraHttpHeaders),
- navigateActionFunc(logger, url),
+ navigateActionFunc(logger, url, options.SkipNetworkIdleEvent),
hideDefaultWhiteBackgroundActionFunc(logger, options.OmitBackground, options.PrintBackground),
forceExactColorsActionFunc(),
emulateMediaTypeActionFunc(logger, options.EmulatedMediaType),
diff --git a/pkg/modules/chromium/browser_test.go b/pkg/modules/chromium/browser_test.go
index 39d295fd..afe9e214 100644
--- a/pkg/modules/chromium/browser_test.go
+++ b/pkg/modules/chromium/browser_test.go
@@ -380,6 +380,41 @@ func TestChromiumBrowser_pdf(t *testing.T) {
"'file:///etc/passwd' matches the expression from the denied list",
},
},
+ {
+ scenario: "skip networkIdle event",
+ browser: newChromiumBrowser(
+ browserArguments{
+ binPath: os.Getenv("CHROMIUM_BIN_PATH"),
+ wsUrlReadTimeout: 5 * time.Second,
+ allowList: regexp.MustCompile(""),
+ denyList: regexp.MustCompile(""),
+ },
+ ),
+ fs: func() *gotenberg.FileSystem {
+ fs := gotenberg.NewFileSystem()
+
+ err := os.MkdirAll(fs.WorkingDirPath(), 0o755)
+ if err != nil {
+ t.Fatalf(fmt.Sprintf("expected no error but got: %v", err))
+ }
+
+ err = os.WriteFile(fmt.Sprintf("%s/index.html", fs.WorkingDirPath()), []byte("
Skip networkIdle event
"), 0o755)
+ if err != nil {
+ t.Fatalf("expected no error but got: %v", err)
+ }
+
+ return fs
+ }(),
+ options: Options{
+ SkipNetworkIdleEvent: true,
+ },
+ noDeadline: false,
+ start: true,
+ expectError: false,
+ expectedLogEntries: []string{
+ "skipping network idle event",
+ },
+ },
{
scenario: "ErrConsoleExceptions",
browser: newChromiumBrowser(
diff --git a/pkg/modules/chromium/chromium.go b/pkg/modules/chromium/chromium.go
index fc9a9735..c23bff70 100644
--- a/pkg/modules/chromium/chromium.go
+++ b/pkg/modules/chromium/chromium.go
@@ -69,6 +69,13 @@ type Chromium struct {
// Options are the available expectedOptions for converting HTML document to PDF.
type Options struct {
+ // SkipNetworkIdleEvent set if the conversion should wait for the
+ // "networkIdle" event, drastically improving the conversion speed. It may
+ // not be suitable for all HTML documents, as some may not be fully
+ // rendered until this event is fired.
+ // Optional.
+ SkipNetworkIdleEvent bool
+
// FailOnConsoleExceptions sets if the conversion should fail if there are
// exceptions in the Chromium console.
// Optional.
@@ -171,6 +178,7 @@ type Options struct {
// DefaultOptions returns the default values for Options.
func DefaultOptions() Options {
return Options{
+ SkipNetworkIdleEvent: false,
FailOnConsoleExceptions: false,
WaitDelay: 0,
WaitWindowStatus: "",
diff --git a/pkg/modules/chromium/routes.go b/pkg/modules/chromium/routes.go
index 83e8e80b..1d5038ab 100644
--- a/pkg/modules/chromium/routes.go
+++ b/pkg/modules/chromium/routes.go
@@ -27,6 +27,7 @@ func FormDataChromiumPdfOptions(ctx *api.Context) (*api.FormData, Options) {
defaultOptions := DefaultOptions()
var (
+ skipNetworkIdleEvent bool
failOnConsoleExceptions bool
waitDelay time.Duration
waitWindowStatus string
@@ -42,6 +43,7 @@ func FormDataChromiumPdfOptions(ctx *api.Context) (*api.FormData, Options) {
)
form := ctx.FormData().
+ Bool("skipNetworkIdleEvent", &skipNetworkIdleEvent, defaultOptions.SkipNetworkIdleEvent).
Bool("failOnConsoleExceptions", &failOnConsoleExceptions, defaultOptions.FailOnConsoleExceptions).
Duration("waitDelay", &waitDelay, defaultOptions.WaitDelay).
String("waitWindowStatus", &waitWindowStatus, defaultOptions.WaitWindowStatus).
@@ -91,6 +93,7 @@ func FormDataChromiumPdfOptions(ctx *api.Context) (*api.FormData, Options) {
Bool("preferCssPageSize", &preferCssPageSize, defaultOptions.PreferCssPageSize)
options := Options{
+ SkipNetworkIdleEvent: skipNetworkIdleEvent,
FailOnConsoleExceptions: failOnConsoleExceptions,
WaitDelay: waitDelay,
WaitWindowStatus: waitWindowStatus,
diff --git a/pkg/modules/chromium/tasks.go b/pkg/modules/chromium/tasks.go
index bf740c43..904553dd 100644
--- a/pkg/modules/chromium/tasks.go
+++ b/pkg/modules/chromium/tasks.go
@@ -136,7 +136,7 @@ func extraHttpHeadersActionFunc(logger *zap.Logger, extraHttpHeaders map[string]
}
}
-func navigateActionFunc(logger *zap.Logger, url string) chromedp.ActionFunc {
+func navigateActionFunc(logger *zap.Logger, url string, skipNetworkIdleEvent bool) chromedp.ActionFunc {
return func(ctx context.Context) error {
logger.Debug(fmt.Sprintf("navigate to '%s'", url))
@@ -145,12 +145,21 @@ func navigateActionFunc(logger *zap.Logger, url string) chromedp.ActionFunc {
return fmt.Errorf("navigate to '%s': %w", url, err)
}
- err = runBatch(
- ctx,
+ waitFunc := []func() error{
waitForEventDomContentEventFired(ctx, logger),
waitForEventLoadEventFired(ctx, logger),
- waitForEventNetworkIdle(ctx, logger),
waitForEventLoadingFinished(ctx, logger),
+ }
+
+ if !skipNetworkIdleEvent {
+ waitFunc = append(waitFunc, waitForEventNetworkIdle(ctx, logger))
+ } else {
+ logger.Debug("skipping network idle event")
+ }
+
+ err = runBatch(
+ ctx,
+ waitFunc...,
)
if err == nil {