diff --git a/src/encoding/json/encode.go b/src/encoding/json/encode.go
index 5b67251fbb8595..dba44a70fbed83 100644
--- a/src/encoding/json/encode.go
+++ b/src/encoding/json/encode.go
@@ -746,18 +746,39 @@ FieldLoop:
 			fv = fv.Field(i)
 		}
 
+		// fast path omitEmpty
 		if f.omitEmpty && isEmptyValue(fv) {
 			continue
 		}
+		omitEmptyResetLocation := e.Len()
+
 		e.WriteByte(next)
-		next = ','
 		if opts.escapeHTML {
 			e.WriteString(f.nameEscHTML)
 		} else {
 			e.WriteString(f.nameNonEsc)
 		}
 		opts.quoted = f.quoted
+
+		startLen := e.Len()
 		f.encoder(e, fv, opts)
+		newLen := e.Len()
+
+		if f.omitEmpty && (newLen-startLen) <= 5 {
+			// using `Next` and `bytes.NewBuffer` we can modify the end of the
+			// underlying slice efficiently (without doing any copying)
+			fullBuf := e.Next(newLen) // extract underlying slice from buffer
+			switch string(fullBuf[startLen:newLen]) {
+			case "false", "0", "\"\"", "null", "[]":
+				// reconstruct buffer without zero value
+				e.Buffer = *bytes.NewBuffer(fullBuf[:omitEmptyResetLocation])
+				continue
+			default:
+				// reconstruct original buffer
+				e.Buffer = *bytes.NewBuffer(fullBuf)
+			}
+		}
+		next = ','
 	}
 	if next == '{' {
 		e.WriteString("{}")
diff --git a/src/encoding/json/encode_test.go b/src/encoding/json/encode_test.go
index 0b021f0074991d..26054ed023e561 100644
--- a/src/encoding/json/encode_test.go
+++ b/src/encoding/json/encode_test.go
@@ -17,6 +17,12 @@ import (
 	"unicode"
 )
 
+type NullMarshal int
+
+func (NullMarshal) MarshalJSON() ([]byte, error) {
+	return []byte(`null`), nil
+}
+
 type Optionals struct {
 	Sr string `json:"sr"`
 	So string `json:"so,omitempty"`
@@ -42,6 +48,9 @@ type Optionals struct {
 
 	Str struct{} `json:"str"`
 	Sto struct{} `json:"sto,omitempty"`
+
+	Nur NullMarshal `json:"nur"`
+	Nuo NullMarshal `json:"nuo,omitempty"`
 }
 
 var optionalsExpected = `{
@@ -53,7 +62,8 @@ var optionalsExpected = `{
  "br": false,
  "ur": 0,
  "str": {},
- "sto": {}
+ "sto": {},
+ "nur": null
 }`
 
 func TestOmitEmpty(t *testing.T) {
@@ -1082,9 +1092,9 @@ func TestMarshalRawMessageValue(t *testing.T) {
 		{map[string]any{"M": &rawNil}, `{"M":null}`, true},
 		{&map[string]any{"M": &rawNil}, `{"M":null}`, true},
 		{T1{rawNil}, "{}", true},
-		{T2{&rawNil}, `{"M":null}`, true},
+		{T2{&rawNil}, "{}", true},
 		{&T1{rawNil}, "{}", true},
-		{&T2{&rawNil}, `{"M":null}`, true},
+		{&T2{&rawNil}, "{}", true},
 
 		// Test with empty, but non-nil, RawMessage.
 		{rawEmpty, "", false},