From cb2f95ceee76c7166e95ec1b59c3e2fbac9b0079 Mon Sep 17 00:00:00 2001 From: Giedrius Jonikas Date: Sat, 16 Nov 2024 15:29:57 +0000 Subject: [PATCH] Optimise `docker stats` to not require clearing the whole screen Instead of clearing the whole screen and then writing the new stats, we now write the new stats on top of the old text, and then clear the remaining text. This is a more efficient way to update the stats, as it avoids the flickering that happens when the screen is cleared and rewritten. Signed-off-by: Giedrius Jonikas --- cli/command/container/stats.go | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/cli/command/container/stats.go b/cli/command/container/stats.go index 1ca14ad4c7..d6afb0528c 100644 --- a/cli/command/container/stats.go +++ b/cli/command/container/stats.go @@ -287,16 +287,26 @@ func RunStats(ctx context.Context, dockerCLI command.Cli, options *StatsOptions) cStats.mu.RUnlock() if !options.NoStream { - // Start by clearing the screen and moving the cursor to the top-left - _, _ = fmt.Fprint(&statsTextBuffer, "\033[2J\033[H") + // Start by moving the cursor to the top-left + _, _ = fmt.Fprint(&statsTextBuffer, "\033[H") } if err = statsFormatWrite(statsCtx, ccStats, daemonOSType, !options.NoTrunc); err != nil { break } - _, _ = fmt.Fprint(dockerCLI.Out(), statsTextBuffer.String()) + if !options.NoStream { + for _, line := range strings.Split(statsTextBuffer.String(), "\n") { + // In case the new text is shorter than the one we are writing over, + // we'll append the "erase line" escape sequence to clear the remaining text. + _, _ = fmt.Fprint(&statsTextBuffer, line, "\033[K\n") + } + // We might have fewer containers than before, so let's clear the remaining text + _, _ = fmt.Fprint(&statsTextBuffer, "\033[J") + } + + _, _ = fmt.Fprint(dockerCLI.Out(), statsTextBuffer.String()) statsTextBuffer.Reset() if len(cStats.cs) == 0 && !showAll {