@@ -15,8 +15,8 @@ var fs embed.FS
1515// localeCache stores parsed locale resources keyed by the embedded file path.
1616var localeCache sync.Map
1717
18- // localeEntry caches the parsed resources of a locale file .
19- type localeEntry struct {
18+ // cachedResources holds the cached resources for each language .
19+ type cachedResources struct {
2020 once sync.Once
2121 resources map [string ]string
2222 err error
@@ -77,9 +77,17 @@ func (lang *Language) SetLocale(locale string) *Language {
7777 return lang
7878 }
7979
80+ // Early return if locale hasn't changed and resources are already loaded
81+ lang .rw .RLock ()
82+ if lang .locale == locale && lang .resources != nil && len (lang .resources ) > 0 {
83+ lang .rw .RUnlock ()
84+ return lang
85+ }
86+ lang .rw .RUnlock ()
87+
8088 fileName := fmt .Sprintf ("%s/%s.json" , lang .dir , locale )
81- entryIface , _ := localeCache .LoadOrStore (fileName , new (localeEntry ))
82- entry := entryIface .(* localeEntry )
89+ load , _ := localeCache .LoadOrStore (fileName , new (cachedResources ))
90+ entry := load .(* cachedResources )
8391
8492 entry .once .Do (func () {
8593 bs , err := fs .ReadFile (fileName )
@@ -89,10 +97,7 @@ func (lang *Language) SetLocale(locale string) *Language {
8997 }
9098
9199 var resources map [string ]string
92- if err := json .Unmarshal (bs , & resources ); err != nil {
93- entry .err = fmt .Errorf ("failed to decode locale file %q: %w" , fileName , err )
94- return
95- }
100+ _ = json .Unmarshal (bs , & resources )
96101 entry .resources = resources
97102 })
98103
@@ -101,11 +106,18 @@ func (lang *Language) SetLocale(locale string) *Language {
101106 return lang
102107 }
103108
104- lang .rw .Lock ()
105- defer lang .rw .Unlock ()
109+ // Create a copy of the cached resources to avoid modifying the cache
110+ // Pre-allocate with exact capacity for better memory efficiency
111+ newResources := make (map [string ]string , len (entry .resources ))
112+ for k , v := range entry .resources {
113+ newResources [k ] = v
114+ }
106115
116+ lang .rw .Lock ()
107117 lang .locale = locale
108- lang .resources = entry .resources
118+ lang .resources = newResources
119+ lang .rw .Unlock ()
120+
109121 return lang
110122}
111123
0 commit comments