diff --git a/src/core/services/utils/utils.ts b/src/core/services/utils/utils.ts
index 1d267b7ce..75e68885f 100644
--- a/src/core/services/utils/utils.ts
+++ b/src/core/services/utils/utils.ts
@@ -1491,7 +1491,7 @@ export class CoreUtilsProvider {
     debounce<T extends unknown[]>(fn: (...args: T) => unknown, delay: number): (...args: T) => void {
         let timeoutID: number;
 
-        const debounced = (...args: unknown[]): void => {
+        const debounced = (...args: T): void => {
             clearTimeout(timeoutID);
 
             timeoutID = window.setTimeout(() => fn.apply(null, args), delay);
diff --git a/src/core/singletons/logger.ts b/src/core/singletons/logger.ts
index 88e1dd93d..be7209703 100644
--- a/src/core/singletons/logger.ts
+++ b/src/core/singletons/logger.ts
@@ -16,6 +16,16 @@ import moment from 'moment';
 
 import { CoreConstants } from '@/core/constants';
 
+import { CoreTime } from './time';
+
+/**
+ * Method to warn that logs are disabled, called only once.
+ */
+const warnLogsDisabled = CoreTime.once(() => {
+    // eslint-disable-next-line no-console
+    console.warn('Log is disabled in production app');
+});
+
 /**
  * Log function type.
  */
@@ -59,8 +69,7 @@ export class CoreLogger {
         // Disable log on production and testing.
         if (CoreConstants.BUILD.isProduction || CoreConstants.BUILD.isTesting) {
             if (CoreConstants.BUILD.isProduction) {
-                // eslint-disable-next-line no-console
-                console.warn('Log is disabled in production app');
+                warnLogsDisabled();
             }
 
             // eslint-disable-next-line @typescript-eslint/no-empty-function
diff --git a/src/core/singletons/time.ts b/src/core/singletons/time.ts
new file mode 100644
index 000000000..8e8f92018
--- /dev/null
+++ b/src/core/singletons/time.ts
@@ -0,0 +1,39 @@
+// (C) Copyright 2015 Moodle Pty Ltd.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+/**
+ * Singleton with helper functions for time operations.
+ */
+export class CoreTime {
+
+    /**
+     * Wrap a function so that it is called only once.
+     *
+     * @param fn Function.
+     * @return Wrapper that will call the underlying function only once.
+     */
+    static once<T extends unknown[]>(fn: (...args: T) => unknown): (...args: T) => void {
+        let called = false;
+
+        return (...args: T) => {
+            if (called) {
+                return;
+            }
+
+            called = true;
+            fn.apply(null, args);
+        };
+    }
+
+}