[NUI] Make Action id as internal static readonly
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI / src / public / BaseComponents / ImageView.cs
index e22ffef..af61687 100755 (executable)
@@ -15,6 +15,7 @@
 *
 */
 using System;
+using System.Collections.Generic;
 using System.Runtime.InteropServices;
 using System.ComponentModel;
 using Tizen.NUI.Binding;
@@ -36,16 +37,55 @@ namespace Tizen.NUI.BaseComponents
         private EventHandler<ResourceLoadedEventArgs> _resourceLoadedEventHandler;
         private _resourceLoadedCallbackType _resourceLoadedCallback;
 
+        /// <summary>
+        /// Convert non-null string that some keyword change as application specific directory.
+        /// </summary>
+        /// <param name="value">Inputed and replaced after this function finished</param>
+        /// <returns>Replaced url</returns>
+        private static string ConvertResourceUrl(ref string value)
+        {
+            value ??= "";
+            if (value.StartsWith("*Resource*"))
+            {
+                string resource = Tizen.Applications.Application.Current.DirectoryInfo.Resource;
+                value = value.Replace("*Resource*", resource);
+            }
+            return value;
+        }
+
+        // Collection of image-sensitive properties.
+        private static readonly List<int> cachedImagePropertyKeyList = new List<int> {
+            Visual.Property.Type,
+            ImageVisualProperty.URL,
+            ImageVisualProperty.AlphaMaskURL,
+            ImageVisualProperty.CropToMask,
+            Visual.Property.VisualFittingMode,
+            ImageVisualProperty.DesiredWidth,
+            ImageVisualProperty.DesiredHeight,
+            ImageVisualProperty.ReleasePolicy,
+            ImageVisualProperty.WrapModeU,
+            ImageVisualProperty.WrapModeV,
+            ImageVisualProperty.SynchronousLoading,
+            Visual.Property.PremultipliedAlpha,
+            ImageVisualProperty.OrientationCorrection,
+            ImageVisualProperty.FastTrackUploading,
+            NpatchImageVisualProperty.Border,
+            NpatchImageVisualProperty.BorderOnly,
+        };
+        internal PropertyMap cachedImagePropertyMap;
+        internal bool imagePropertyUpdatedFlag = false;
+
+        private bool imagePropertyUpdateProcessAttachedFlag = false;
         private Rectangle _border;
         private string _resourceUrl = "";
-        private bool _synchronousLoading = false;
-        private string _alphaMaskUrl = null;
         private int _desired_width = -1;
         private int _desired_height = -1;
-        private VisualFittingModeType _fittingMode = VisualFittingModeType.Fill;
+        private bool _fastTrackUploading = false;
         private TriggerableSelector<string> resourceUrlSelector;
         private TriggerableSelector<Rectangle> borderSelector;
 
+        private RelativeVector4 internalPixelArea;
+
         /// <summary>
         /// Creates an initialized ImageView.
         /// </summary>
@@ -79,9 +119,15 @@ namespace Tizen.NUI.BaseComponents
         /// </summary>
         /// <param name="url">The URL of the image resource to display.</param>
         /// <since_tizen> 3 </since_tizen>
-        public ImageView(string url) : this(Interop.ImageView.New(url), true)
+        public ImageView(string url) : this(Interop.ImageView.New(ConvertResourceUrl(ref url)), true)
         {
-            ResourceUrl = url;
+            _resourceUrl = url;
+
+            // Update cached property. Note that we should not re-create new visual.
+            using (PropertyValue urlValue = new PropertyValue(_resourceUrl))
+            {
+                UpdateImage(ImageVisualProperty.URL, urlValue, false);
+            }
             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
 
         }
@@ -93,16 +139,38 @@ namespace Tizen.NUI.BaseComponents
         /// <param name="shown">false : Not displayed (hidden), true : displayed (shown)</param>
         /// This will be public opened in next release of tizen after ACR done. Before ACR, it is used as HiddenAPI (InhouseAPI).
         [EditorBrowsable(EditorBrowsableState.Never)]
-        public ImageView(string url, bool shown) : this(Interop.ImageView.New(url), true)
+        public ImageView(string url, bool shown) : this(Interop.ImageView.New(ConvertResourceUrl(ref url)), true)
         {
-            ResourceUrl = url;
+            _resourceUrl = url;
+
+            // Update cached property. Note that we should not re-create new visual.
+            using (PropertyValue urlValue = new PropertyValue(_resourceUrl))
+            {
+                UpdateImage(ImageVisualProperty.URL, urlValue, false);
+            }
             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
             SetVisible(shown);
         }
 
-        internal ImageView(string url, Uint16Pair size, bool shown = true) : this(Interop.ImageView.New(url, Uint16Pair.getCPtr(size)), true)
+        internal ImageView(string url, Uint16Pair size, bool shown = true) : this(Interop.ImageView.New(ConvertResourceUrl(ref url), Uint16Pair.getCPtr(size)), true)
         {
-            ResourceUrl = url;
+            _resourceUrl = url;
+            _desired_width = size?.GetWidth() ?? -1;
+            _desired_height = size?.GetHeight() ?? -1;
+
+            // Update cached property. Note that we should not re-create new visual.
+            using (PropertyValue urlValue = new PropertyValue(_resourceUrl))
+            {
+                UpdateImage(ImageVisualProperty.URL, urlValue, false);
+            }
+            using (PropertyValue desiredWidthValue = new PropertyValue(_desired_width))
+            {
+                UpdateImage(ImageVisualProperty.DesiredWidth, desiredWidthValue, false);
+            }
+            using (PropertyValue desiredHeightValue = new PropertyValue(_desired_height))
+            {
+                UpdateImage(ImageVisualProperty.DesiredWidth, desiredHeightValue, false);
+            }
             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
 
             if (!shown)
@@ -216,6 +284,24 @@ namespace Tizen.NUI.BaseComponents
         }
 
         /// <summary>
+        /// Enumeration for MaskingMode of image.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public enum MaskingModeType
+        {
+            /// <summary>
+            /// Applies alpha masking on rendering time.
+            /// </summary>
+            [EditorBrowsable(EditorBrowsableState.Never)]
+            MaskingOnRendering,
+            /// <summary>
+            /// Applies alpha masking on loading time.
+            /// </summary>
+            [EditorBrowsable(EditorBrowsableState.Never)]
+            MaskingOnLoading
+        }
+
+        /// <summary>
         /// ImageView ResourceUrl, type string.
         /// This is one of mandatory property. Even if not set or null set, it sets empty string ("") internally.
         /// When it is set as null, it gives empty string ("") to be read.
@@ -235,11 +321,11 @@ namespace Tizen.NUI.BaseComponents
         }
 
         /// <summary>
-        /// This will be deprecated, please use Image instead. <br />
+        /// This will be deprecated, Use Image instead. <br />
         /// ImageView ImageMap, type PropertyMap: string if it is a URL, map otherwise.
         /// </summary>
         /// <since_tizen> 3 </since_tizen>
-        [Obsolete("Please do not use! This will be deprecated! Please use Image property instead!")]
+        [Obsolete("Do not use this, that will be deprecated. Use Image property instead.")]
         [EditorBrowsable(EditorBrowsableState.Never)]
         public PropertyMap ImageMap
         {
@@ -259,10 +345,20 @@ namespace Tizen.NUI.BaseComponents
             {
                 if (_border == null)
                 {
+                    // Sync as current properties
+                    UpdateImage();
+
+                    // Get current properties force.
                     PropertyMap returnValue = new PropertyMap();
                     PropertyValue image = GetProperty(ImageView.Property.IMAGE);
                     image?.Get(returnValue);
                     image?.Dispose();
+
+                    // Update cached property map
+                    if (returnValue != null)
+                    {
+                        MergeCachedImageVisualProperty(returnValue);
+                    }
                     return returnValue;
                 }
                 else
@@ -276,6 +372,13 @@ namespace Tizen.NUI.BaseComponents
                 {
                     PropertyValue setValue = new Tizen.NUI.PropertyValue(value);
                     SetProperty(ImageView.Property.IMAGE, setValue);
+
+                    // Image properties are changed hardly. We should ignore lazy UpdateImage
+                    imagePropertyUpdatedFlag = false;
+                    cachedImagePropertyMap?.Dispose();
+                    cachedImagePropertyMap = null;
+                    MergeCachedImageVisualProperty(value);
+
                     NotifyPropertyChanged();
                     setValue?.Dispose();
                 }
@@ -355,8 +458,7 @@ namespace Tizen.NUI.BaseComponents
         {
             get
             {
-                RelativeVector4 temp = (RelativeVector4)GetValue(PixelAreaProperty);
-                return new RelativeVector4(OnPixelAreaChanged, temp.X, temp.Y, temp.Z, temp.W);
+                return (RelativeVector4)GetValue(PixelAreaProperty);
             }
             set
             {
@@ -420,7 +522,7 @@ namespace Tizen.NUI.BaseComponents
         /// Gets or sets whether to synchronous loading the resourceurl of image.<br />
         /// </summary>
         /// <since_tizen> 3 </since_tizen>
-        [Obsolete("Deprecated since API level 9 and will be removed in API level 11. Please use SynchronousLoading instead!")]
+        [Obsolete("This has been deprecated since API9 and will be removed in API11. Use SynchronousLoading instead.")]
         public bool SynchronosLoading
         {
             get
@@ -438,7 +540,7 @@ namespace Tizen.NUI.BaseComponents
         /// </summary>
         /// <remarks>
         /// Changing this property make this ImageView load image synchronously at the next loading
-        /// by following operation: <see cref="Reload"/>, <see cref="SetImage"/>,
+        /// by following operation: <see cref="Reload"/>, <see cref="SetImage(string)"/>,
         /// and by some properties those cause reloading: <see cref="ResourceUrl"/>, <see cref="PreMultipliedAlpha"/> and etc.
         /// </remarks>
         /// <since_tizen> 9 </since_tizen>
@@ -473,6 +575,102 @@ namespace Tizen.NUI.BaseComponents
         }
 
         /// <summary>
+        /// Gets or sets whether to apply mask on GPU or not.<br />
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public MaskingModeType MaskingMode
+        {
+            get
+            {
+                return (MaskingModeType)GetValue(MaskingModeProperty);
+            }
+            set
+            {
+                SetValue(MaskingModeProperty, value);
+                NotifyPropertyChanged();
+            }
+        }
+
+        private MaskingModeType InternalMaskingMode
+        {
+            get
+            {
+                int ret = (int)MaskingModeType.MaskingOnLoading;
+
+                PropertyValue maskingMode = GetCachedImageVisualProperty(ImageVisualProperty.MaskingMode);
+                maskingMode?.Get(out ret);
+                maskingMode?.Dispose();
+
+                return (MaskingModeType)ret;
+            }
+            set
+            {
+                MaskingModeType ret = value;
+                PropertyValue setValue = new PropertyValue((int)ret);
+                UpdateImage(ImageVisualProperty.MaskingMode, setValue);
+                setValue?.Dispose();
+            }
+        }
+
+        /// <summary>
+        /// Gets or sets whether to apply fast track uploading or not.<br />
+        /// </summary>
+        /// <remarks>
+        /// If we use fast track uploading feature, It can upload texture without event-thead dependency. But also,<br />
+        ///  - Texture size is invalid until ResourceReady signal comes.<br />
+        ///  - Texture cannot be cached (We always try to load new image).<br />
+        ///  - Seamless visual change didn't supported.<br />
+        ///  - Alpha masking didn't supported. If you try, It will load as normal case.<br />
+        ///  - Synchronous loading didn't supported. If you try, It will load as normal case.<br />
+        ///  - Reload action didn't supported. If you try, It will load as normal case.<br />
+        ///  - Atlas loading didn't supported. If you try, It will load as normal case.<br />
+        ///  - Custom shader didn't supported. If you try, It will load as normal case.
+        /// </remarks>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public bool FastTrackUploading
+        {
+            get
+            {
+                return (bool)GetValue(FastTrackUploadingProperty);
+            }
+            set
+            {
+                SetValue(FastTrackUploadingProperty, value);
+                NotifyPropertyChanged();
+            }
+        }
+
+        private bool InternalFastTrackUploading
+        {
+            get
+            {
+                PropertyValue fastTrackUploading = GetCachedImageVisualProperty(ImageVisualProperty.FastTrackUploading);
+                fastTrackUploading?.Get(out _fastTrackUploading);
+                fastTrackUploading?.Dispose();
+
+                return _fastTrackUploading;
+            }
+            set
+            {
+                if (_fastTrackUploading != value)
+                {
+                    _fastTrackUploading = value;
+
+                    PropertyValue setValue = new PropertyValue(_fastTrackUploading);
+                    UpdateImage(ImageVisualProperty.FastTrackUploading, setValue);
+                    setValue?.Dispose();
+
+                    if (_fastTrackUploading && !string.IsNullOrEmpty(_resourceUrl))
+                    {
+                        // Special case. If user set FastTrackUploading mean, user want to upload image As-Soon-As-Possible.
+                        // Create ImageVisual synchronously.
+                        UpdateImage();
+                    }
+                }
+            }
+        }
+
+        /// <summary>
         /// Gets the loading state of the visual resource.
         /// </summary>
         /// <since_tizen> 5 </since_tizen>
@@ -488,10 +686,9 @@ namespace Tizen.NUI.BaseComponents
         /// Downcasts a handle to imageView handle.
         /// </summary>
         /// <exception cref="ArgumentNullException"> Thrown when handle is null. </exception>
-        /// Please do not use! this will be deprecated!
-        /// Instead please use as keyword.
+        /// Do not use this, that will be deprecated. Use as keyword instead.
         /// <since_tizen> 3 </since_tizen>
-        [Obsolete("Please do not use! This will be deprecated! Please use as keyword instead! " +
+        [Obsolete("Do not use this, that will be deprecated. Use as keyword instead. " +
         "Like: " +
         "BaseHandle handle = new ImageView(imagePath); " +
         "ImageView image = handle as ImageView")]
@@ -523,14 +720,20 @@ namespace Tizen.NUI.BaseComponents
 
             if (url.Contains(".json"))
             {
-                Tizen.Log.Fatal("NUI", "[ERROR] Please DO NOT set lottie file in ImageView! This is temporary checking, will be removed soon!");
+                Tizen.Log.Fatal("NUI", "[ERROR] Do not set lottie file in ImageView! This is temporary checking, will be removed soon!");
                 return;
             }
 
-            Interop.ImageView.SetImage(SwigCPtr, url);
+            Interop.ImageView.SetImage(SwigCPtr, ConvertResourceUrl(ref url));
             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
 
-            ResourceUrl = url;
+            _resourceUrl = url;
+            // Update cached property. Note that we should not re-create new visual.
+            using (PropertyValue urlValue = new PropertyValue(_resourceUrl))
+            {
+                UpdateImage(ImageVisualProperty.URL, urlValue, false);
+            }
+            imagePropertyUpdatedFlag = false;
         }
 
         /// <summary>
@@ -553,9 +756,11 @@ namespace Tizen.NUI.BaseComponents
         /// <since_tizen> 5 </since_tizen>
         public void Reload()
         {
-            PropertyValue attributes = new PropertyValue(0);
-            this.DoAction(ImageView.Property.IMAGE, Property.ActionReload, attributes);
-            attributes?.Dispose();
+            // Sync as current properties
+            UpdateImage();
+
+
+            Interop.View.DoActionWithEmptyAttributes(this.SwigCPtr, ImageView.Property.IMAGE, ActionReload);
         }
 
         /// <summary>
@@ -564,9 +769,11 @@ namespace Tizen.NUI.BaseComponents
         /// <since_tizen> 5 </since_tizen>
         public void Play()
         {
-            PropertyValue attributes = new PropertyValue(0);
-            this.DoAction(ImageView.Property.IMAGE, Property.ActionPlay, attributes);
-            attributes?.Dispose();
+            // Sync as current properties
+            UpdateImage();
+
+
+            Interop.View.DoActionWithEmptyAttributes(this.SwigCPtr, ImageView.Property.IMAGE, ActionPlay);
         }
 
         /// <summary>
@@ -575,9 +782,11 @@ namespace Tizen.NUI.BaseComponents
         /// <since_tizen> 5 </since_tizen>
         public void Pause()
         {
-            PropertyValue attributes = new PropertyValue(0);
-            this.DoAction(ImageView.Property.IMAGE, Property.ActionPause, attributes);
-            attributes?.Dispose();
+            // Sync as current properties
+            UpdateImage();
+
+
+            Interop.View.DoActionWithEmptyAttributes(this.SwigCPtr, ImageView.Property.IMAGE, ActionPause);
         }
 
         /// <summary>
@@ -586,9 +795,12 @@ namespace Tizen.NUI.BaseComponents
         /// <since_tizen> 5 </since_tizen>
         public void Stop()
         {
-            PropertyValue attributes = new PropertyValue(0);
-            this.DoAction(ImageView.Property.IMAGE, Property.ActionStop, attributes);
-            attributes?.Dispose();
+            // Sync as current properties
+            UpdateImage();
+
+
+
+            Interop.View.DoActionWithEmptyAttributes(this.SwigCPtr, ImageView.Property.IMAGE, ActionStop);
         }
 
         /// <summary>
@@ -615,30 +827,26 @@ namespace Tizen.NUI.BaseComponents
             get
             {
                 string ret = "";
-                PropertyMap imageMap = new PropertyMap();
-                PropertyValue image = Tizen.NUI.Object.GetProperty(SwigCPtr, ImageView.Property.IMAGE);
-                image?.Get(imageMap);
-                PropertyValue maskUrl = imageMap?.Find(ImageVisualProperty.AlphaMaskURL);
-                maskUrl?.Get(out ret);
-                _alphaMaskUrl = ret;
 
-                imageMap?.Dispose();
-                image?.Dispose();
+                PropertyValue maskUrl = GetCachedImageVisualProperty(ImageVisualProperty.AlphaMaskURL);
+                maskUrl?.Get(out ret);
                 maskUrl?.Dispose();
 
                 return ret;
             }
             set
             {
-                if (value == null)
+                PropertyValue setValue = new PropertyValue(value ?? "");
+                UpdateImage(ImageVisualProperty.AlphaMaskURL, setValue);
+                // When we never set CropToMask property before, we should set default value as true.
+                using (PropertyValue cropToMask = GetCachedImageVisualProperty(ImageVisualProperty.CropToMask))
                 {
-                    value = "";
+                    if (cropToMask == null)
+                    {
+                        using PropertyValue setCropValue = new PropertyValue(true);
+                        UpdateImage(ImageVisualProperty.CropToMask, setCropValue);
+                    }
                 }
-
-                _alphaMaskUrl = value;
-
-                PropertyValue setValue = new PropertyValue(value);
-                UpdateImage(ImageVisualProperty.AlphaMaskURL, setValue);
                 setValue?.Dispose();
             }
         }
@@ -665,15 +873,10 @@ namespace Tizen.NUI.BaseComponents
             get
             {
                 bool ret = false;
-                PropertyMap imageMap = new PropertyMap();
-                PropertyValue image = Tizen.NUI.Object.GetProperty(SwigCPtr, ImageView.Property.IMAGE);
-                image?.Get(imageMap);
-                PropertyValue cropUrl = imageMap?.Find(ImageVisualProperty.CropToMask);
-                cropUrl?.Get(out ret);
 
-                imageMap?.Dispose();
-                image?.Dispose();
-                cropUrl?.Dispose();
+                PropertyValue cropToMask = GetCachedImageVisualProperty(ImageVisualProperty.CropToMask);
+                cropToMask?.Get(out ret);
+                cropToMask?.Dispose();
 
                 return ret;
             }
@@ -681,11 +884,31 @@ namespace Tizen.NUI.BaseComponents
             {
                 PropertyValue setValue = new PropertyValue(value);
                 UpdateImage(ImageVisualProperty.CropToMask, setValue);
-                setValue.Dispose();
+                setValue?.Dispose();
             }
         }
 
-        internal VisualFittingModeType CovertFittingModetoVisualFittingMode(FittingModeType value)
+        /// <summary>
+        /// Actions property value for Reload image.
+        /// </summary>
+        internal static readonly int ActionReload = Interop.ImageView.ImageVisualActionReloadGet();
+
+        /// <summary>
+        /// Actions property value to Play animated images.
+        /// </summary>
+        internal static readonly int ActionPlay = Interop.AnimatedImageView.AnimatedImageVisualActionPlayGet();
+
+        /// <summary>
+        /// Actions property value to Pause animated images.
+        /// </summary>
+        internal static readonly int ActionPause = Interop.AnimatedImageView.AnimatedImageVisualActionPauseGet();
+
+        /// <summary>
+        /// Actions property value to Stop animated images.
+        /// </summary>
+        internal static readonly int ActionStop = Interop.AnimatedImageView.AnimatedImageVisualActionStopGet();
+
+        internal VisualFittingModeType ConvertFittingModetoVisualFittingMode(FittingModeType value)
         {
             switch (value)
             {
@@ -700,7 +923,7 @@ namespace Tizen.NUI.BaseComponents
                 case FittingModeType.FitHeight:
                     return VisualFittingModeType.FitHeight;
                 case FittingModeType.FitWidth:
-                    return VisualFittingModeType.FitHeight;
+                    return VisualFittingModeType.FitWidth;
                 default:
                     return VisualFittingModeType.Fill;
             }
@@ -757,35 +980,23 @@ namespace Tizen.NUI.BaseComponents
         {
             get
             {
-                int ret = (int)_fittingMode;
-                PropertyMap imageMap = new PropertyMap();
-                PropertyValue image = Tizen.NUI.Object.GetProperty(SwigCPtr, ImageView.Property.IMAGE);
-                image?.Get(imageMap);
-                PropertyValue fittingMode = imageMap?.Find(Visual.Property.VisualFittingMode);
-                fittingMode?.Get(out ret);
-                _fittingMode = (VisualFittingModeType)ret;
+                int ret = (int)VisualFittingModeType.Fill;
 
-                imageMap?.Dispose();
-                image?.Dispose();
+                PropertyValue fittingMode = GetCachedImageVisualProperty(Visual.Property.VisualFittingMode);
+                fittingMode?.Get(out ret);
                 fittingMode?.Dispose();
 
                 return ConvertVisualFittingModetoFittingMode((VisualFittingModeType)ret);
             }
             set
             {
-                VisualFittingModeType ret = CovertFittingModetoVisualFittingMode(value);
+                VisualFittingModeType ret = ConvertFittingModetoVisualFittingMode(value);
                 PropertyValue setValue = new PropertyValue((int)ret);
-                if(_fittingMode != ret)
-                {
-                    _fittingMode = ret;
-                    UpdateImage(Visual.Property.VisualFittingMode, setValue);
-                }
+                UpdateImage(Visual.Property.VisualFittingMode, setValue);
                 setValue?.Dispose();
             }
         }
 
-
-
         /// <summary>
         /// Gets or sets the desired image width.<br />
         /// If not specified, the actual image width is used.<br />
@@ -810,15 +1021,14 @@ namespace Tizen.NUI.BaseComponents
         {
             get
             {
-                PropertyMap imageMap = new PropertyMap();
-                PropertyValue image = Tizen.NUI.Object.GetProperty(SwigCPtr, ImageView.Property.IMAGE);
-                image?.Get(imageMap);
-                PropertyValue desireWidth = imageMap?.Find(ImageVisualProperty.DesiredWidth);
-                desireWidth?.Get(out _desired_width);
-
-                imageMap?.Dispose();
-                image?.Dispose();
-                desireWidth?.Dispose();
+                // Sync as current properties only if both _desired_width and _desired_height are setuped.
+                if (_desired_width != -1 && _desired_height != -1)
+                {
+                    UpdateImage();
+                }
+                PropertyValue desirewidth = GetCachedImageVisualProperty(ImageVisualProperty.DesiredWidth);
+                desirewidth?.Get(out _desired_width);
+                desirewidth?.Dispose();
 
                 return _desired_width;
             }
@@ -827,7 +1037,9 @@ namespace Tizen.NUI.BaseComponents
                 if (_desired_width != value)
                 {
                     _desired_width = value;
-                    UpdateImage(0, null);
+                    PropertyValue setValue = new PropertyValue(value);
+                    UpdateImage(ImageVisualProperty.DesiredWidth, setValue, false);
+                    setValue?.Dispose();
                 }
             }
         }
@@ -856,14 +1068,13 @@ namespace Tizen.NUI.BaseComponents
         {
             get
             {
-                PropertyMap imageMap = new PropertyMap();
-                PropertyValue image = Tizen.NUI.Object.GetProperty(SwigCPtr, ImageView.Property.IMAGE);
-                image?.Get(imageMap);
-                PropertyValue desireheight = imageMap?.Find(ImageVisualProperty.DesiredHeight);
+                // Sync as current properties only if both _desired_width and _desired_height are setuped.
+                if (_desired_width != -1 && _desired_height != -1)
+                {
+                    UpdateImage();
+                }
+                PropertyValue desireheight = GetCachedImageVisualProperty(ImageVisualProperty.DesiredHeight);
                 desireheight?.Get(out _desired_height);
-
-                imageMap?.Dispose();
-                image?.Dispose();
                 desireheight?.Dispose();
 
                 return _desired_height;
@@ -873,7 +1084,9 @@ namespace Tizen.NUI.BaseComponents
                 if (_desired_height != value)
                 {
                     _desired_height = value;
-                    UpdateImage(0, null);
+                    PropertyValue setValue = new PropertyValue(value);
+                    UpdateImage(ImageVisualProperty.DesiredHeight, setValue, false);
+                    setValue?.Dispose();
                 }
             }
         }
@@ -895,20 +1108,15 @@ namespace Tizen.NUI.BaseComponents
                 NotifyPropertyChanged();
             }
         }
-        
+
         private ReleasePolicyType InternalReleasePolicy
         {
             get
             {
                 int ret = (int)ReleasePolicyType.Detached;
-                PropertyMap imageMap = new PropertyMap();
-                PropertyValue image = Tizen.NUI.Object.GetProperty(SwigCPtr, ImageView.Property.IMAGE);
-                image?.Get(imageMap);
-                PropertyValue releasePoli = imageMap?.Find(ImageVisualProperty.ReleasePolicy);
-                releasePoli?.Get(out ret);
 
-                imageMap?.Dispose();
-                image?.Dispose();
+                PropertyValue releasePoli = GetCachedImageVisualProperty(ImageVisualProperty.ReleasePolicy);
+                releasePoli?.Get(out ret);
                 releasePoli?.Dispose();
 
                 return (ReleasePolicyType)ret;
@@ -948,15 +1156,10 @@ namespace Tizen.NUI.BaseComponents
             get
             {
                 int ret = (int)WrapModeType.Default;
-                PropertyMap imageMap = new PropertyMap();
-                PropertyValue image = Tizen.NUI.Object.GetProperty(SwigCPtr, ImageView.Property.IMAGE);
-                image?.Get(imageMap);
-                PropertyValue warpModeU = imageMap?.Find(ImageVisualProperty.WrapModeU);
-                warpModeU?.Get(out ret);
 
-                imageMap?.Dispose();
-                image?.Dispose();
-                warpModeU?.Dispose();
+                PropertyValue wrapModeU = GetCachedImageVisualProperty(ImageVisualProperty.WrapModeU);
+                wrapModeU?.Get(out ret);
+                wrapModeU?.Dispose();
 
                 return (WrapModeType)ret;
             }
@@ -996,14 +1199,9 @@ namespace Tizen.NUI.BaseComponents
             get
             {
                 int ret = (int)WrapModeType.Default;
-                PropertyMap imageMap = new PropertyMap();
-                PropertyValue image = Tizen.NUI.Object.GetProperty(SwigCPtr, ImageView.Property.IMAGE);
-                image?.Get(imageMap);
-                PropertyValue wrapModeV = imageMap?.Find(ImageVisualProperty.WrapModeV);
-                wrapModeV?.Get(out ret);
 
-                imageMap?.Dispose();
-                image?.Dispose();
+                PropertyValue wrapModeV = GetCachedImageVisualProperty(ImageVisualProperty.WrapModeV);
+                wrapModeV?.Get(out ret);
                 wrapModeV?.Dispose();
 
                 return (WrapModeType)ret;
@@ -1018,10 +1216,16 @@ namespace Tizen.NUI.BaseComponents
 
         /// <summary>
         /// Gets or sets the mode to adjust view size to preserve the aspect ratio of the image resource.
-        /// If this is set to be true, then the width or height, which is not set by user explicitly, can be adjusted to preserve the aspect ratio of the image resource.
-        /// AdjustViewSize works only if ImageView is added to a View having Layout.
         /// </summary>
-        [EditorBrowsable(EditorBrowsableState.Never)]
+        /// <remarks>
+        /// This is false by default.
+        /// If this is set to be true, then the width or height value, which is not set by user explicitly, can be changed automatically
+        /// to preserve the aspect ratio of the image resource.
+        /// AdjustViewSize works only if ImageView is added to a View having Layout.
+        /// e.g. If the image resource size is (100, 100), then the ImageView requests size (100, 100) to its parent layout by default.
+        ///      If the ImageView's HeightSpecification is 50 and AdjustViewSize is true, then the ImageView requests size (50, 50) instead of (100, 50).
+        /// </remarks>
+        /// <since_tizen> 9 </since_tizen>
         public bool AdjustViewSize
         {
             get
@@ -1036,6 +1240,44 @@ namespace Tizen.NUI.BaseComponents
         }
         private bool adjustViewSize = false;
 
+        /// <summary>
+        /// ImageView PlaceHolderUrl, type string.
+        /// This is one of mandatory property. Even if not set or null set, it sets empty string ("") internally.
+        /// When it is set as null, it gives empty string ("") to be read.
+        /// </summary>
+        /// <since_tizen> 11 </since_tizen>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public string PlaceHolderUrl
+        {
+            get
+            {
+                return (string)GetValue(PlaceHolderUrlProperty);
+            }
+            set
+            {
+                SetValue(PlaceHolderUrlProperty, value);
+                NotifyPropertyChanged();
+            }
+        }
+
+        /// <summary>
+        /// Gets or sets whether the image use TransitionEffect or not<br />
+        /// </summary>
+        /// <since_tizen> 11 </since_tizen>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public bool TransitionEffect
+        {
+            get
+            {
+                return (bool)GetValue(TransitionEffectProperty);
+            }
+            set
+            {
+                SetValue(TransitionEffectProperty, value);
+                NotifyPropertyChanged();
+            }
+        }
+
         internal Selector<string> ResourceUrlSelector
         {
             get => GetSelector<string>(resourceUrlSelector, ImageView.ResourceUrlProperty);
@@ -1062,14 +1304,31 @@ namespace Tizen.NUI.BaseComponents
         {
             if (url.Contains(".json"))
             {
-                Tizen.Log.Fatal("NUI", "[ERROR] Please DO NOT set lottie file in ImageView! This is temporary checking, will be removed soon!");
+                Tizen.Log.Fatal("NUI", "[ERROR] Do not set lottie file in ImageView! This is temporary checking, will be removed soon!");
                 return;
             }
 
-            Interop.ImageView.SetImage(SwigCPtr, url, Uint16Pair.getCPtr(size));
+            Interop.ImageView.SetImage(SwigCPtr, ConvertResourceUrl(ref url), Uint16Pair.getCPtr(size));
             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
 
-            ResourceUrl = url;
+            _resourceUrl = url;
+            _desired_width = size?.GetWidth() ?? -1;
+            _desired_height = size?.GetHeight() ?? -1;
+
+            // Update cached property. Note that we should not re-create new visual.
+            using (PropertyValue urlValue = new PropertyValue(_resourceUrl))
+            {
+                UpdateImage(ImageVisualProperty.URL, urlValue, false);
+            }
+            using (PropertyValue desiredWidthValue = new PropertyValue(_desired_width))
+            {
+                UpdateImage(ImageVisualProperty.DesiredWidth, desiredWidthValue, false);
+            }
+            using (PropertyValue desiredHeightValue = new PropertyValue(_desired_height))
+            {
+                UpdateImage(ImageVisualProperty.DesiredWidth, desiredHeightValue, false);
+            }
+            imagePropertyUpdatedFlag = false;
         }
 
         internal ViewResourceReadySignal ResourceReadySignal(View view)
@@ -1083,36 +1342,28 @@ namespace Tizen.NUI.BaseComponents
         {
             base.ApplyCornerRadius();
 
-            UpdateImage(0, null);
+            if (backgroundExtraData == null) return;
+
+
+            // Update corner radius properties to image by ActionUpdateProperty
+            if (backgroundExtraData.CornerRadius != null)
+            {
+                Interop.View.InternalUpdateVisualPropertyVector4(this.SwigCPtr, ImageView.Property.IMAGE, Visual.Property.CornerRadius, Vector4.getCPtr(backgroundExtraData.CornerRadius));
+            }
+            Interop.View.InternalUpdateVisualPropertyInt(this.SwigCPtr, ImageView.Property.IMAGE, Visual.Property.CornerRadiusPolicy, (int)backgroundExtraData.CornerRadiusPolicy);
         }
 
         internal override void ApplyBorderline()
         {
             base.ApplyBorderline();
 
-            // Apply borderline to IMAGE.
-            if (backgroundExtraData != null)
-            {
-                var borderlineColor = backgroundExtraData.BorderlineColor == null ? new PropertyValue(Color.Black) : new PropertyValue(backgroundExtraData.BorderlineColor);
+            if (backgroundExtraData == null) return;
 
-                // Apply to the image visual
-                PropertyMap imageMap = new PropertyMap();
-                PropertyValue imageValue = Tizen.NUI.Object.GetProperty(SwigCPtr, ImageView.Property.IMAGE);
-                if (imageValue.Get(imageMap) && !imageMap.Empty())
-                {
-                    imageMap[Visual.Property.BorderlineWidth] = new PropertyValue(backgroundExtraData.BorderlineWidth);
-                    imageMap[Visual.Property.BorderlineColor] = borderlineColor;
-                    imageMap[Visual.Property.BorderlineOffset] = new PropertyValue(backgroundExtraData.BorderlineOffset);
-                    var temp = new PropertyValue(imageMap);
-                    Tizen.NUI.Object.SetProperty(SwigCPtr, ImageView.Property.IMAGE, temp);
-                    temp.Dispose();
-                }
-                imageMap.Dispose();
-                imageValue.Dispose();
-                borderlineColor.Dispose();
-            }
 
-            UpdateImage(0, null);
+            // Update borderline properties to image by ActionUpdateProperty
+            Interop.View.InternalUpdateVisualPropertyFloat(this.SwigCPtr, ImageView.Property.IMAGE, Visual.Property.BorderlineWidth, backgroundExtraData.BorderlineWidth);
+            Interop.View.InternalUpdateVisualPropertyVector4(this.SwigCPtr, ImageView.Property.IMAGE, Visual.Property.BorderlineColor, Vector4.getCPtr(backgroundExtraData.BorderlineColor ?? Color.Black));
+            Interop.View.InternalUpdateVisualPropertyFloat(this.SwigCPtr, ImageView.Property.IMAGE, Visual.Property.BorderlineOffset, backgroundExtraData.BorderlineOffset);
         }
 
         internal ResourceLoadingStatusType GetResourceStatus()
@@ -1132,6 +1383,8 @@ namespace Tizen.NUI.BaseComponents
                 return;
             }
 
+            internalPixelArea?.Dispose();
+
             if (type == DisposeTypes.Explicit)
             {
                 //Called by User
@@ -1141,6 +1394,14 @@ namespace Tizen.NUI.BaseComponents
                 _border = null;
                 borderSelector?.Reset(this);
                 resourceUrlSelector?.Reset(this);
+                imagePropertyUpdatedFlag = false;
+                if (imagePropertyUpdateProcessAttachedFlag)
+                {
+                    ProcessorController.Instance.ProcessorOnceEvent -= UpdateImage;
+                    imagePropertyUpdateProcessAttachedFlag = false;
+                }
+                cachedImagePropertyMap?.Dispose();
+                cachedImagePropertyMap = null;
             }
 
             base.Dispose(type);
@@ -1156,6 +1417,11 @@ namespace Tizen.NUI.BaseComponents
         // Callback for View ResourceReady signal
         private void OnResourceReady(IntPtr data)
         {
+            if (!CheckResourceReady())
+            {
+                return;
+            }
+
             ResourceReadyEventArgs e = new ResourceReadyEventArgs();
             if (data != null)
             {
@@ -1170,14 +1436,27 @@ namespace Tizen.NUI.BaseComponents
 
         private void SetResourceUrl(string value)
         {
-            value = (value == null ? "" : value);
-            if (value.StartsWith("*Resource*"))
+            if (_resourceUrl != ConvertResourceUrl(ref value))
             {
-                string resource = Tizen.Applications.Application.Current.DirectoryInfo.Resource;
-                value = value.Replace("*Resource*", resource);
+                _resourceUrl = value;
+                if (string.IsNullOrEmpty(_resourceUrl))
+                {
+                    // Special case. If we set ResourceUrl as empty, Unregist visual.
+                    RemoveImage();
+                }
+                else
+                {
+                    using (PropertyValue setValue = new PropertyValue(value))
+                    {
+                        UpdateImage(ImageVisualProperty.URL, setValue);
+                    }
+                    // Special case. If we set GeneratedUrl, or FastTrackUploading, Create ImageVisual synchronously.
+                    if (value.StartsWith("dali://") || value.StartsWith("enbuf://") || _fastTrackUploading)
+                    {
+                        UpdateImage();
+                    }
+                }
             }
-            _resourceUrl = value;
-            UpdateImage(ImageVisualProperty.URL, new PropertyValue(value));
         }
 
         private void SetBorder(Rectangle value)
@@ -1186,81 +1465,159 @@ namespace Tizen.NUI.BaseComponents
             {
                 return;
             }
-            _border = new Rectangle(value);
-            UpdateImage(NpatchImageVisualProperty.Border, new PropertyValue(_border));
+            if (_border != value)
+            {
+                _border = new Rectangle(value);
+                UpdateImage(NpatchImageVisualProperty.Border, new PropertyValue(_border));
+            }
         }
 
-        private void UpdateImageMap(PropertyMap fromMap)
+        /// <summary>
+        /// Unregist image visual directly. After this operation, we cannot get any properties from Image property.
+        /// </summary>
+        private void RemoveImage()
         {
-            PropertyMap imageMap = new PropertyMap();
+            // If previous resourceUrl was already empty, we don't need to do anything. just ignore.
+            // Unregist and detach process only if previous resourceUrl was not empty
+            string currentResourceUrl = "";
+            PropertyValue currentResourceUrlValue = GetCachedImageVisualProperty(ImageVisualProperty.URL);
+            if ((currentResourceUrlValue?.Get(out currentResourceUrl) ?? false) && !string.IsNullOrEmpty(currentResourceUrl))
+            {
+                PropertyValue emptyValue = new PropertyValue();
 
-            PropertyValue image = Tizen.NUI.Object.GetProperty(SwigCPtr, ImageView.Property.IMAGE);
-            image?.Get(imageMap);
-            imageMap?.Merge(fromMap);
-            PropertyValue setValue = new PropertyValue(imageMap);
-            SetProperty(ImageView.Property.IMAGE, setValue);
+                // Remove current registed Image.
+                SetProperty(ImageView.Property.IMAGE, emptyValue);
 
-            imageMap?.Dispose();
-            image?.Dispose();
-            setValue?.Dispose();
+                // Image visual is not exist anymore. We should ignore lazy UpdateImage
+                imagePropertyUpdatedFlag = false;
+                if (imagePropertyUpdateProcessAttachedFlag)
+                {
+                    ProcessorController.Instance.ProcessorOnceEvent -= UpdateImage;
+                    imagePropertyUpdateProcessAttachedFlag = false;
+                }
+                // Update resourceUrl as empty value
+                cachedImagePropertyMap[ImageVisualProperty.URL] = emptyValue;
+
+                emptyValue?.Dispose();
+            }
+            currentResourceUrlValue?.Dispose();
         }
 
-        private void UpdateImage(int key, PropertyValue value)
+        /// <summary>
+        /// Lazy call to UpdateImage.
+        /// Collect Properties need to be update, and set properties that starts the Processing.
+        ///
+        /// If you want to update cachedImagePropertyMap, but don't want to request new visual creation, make requiredVisualCreation value as false.
+        /// (Example : if we change SynchronousLoading property from 'true' to 'false', or if we call this function during UpdateImage)
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        protected virtual void UpdateImage(int key, PropertyValue value, bool requiredVisualCreation = true)
         {
-            PropertyMap imageMap = new PropertyMap();
-
-            if (_alphaMaskUrl != null)
+            // Update image property map value as inputed value.
+            if (key != 0)
             {
-                PropertyValue alphaMaskUrl = new PropertyValue(_alphaMaskUrl);
-                imageMap?.Insert(ImageVisualProperty.AlphaMaskURL, alphaMaskUrl);
-                alphaMaskUrl?.Dispose();
-            }
+                if (!HasBody())
+                {
+                    // Throw exception if ImageView is disposed.
+                    throw new global::System.InvalidOperationException("[NUI][ImageVIew] Someone try to change disposed ImageView's property.\n");
+                }
 
-            if (string.IsNullOrEmpty(_resourceUrl))
-            {
-                PropertyValue resourceUrl = new PropertyValue(_resourceUrl);
-                imageMap?.Insert(ImageVisualProperty.URL, resourceUrl);
-                PropertyValue setValue = new PropertyValue(imageMap);
-                SetProperty(ImageView.Property.IMAGE, setValue);
-                resourceUrl?.Dispose();
-                setValue?.Dispose();
-                return;
-            }
+                if (cachedImagePropertyMap == null)
+                {
+                    cachedImagePropertyMap = new PropertyMap();
+                }
 
-            if (_border == null)
-            {
-                PropertyValue image = new PropertyValue((int)Visual.Type.Image);
-                imageMap?.Insert(Visual.Property.Type, image);
-                image?.Dispose();
+                // To optimization, we don't check URL duplicate case. We already checked before.
+                if (key != ImageVisualProperty.URL)
+                {
+                    using (PropertyValue oldValue = GetCachedImageVisualProperty(key))
+                    {
+                        if (oldValue != null && oldValue.EqualTo(value))
+                        {
+                            // Ignore UpdateImage query when we try to update equality value.
+                            return;
+                        }
+                    }
+                }
+                imagePropertyUpdatedFlag = true;
+                cachedImagePropertyMap[key] = value;
+
+                // Lazy update only if visual creation required, and _resourceUrl is not empty, and ProcessAttachedFlag is false.
+                if (requiredVisualCreation && !string.IsNullOrEmpty(_resourceUrl) && !imagePropertyUpdateProcessAttachedFlag)
+                {
+                    imagePropertyUpdateProcessAttachedFlag = true;
+                    ProcessorController.Instance.ProcessorOnceEvent += UpdateImage;
+                    // Call process hardly.
+                    ProcessorController.Instance.Awake();
+                }
             }
-            else
+        }
+
+        /// <summary>
+        /// Callback function to Lazy UpdateImage.
+        /// </summary>
+        private void UpdateImage(object source, EventArgs e)
+        {
+            // Note : To allow event attachment during UpdateImage, let we make flag as false before call UpdateImage().
+            imagePropertyUpdateProcessAttachedFlag = false;
+            UpdateImage();
+        }
+
+        /// <summary>
+        /// Update image-relative properties synchronously.
+        /// After call this API, All image properties updated.
+        /// </summary>
+        /// <remarks>
+        /// Current version ImageView property update asynchronously.
+        /// If you want to guarantee that ImageView property setuped,
+        /// Please call this ImageView.UpdateImage() API.
+        /// </remarks>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        protected virtual void UpdateImage()
+        {
+            if (!imagePropertyUpdatedFlag) return;
+
+            imagePropertyUpdatedFlag = false;
+
+            if (cachedImagePropertyMap == null)
             {
-                PropertyValue nPatch = new PropertyValue((int)Visual.Type.NPatch);
-                imageMap?.Insert(Visual.Property.Type, nPatch);
-                nPatch?.Dispose();
-                PropertyValue border = new PropertyValue(_border);
-                imageMap?.Insert(NpatchImageVisualProperty.Border, border);
-                border?.Dispose();
+                cachedImagePropertyMap = new PropertyMap();
             }
 
-            if(key != Visual.Property.VisualFittingMode && _fittingMode != VisualFittingModeType.Fill)
+            // Checkup the cached visual type is AnimatedImage.
+            // It is trick to know that this code is running on AnimatedImageView.UpdateImage() with resourceURLs or not.
+            int visualType = (int)Visual.Type.Invalid;
+            if (!((GetCachedImageVisualProperty(Visual.Property.Type)?.Get(out visualType) ?? false) && (visualType == (int)Visual.Type.AnimatedImage)))
             {
-                PropertyValue fittingMode = new PropertyValue((int)_fittingMode);
-                imageMap?.Insert(Visual.Property.VisualFittingMode, fittingMode);
-                fittingMode?.Dispose();
+                // If ResourceUrl is not setuped, don't set property. fast return.
+                if (string.IsNullOrEmpty(_resourceUrl))
+                {
+                    return;
+                }
+                if (_border == null)
+                {
+                    PropertyValue image = new PropertyValue((int)Visual.Type.Image);
+                    cachedImagePropertyMap[Visual.Property.Type] = image;
+                    image?.Dispose();
+                }
+                else
+                {
+                    PropertyValue nPatch = new PropertyValue((int)Visual.Type.NPatch);
+                    cachedImagePropertyMap[Visual.Property.Type] = nPatch;
+                    nPatch?.Dispose();
+                    PropertyValue border = new PropertyValue(_border);
+                    cachedImagePropertyMap[NpatchImageVisualProperty.Border] = border;
+                    border?.Dispose();
+                }
             }
 
-            PropertyValue synchronousLoading = new PropertyValue(_synchronousLoading);
-            imageMap?.Insert(NpatchImageVisualProperty.SynchronousLoading, synchronousLoading);
-            synchronousLoading?.Dispose();
-
             if (backgroundExtraData != null && backgroundExtraData.CornerRadius != null)
             {
                 using (var cornerRadius = new PropertyValue(backgroundExtraData.CornerRadius))
                 using (var cornerRadiusPolicy = new PropertyValue((int)backgroundExtraData.CornerRadiusPolicy))
                 {
-                    imageMap.Insert(Visual.Property.CornerRadius, cornerRadius);
-                    imageMap.Insert(Visual.Property.CornerRadiusPolicy, new PropertyValue((int)(backgroundExtraData.CornerRadiusPolicy)));
+                    cachedImagePropertyMap[Visual.Property.CornerRadius] = cornerRadius;
+                    cachedImagePropertyMap[Visual.Property.CornerRadiusPolicy] = new PropertyValue((int)(backgroundExtraData.CornerRadiusPolicy));
                 }
             }
 
@@ -1270,24 +1627,20 @@ namespace Tizen.NUI.BaseComponents
                 using (var borderlineColor = new PropertyValue(backgroundExtraData.BorderlineColor))
                 using (var borderlineOffset = new PropertyValue(backgroundExtraData.BorderlineOffset))
                 {
-                    imageMap.Insert(Visual.Property.BorderlineWidth, borderlineWidth);
-                    imageMap.Insert(Visual.Property.BorderlineColor, borderlineColor);
-                    imageMap.Insert(Visual.Property.BorderlineOffset, borderlineOffset);
+                    cachedImagePropertyMap[Visual.Property.BorderlineWidth] = borderlineWidth;
+                    cachedImagePropertyMap[Visual.Property.BorderlineColor] = borderlineColor;
+                    cachedImagePropertyMap[Visual.Property.BorderlineOffset] = borderlineOffset;
                 }
             }
 
-            if (value != null)
-            {
-                imageMap?.Insert(key, value);
-            }
-
             // Do Fitting Buffer when desired dimension is set
+            // TODO : Couldn't we do this job in dali-engine side.
             if (_desired_width != -1 && _desired_height != -1)
             {
                 if (_resourceUrl != null)
                 {
                     Size2D imageSize = ImageLoader.GetOriginalImageSize(_resourceUrl, true);
-                    if( imageSize.Height > 0 && imageSize.Width > 0 && _desired_width > 0  && _desired_height > 0 )
+                    if (imageSize.Height > 0 && imageSize.Width > 0 && _desired_width > 0 && _desired_height > 0)
                     {
                         int adjustedDesiredWidth, adjustedDesiredHeight;
                         float aspectOfDesiredSize = (float)_desired_height / (float)_desired_width;
@@ -1304,32 +1657,131 @@ namespace Tizen.NUI.BaseComponents
                         }
 
                         PropertyValue returnWidth = new PropertyValue(adjustedDesiredWidth);
-                        imageMap?.Insert(ImageVisualProperty.DesiredWidth, returnWidth);
+                        cachedImagePropertyMap[ImageVisualProperty.DesiredWidth] = returnWidth;
                         returnWidth?.Dispose();
                         PropertyValue returnHeight = new PropertyValue(adjustedDesiredHeight);
-                        imageMap?.Insert(ImageVisualProperty.DesiredHeight, returnHeight);
+                        cachedImagePropertyMap[ImageVisualProperty.DesiredHeight] = returnHeight;
                         returnHeight?.Dispose();
                         PropertyValue scaleToFit = new PropertyValue((int)FittingModeType.ScaleToFill);
-                        imageMap?.Insert(ImageVisualProperty.FittingMode, scaleToFit);
+                        cachedImagePropertyMap[ImageVisualProperty.FittingMode] = scaleToFit;
                         scaleToFit?.Dispose();
                     }
-                    else
-                    {
-                        Tizen.Log.Fatal("NUI", "[ERROR] Can't use DesiredSize when ImageLoading is failed.");
-                    }
                     imageSize?.Dispose();
                 }
             }
 
-            UpdateImageMap(imageMap);
+            UpdateImageMap();
+        }
+
+        /// <summary>
+        /// Merge our collected properties, and set IMAGE property internally.
+        /// </summary>
+        private void UpdateImageMap()
+        {
+            // Note : We can't use ImageView.Image property here. Because That property call UpdateImage internally.
+            using (PropertyMap imageMap = new PropertyMap())
+            {
+                using (PropertyValue returnValue = Tizen.NUI.Object.GetProperty(SwigCPtr, ImageView.Property.IMAGE))
+                {
+                    returnValue?.Get(imageMap);
+                }
+                if (cachedImagePropertyMap != null)
+                {
+                    imageMap?.Merge(cachedImagePropertyMap);
+                }
+                using (PropertyValue setValue = new PropertyValue(imageMap))
+                {
+                    SetProperty(ImageView.Property.IMAGE, setValue);
+                }
+
+                // Update cached image property.
+                MergeCachedImageVisualProperty(imageMap);
+            }
+        }
+
+        /// <summary>
+        /// Get image visual property by key.
+        /// If we found value in local Cached result, return that.
+        /// Else, get synced native map and return that.
+        /// If there is no matched value, return null.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        protected virtual PropertyValue GetImageVisualProperty(int key)
+        {
+            PropertyValue ret = GetCachedImageVisualProperty(key);
+            if (ret == null)
+            {
+                // If we cannot find result form cached map, Get value from native engine.
+                ret = Image?.Find(key);
+            }
+            return ret;
+        }
+
+        /// <summary>
+        /// Get image visual property from NUI cached image map by key.
+        /// If there is no matched value, return null.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        protected virtual PropertyValue GetCachedImageVisualProperty(int key)
+        {
+            return cachedImagePropertyMap?.Find(key);
+        }
+
+        /// <summary>
+        /// Update NUI cached image visual property map by inputed property map.
+        /// </summary>
+        /// <remarks>
+        /// For performance issue, we will collect only "cachedImagePropertyKeyList" hold.
+        /// </remarks>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        protected virtual void MergeCachedImageVisualProperty(PropertyMap map)
+        {
+            if (map == null) return;
+            if (cachedImagePropertyMap == null)
+            {
+                cachedImagePropertyMap = new PropertyMap();
+            }
+            foreach (var key in cachedImagePropertyKeyList)
+            {
+                PropertyValue value = map.Find(key);
+                if (value != null)
+                {
+                    // Update-or-Insert new value
+                    cachedImagePropertyMap[key] = value;
+                    if (key == ImageVisualProperty.URL)
+                    {
+                        // Special case. If key is Url, update _resourceUrl here.
+                        value.Get(out _resourceUrl);
+                    }
+                }
+            }
+        }
 
-            imageMap?.Dispose();
-            imageMap = null;
+        /// <summary>
+        /// GetNaturalSize() should be guaranteed that ResourceUrl property setuped.
+        /// So before get base.GetNaturalSize(), we should synchronous image properties
+        /// </summary>
+        internal override Vector3 GetNaturalSize()
+        {
+            // Sync as current properties
+            UpdateImage();
+            return base.GetNaturalSize();
         }
 
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        protected override bool CheckResourceReady()
+        {
+            // If we have some properties to be updated, this signal is old thing.
+            // We need to ignore current signal, and wait next.
+            return !(imagePropertyUpdateProcessAttachedFlag && imagePropertyUpdatedFlag);
+        }
 
         private void OnResourceLoaded(IntPtr view)
         {
+            if (!CheckResourceReady())
+            {
+                return;
+            }
             ResourceLoadedEventArgs e = new ResourceLoadedEventArgs();
             e.Status = (ResourceLoadingStatusType)Interop.View.GetVisualResourceStatus(this.SwigCPtr, Property.IMAGE);
 
@@ -1385,10 +1837,8 @@ namespace Tizen.NUI.BaseComponents
             internal static readonly int IMAGE = Interop.ImageView.ImageGet();
             internal static readonly int PreMultipliedAlpha = Interop.ImageView.PreMultipliedAlphaGet();
             internal static readonly int PixelArea = Interop.ImageView.PixelAreaGet();
-            internal static readonly int ActionReload = Interop.ImageView.ImageVisualActionReloadGet();
-            internal static readonly int ActionPlay = Interop.ImageView.ImageVisualActionPlayGet();
-            internal static readonly int ActionPause = Interop.ImageView.ImageVisualActionPauseGet();
-            internal static readonly int ActionStop = Interop.ImageView.ImageVisualActionStopGet();
+            internal static readonly int PlaceHolderUrl = Interop.ImageView.PlaceHolderImageGet();
+            internal static readonly int TransitionEffect = Interop.ImageView.TransitionEffectGet();
         }
 
         private enum ImageType