diff --git a/HISTORY.md b/HISTORY.md
index dd909594..405f3e65 100644
--- a/HISTORY.md
+++ b/HISTORY.md
@@ -364,6 +364,9 @@ Response:
 
 Other Improvements:
 
+- Add `Party.SetRoutesNoLog(disable bool) Party` to disable (the new) verbose logging of next routes.
+- Add `mvc.Application.SetControllersNoLog(disable bool) *mvc.Application` to disable (the new) verbose logging of next controllers. As requested at [#1630](https://github.com/kataras/iris/issues/1630).
+
 - Fix [#1621](https://github.com/kataras/iris/issues/1621) and add a new `cache.WithKey` to customize the cached entry key.
 
 - Add a `Response() *http.Response` to the Response Recorder.
diff --git a/_examples/mvc/basic/main.go b/_examples/mvc/basic/main.go
index ebdfcde9..e7f14c1e 100644
--- a/_examples/mvc/basic/main.go
+++ b/_examples/mvc/basic/main.go
@@ -14,12 +14,17 @@ func main() {
 	app := iris.New()
 	app.Use(recover.New())
 	app.Logger().SetLevel("debug")
+	// Disable verbose logging of routes for this and its children parties
+	// when the log level is "debug": app.SetRoutesNoLog(true)
 	mvc.Configure(app.Party("/basic"), basicMVC)
 
 	app.Listen(":8080")
 }
 
 func basicMVC(app *mvc.Application) {
+	// Disable verbose logging of controllers for this and its children mvc apps
+	// when the log level is "debug": app.SetControllersNoLog(true)
+
 	// You can use normal middlewares at MVC apps of course.
 	app.Router.Use(func(ctx iris.Context) {
 		ctx.Application().Logger().Infof("Path: %s", ctx.Path())
diff --git a/core/router/api_builder.go b/core/router/api_builder.go
index 46ee5526..28dcba0e 100644
--- a/core/router/api_builder.go
+++ b/core/router/api_builder.go
@@ -198,6 +198,8 @@ type APIBuilder struct {
 	macros *macro.Macros
 	// the api builder global routes repository
 	routes *repository
+	// disables the debug logging of routes under a per-party and its children.
+	routesNoLog bool
 
 	// the per-party handlers, order
 	// of handlers registration matters,
@@ -643,6 +645,7 @@ func (api *APIBuilder) createRoutes(errorCode int, methods []string, relativePat
 		// route.Use(api.beginGlobalHandlers...)
 		// route.Done(api.doneGlobalHandlers...)
 
+		route.NoLog = api.routesNoLog
 		routes[i] = route
 	}
 
@@ -714,6 +717,7 @@ func (api *APIBuilder) Party(relativePath string, handlers ...context.Handler) P
 		logger:              api.logger,
 		macros:              api.macros,
 		routes:              api.routes,
+		routesNoLog:         api.routesNoLog,
 		beginGlobalHandlers: api.beginGlobalHandlers,
 		doneGlobalHandlers:  api.doneGlobalHandlers,
 
@@ -866,6 +870,18 @@ func (api *APIBuilder) GetRouteReadOnlyByPath(tmplPath string) context.RouteRead
 	return r.ReadOnly
 }
 
+// SetRoutesNoLog disables (true) the verbose logging for the next registered
+// routes under this Party and its children.
+//
+// To disable logging for controllers under MVC Application,
+// see `mvc/Application.SetControllersNoLog` instead.
+//
+// Defaults to false when log level is "debug".
+func (api *APIBuilder) SetRoutesNoLog(disable bool) Party {
+	api.routesNoLog = disable
+	return api
+}
+
 type (
 	// PartyMatcherFunc used to build a filter which decides
 	// if the given Party is responsible to fire its `UseRouter` handlers or not.
diff --git a/core/router/party.go b/core/router/party.go
index 98110f88..85d7ec8e 100644
--- a/core/router/party.go
+++ b/core/router/party.go
@@ -39,6 +39,15 @@ type Party interface {
 	// Learn more at:  https://github.com/kataras/iris/tree/master/_examples/routing/dynamic-path
 	Macros() *macro.Macros
 
+	// SetRoutesNoLog disables (true) the verbose logging for the next registered
+	// routes under this Party and its children.
+	//
+	// To disable logging for controllers under MVC Application,
+	// see `mvc/Application.SetControllersNoLog` instead.
+	//
+	// Defaults to false when log level is "debug".
+	SetRoutesNoLog(disable bool) Party
+
 	// OnErrorCode registers a handlers chain for this `Party` for a specific HTTP status code.
 	// Read more at: http://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml
 	// Look `UseError` and `OnAnyErrorCode` too.
diff --git a/i18n/loader.go b/i18n/loader.go
index 42c76438..34d88a0c 100644
--- a/i18n/loader.go
+++ b/i18n/loader.go
@@ -7,6 +7,7 @@ import (
 	"io/ioutil"
 	"path/filepath"
 	"strings"
+	"sync"
 	"text/template"
 
 	"github.com/kataras/iris/v12/context"
@@ -144,16 +145,15 @@ func load(assetNames []string, asset func(string) ([]byte, error), options ...Lo
 
 			t := m.Languages[langIndex]
 			locale := &defaultLocale{
-				index:        langIndex,
-				id:           t.String(),
-				tag:          &t,
-				templateKeys: templateKeys,
-				lineKeys:     lineKeys,
-				other:        other,
-
+				index:              langIndex,
+				id:                 t.String(),
+				tag:                &t,
+				templateKeys:       templateKeys,
+				lineKeys:           lineKeys,
+				other:              other,
 				defaultMessageFunc: m.defaultMessageFunc,
 			}
-
+			var longestValueLength int
 			for k, v := range keyValues {
 				// fmt.Printf("[%d] %s = %v of type: [%T]\n", langIndex, k, v, v)
 
@@ -176,24 +176,34 @@ func load(assetNames []string, asset func(string) ([]byte, error), options ...Lo
 							}
 						}
 
-						if t, err := template.New(k).
-							Delims(c.Left, c.Right).
-							Funcs(funcs).
-							Parse(value); err == nil {
+						t, err := template.New(k).Delims(c.Left, c.Right).Funcs(funcs).Parse(value)
+						if err == nil {
 							templateKeys[k] = t
-							continue
 						} else if c.Strict {
 							return nil, err
 						}
+
+						if valueLength := len(value); valueLength > longestValueLength {
+							longestValueLength = valueLength
+						}
 					}
 
 					lineKeys[k] = value
 				default:
 					other[k] = v
 				}
-
-				locales[langIndex] = locale
 			}
+
+			// pre-allocate the initial internal buffer.
+			// Note that Reset should be called immediately.
+			initBuf := []byte(strings.Repeat("x", longestValueLength))
+			locale.tmplBufPool = &sync.Pool{
+				New: func() interface{} {
+					// try to eliminate the internal "grow" method as much as possible.
+					return bytes.NewBuffer(initBuf)
+				},
+			}
+			locales[langIndex] = locale
 		}
 
 		if n := len(locales); n == 0 {
@@ -263,6 +273,8 @@ type defaultLocale struct {
 	other        map[string]interface{}
 
 	defaultMessageFunc MessageFunc
+
+	tmplBufPool *sync.Pool
 }
 
 func (l *defaultLocale) Index() int {
@@ -289,18 +301,26 @@ func (l *defaultLocale) GetMessageContext(ctx *context.Context, key string, args
 func (l *defaultLocale) getMessage(langInput, key string, args ...interface{}) string {
 	// search on templates.
 	if tmpl, ok := l.templateKeys[key]; ok {
-		var data interface{}
+		var (
+			data interface{}
+			text string
+		)
 		if len(args) > 0 {
 			data = args[0]
 		}
 
-		buf := new(bytes.Buffer)
+		buf := l.tmplBufPool.Get().(*bytes.Buffer)
+		buf.Reset()
+
 		err := tmpl.Execute(buf, data)
 		if err != nil {
-			return err.Error()
+			text = err.Error()
+		} else {
+			text = buf.String()
 		}
 
-		return buf.String()
+		l.tmplBufPool.Put(buf)
+		return text
 	}
 
 	if text, ok := l.lineKeys[key]; ok {
diff --git a/mvc/mvc.go b/mvc/mvc.go
index 0a319976..57d8a749 100644
--- a/mvc/mvc.go
+++ b/mvc/mvc.go
@@ -33,6 +33,10 @@ type Application struct {
 	Router               router.Party
 	Controllers          []*ControllerActivator
 	websocketControllers []websocket.ConnHandler
+
+	// Disables verbose logging for controllers under this and its children mvc apps.
+	// Defaults to false.
+	controllersNoLog bool
 }
 
 func newApp(subRouter router.Party, container *hero.Container) *Application {
@@ -115,6 +119,18 @@ func (app *Application) SetName(appName string) *Application {
 	return app
 }
 
+// SetControllersNoLog disables verbose logging for next registered controllers
+// under this App and its children of `Application.Party` or `Application.Clone`.
+//
+// To disable logging for routes under a Party,
+// see `Party.SetRoutesNoLog` instead.
+//
+// Defaults to false when log level is "debug".
+func (app *Application) SetControllersNoLog(disable bool) *Application {
+	app.controllersNoLog = disable
+	return app
+}
+
 // Register appends one or more values as dependencies.
 // The value can be a single struct value-instance or a function
 // which has one input and one output, the input should be
@@ -286,7 +302,9 @@ func (app *Application) handle(controller interface{}, options ...Option) *Contr
 	app.Controllers = append(app.Controllers, c)
 
 	// Note: log on register-time, so they can catch any failures before build.
-	logController(app.Router.Logger(), c)
+	if !app.controllersNoLog {
+		logController(app.Router.Logger(), c)
+	}
 
 	return c
 }
@@ -308,6 +326,7 @@ func (app *Application) HandleError(handler func(ctx *context.Context, err error
 // Example: `.Clone(app.Party("/path")).Handle(new(TodoSubController))`.
 func (app *Application) Clone(party router.Party) *Application {
 	cloned := newApp(party, app.container.Clone())
+	cloned.controllersNoLog = app.controllersNoLog
 	return cloned
 }