Repository: AvaloniaUI/Avalonia
File: src/Avalonia.Controls/Control.cs (C#)

Code before:
        };

        /// <summary>
        /// Schedules <see cref="OnLoadedCore"/> to be called for this control.
        /// For performance, it will be queued with other controls.
        /// </summary>
        internal void ScheduleOnLoadedCore()
        {
            if (_isLoaded == false)
            {
                bool isAdded = _loadedQueue.Add(this);

                if (isAdded &&
                    _isLoadedProcessing == false)
                {
                    _isLoadedProcessing = true;
                    Dispatcher.UIThread.Post(loadedProcessingAction!, DispatcherPriority.Loaded);
                }
            }
        }

        /// <summary>
        /// Invoked as the first step of marking the control as loaded and raising the
        /// <see cref="Loaded"/> event.
        /// </summary>
        internal virtual void OnLoadedCore()
        {
            if (_isLoaded == false &&
                ((ILogical)this).IsAttachedToLogicalTree)
            {
                _isLoaded = true;
                OnLoaded();
            }
        }

        /// <summary>
        /// Invoked as the first step of marking the control as unloaded and raising the
        /// <see cref="Unloaded"/> event.
        /// </summary>
        internal void OnUnloadedCore()
        {
            if (_isLoaded)
            {
                // Remove from the loaded event queue here as a failsafe in case the control
                // is detached before the dispatcher runs the Loaded jobs.
                _loadedQueue.Remove(this);

                _isLoaded = false;
                OnUnloaded();
            }
        }

Review comment (performance):
Two things:

 1. Should this really be virtual? I don't see it actually used anywhere. Since there were concerns about performance, and this is internal-only and not public, I would not mark it as virtual until really needed.
 2. If it is needed, OnUnloadedCore() should probably be virtual as well.

However, generally the Core methods are fixed and if you want to override something you override OnLoaded or OnUnloaded. So please let me know the use-cases here driving the change.

Code after:
        };

        /// <summary>
        /// Schedules <see cref="OnLoadedCore"/> to be called for this control.
        /// For performance, it will be queued with other controls.
        /// </summary>
        internal void ScheduleOnLoadedCore()
        {
            if (_isLoaded == false)
            {
                bool isAdded = _loadedQueue.Add(this);

                if (isAdded &&
                    _isLoadedProcessing == false)
                {
                    _isLoadedProcessing = true;
                    Dispatcher.UIThread.Post(loadedProcessingAction!, DispatcherPriority.Loaded);
                }
            }
        }

        /// <summary>
        /// Invoked as the first step of marking the control as loaded and raising the
        /// <see cref="Loaded"/> event.
        /// </summary>
        internal void OnLoadedCore()
        {
            if (_isLoaded == false &&
                ((ILogical)this).IsAttachedToLogicalTree)
            {
                _isLoaded = true;
                OnLoaded();
            }
        }

        /// <summary>
        /// Invoked as the first step of marking the control as unloaded and raising the
        /// <see cref="Unloaded"/> event.
        /// </summary>
        internal void OnUnloadedCore()
        {
            if (_isLoaded)
            {
                // Remove from the loaded event queue here as a failsafe in case the control
                // is detached before the dispatcher runs the Loaded jobs.
                _loadedQueue.Remove(this);

                _isLoaded = false;
                OnUnloaded();
            }
        }