From 77cb2b3e8f07ad65c9dfd492c0be6c9eea61ac4d Mon Sep 17 00:00:00 2001 From: Maxence Charriere Date: Fri, 17 Jun 2022 15:43:36 +0200 Subject: [PATCH] optimize html convert --- pkg/app/html.go | 69 ++++++++++++++++++++++++-------------------- pkg/app/html_test.go | 45 +++++++++++++++++++++++++++++ pkg/app/strings.go | 6 +++- 3 files changed, 88 insertions(+), 32 deletions(-) diff --git a/pkg/app/html.go b/pkg/app/html.go index d598c9ee3..a86ee6ed7 100644 --- a/pkg/app/html.go +++ b/pkg/app/html.go @@ -1,6 +1,7 @@ package app import ( + "bufio" "context" "io" "net/url" @@ -329,89 +330,95 @@ func (e *htmlElement) preRender(p Page) { } func (e *htmlElement) html(w io.Writer) { - w.Write([]byte("<")) - w.Write([]byte(e.tag)) + bw := bufio.NewWriter(w) + defer bw.Flush() + + bw.WriteString("<") + bw.WriteString(e.tag) for k, v := range e.attributes { - w.Write([]byte(" ")) - w.Write([]byte(k)) + bw.WriteString(" ") + bw.WriteString(k) if v != "" { - w.Write([]byte(`="`)) - w.Write([]byte(resolveAttributeURLValue(k, v, func(s string) string { + bw.WriteString(`="`) + bw.WriteString(resolveAttributeURLValue(k, v, func(s string) string { if e.dispatcher != nil { return e.dispatcher.resolveStaticResource(v) } return v - }))) - w.Write([]byte(`"`)) + })) + bw.WriteString(`"`) } } - w.Write([]byte(">")) + bw.WriteString(">") if e.isSelfClosing { return } for _, c := range e.children { - w.Write(ln()) + bw.WriteString("n") if c.self() == nil { c.setSelf(c) } - c.html(w) + c.html(bw) } if len(e.children) != 0 { - w.Write(ln()) + bw.WriteString("\n") } - w.Write([]byte("")) + bw.WriteString("") } func (e *htmlElement) htmlWithIndent(w io.Writer, indent int) { + bw := bufio.NewWriter(w) + defer bw.Flush() + writeIndent(w, indent) - w.Write([]byte("<")) - w.Write([]byte(e.tag)) + bw.WriteString("<") + bw.WriteString(e.tag) for k, v := range e.attributes { - w.Write([]byte(" ")) - w.Write([]byte(k)) + bw.WriteString(" ") + bw.WriteString(k) if v != "" { - w.Write([]byte(`="`)) - w.Write([]byte(resolveAttributeURLValue(k, v, func(s string) string { + bw.WriteString(`="`) + bw.WriteString(resolveAttributeURLValue(k, v, func(s string) string { if e.dispatcher != nil { return e.dispatcher.resolveStaticResource(v) } return v - }))) - w.Write([]byte(`"`)) + })) + bw.WriteString(`"`) } } - w.Write([]byte(">")) + bw.WriteString(">") if e.isSelfClosing { return } for _, c := range e.children { - w.Write(ln()) + bw.WriteString("\n") if c.self() == nil { c.setSelf(c) } - c.htmlWithIndent(w, indent+1) + c.htmlWithIndent(bw, indent+1) } if len(e.children) != 0 { - w.Write(ln()) - writeIndent(w, indent) + bw.WriteString("\n") + writeIndent(bw, indent) } - w.Write([]byte("")) + bw.WriteString("") } diff --git a/pkg/app/html_test.go b/pkg/app/html_test.go index 58689620b..9ae178296 100644 --- a/pkg/app/html_test.go +++ b/pkg/app/html_test.go @@ -1,6 +1,7 @@ package app import ( + "bytes" "fmt" "testing" ) @@ -24,3 +25,47 @@ func BenchmarkMountHTMLElement(b *testing.B) { client.Close() } } + +func BenchmarkHTMLElementHTML(b *testing.B) { + div := Div(). + Class("shell"). + Body( + H1().Class("title"). + Text("Hello"), + Input(). + Type("text"). + Class("in"). + Value("World"). + Placeholder("Type a name."). + OnChange(func(ctx Context, e Event) { + fmt.Println("Yo!") + }), + ) + + for n := 0; n < b.N; n++ { + var bytes bytes.Buffer + div.html(&bytes) + } +} + +func BenchmarkHTMLElementHTMLIndent(b *testing.B) { + div := Div(). + Class("shell"). + Body( + H1().Class("title"). + Text("Hello"), + Input(). + Type("text"). + Class("in"). + Value("World"). + Placeholder("Type a name."). + OnChange(func(ctx Context, e Event) { + fmt.Println("Yo!") + }), + ) + + for n := 0; n < b.N; n++ { + var bytes bytes.Buffer + div.htmlWithIndent(&bytes, 0) + } +} diff --git a/pkg/app/strings.go b/pkg/app/strings.go index 4e13714a6..c8da211ed 100644 --- a/pkg/app/strings.go +++ b/pkg/app/strings.go @@ -1,6 +1,7 @@ package app import ( + "bufio" "encoding/json" "fmt" "io" @@ -52,8 +53,11 @@ func toPath(v ...any) string { } func writeIndent(w io.Writer, indent int) { + bw := bufio.NewWriter(w) + defer bw.Flush() + for i := 0; i < indent*2; i++ { - w.Write([]byte(" ")) + bw.WriteString(" ") } }