[NUI] Update ImageView properties lazy
authorEunki, Hong <eunkiki.hong@samsung.com>
Thu, 30 Dec 2021 08:25:22 +0000 (17:25 +0900)
committerSeoyeon2Kim <34738918+Seoyeon2Kim@users.noreply.github.com>
Wed, 12 Jan 2022 08:40:18 +0000 (17:40 +0900)
Current Implementation create/destroy visual whenever properties changed.
This patch hold visual-sensitive properties and
create/destroy visual before next EventProcess called.

Signed-off-by: Eunki, Hong <eunkiki.hong@samsung.com>
src/Tizen.NUI/src/internal/Common/ProcessorController.cs
src/Tizen.NUI/src/internal/Interop/Interop.ProcessorController.cs
src/Tizen.NUI/src/public/BaseComponents/ImageView.cs
src/Tizen.NUI/src/public/BaseComponents/ImageViewBindableProperty.cs

index 6b0ed3c..7815a9f 100755 (executable)
@@ -88,5 +88,14 @@ namespace Tizen.NUI
 
             base.Dispose(type);
         }
+
+        /// <summary>
+        /// Awake ProcessorController. It will call ProcessController.processorCallback hardly
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public void Awake()
+        {
+            Interop.ProcessorController.Awake(SwigCPtr);
+        }
     } // class ProcessorController
 } // namespace Tizen.NUI
index 84b2bbd..b33b532 100755 (executable)
@@ -33,6 +33,9 @@ namespace Tizen.NUI
 
             [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_ProcessorController_RemoveCallback")]
             public static extern void RemoveCallback(global::System.Runtime.InteropServices.HandleRef processorController, Tizen.NUI.ProcessorController.ProcessorEventHandler processorCallback);
+
+            [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_ProcessorController_Awake")]
+            public static extern void Awake(global::System.Runtime.InteropServices.HandleRef processorController);
         }
     }
 }
index 406c6af..1c9e59e 100755 (executable)
@@ -36,13 +36,14 @@ namespace Tizen.NUI.BaseComponents
         private EventHandler<ResourceLoadedEventArgs> _resourceLoadedEventHandler;
         private _resourceLoadedCallbackType _resourceLoadedCallback;
 
+        // Collection of image-sensitive properties.
+        private bool _imagePropertyUpdatedFlag = false;
+        private bool _imagePropertyUpdateProcessAttachedFlag = false;
+        private PropertyMap _imagePropertyMap;
         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 TriggerableSelector<string> resourceUrlSelector;
         private TriggerableSelector<Rectangle> borderSelector;
 
@@ -259,11 +260,10 @@ namespace Tizen.NUI.BaseComponents
             {
                 if (_border == null)
                 {
-                    PropertyMap returnValue = new PropertyMap();
-                    PropertyValue image = GetProperty(ImageView.Property.IMAGE);
-                    image?.Get(returnValue);
-                    image?.Dispose();
-                    return returnValue;
+                    // Sync as current properties.
+                    UpdateImage();
+
+                    return _imagePropertyMap == null ? new PropertyMap() : new PropertyMap(_imagePropertyMap);
                 }
                 else
                 {
@@ -276,6 +276,14 @@ 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;
+                    _imagePropertyMap?.Dispose();
+                    _imagePropertyMap = null;
+                    if(value != null)
+                    {
+                        _imagePropertyMap = new PropertyMap(value);
+                    }
                     NotifyPropertyChanged();
                     setValue?.Dispose();
                 }
@@ -615,29 +623,16 @@ 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 = _imagePropertyMap?.Find(ImageVisualProperty.AlphaMaskURL);
+                maskUrl?.Get(out ret);
                 maskUrl?.Dispose();
 
                 return ret;
             }
             set
             {
-                if (value == null)
-                {
-                    value = "";
-                }
-
-                _alphaMaskUrl = value;
-
-                PropertyValue setValue = new PropertyValue(value);
+                PropertyValue setValue = new PropertyValue(value ?? "");
                 UpdateImage(ImageVisualProperty.AlphaMaskURL, setValue);
                 setValue?.Dispose();
             }
@@ -665,15 +660,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 = _imagePropertyMap?.Find(ImageVisualProperty.CropToMask);
+                cropToMask?.Get(out ret);
+                cropToMask?.Dispose();
 
                 return ret;
             }
@@ -681,7 +671,7 @@ namespace Tizen.NUI.BaseComponents
             {
                 PropertyValue setValue = new PropertyValue(value);
                 UpdateImage(ImageVisualProperty.CropToMask, setValue);
-                setValue.Dispose();
+                setValue?.Dispose();
             }
         }
 
@@ -783,16 +773,10 @@ 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 = _imagePropertyMap?.Find(Visual.Property.VisualFittingMode);
+                fittingMode?.Get(out ret);
                 fittingMode?.Dispose();
 
                 return ConvertVisualFittingModetoFittingMode((VisualFittingModeType)ret);
@@ -801,11 +785,7 @@ namespace Tizen.NUI.BaseComponents
             {
                 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();
             }
         }
@@ -836,15 +816,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 = _imagePropertyMap?.Find(ImageVisualProperty.DesiredWidth);
+                desirewidth?.Get(out _desired_width);
+                desirewidth?.Dispose();
 
                 return _desired_width;
             }
@@ -853,7 +832,9 @@ namespace Tizen.NUI.BaseComponents
                 if (_desired_width != value)
                 {
                     _desired_width = value;
-                    UpdateImage(0, null);
+                    PropertyValue setValue = new PropertyValue(value);
+                    UpdateImage(ImageVisualProperty.DesiredWidth, setValue);
+                    setValue?.Dispose();
                 }
             }
         }
@@ -882,14 +863,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 = _imagePropertyMap?.Find(ImageVisualProperty.DesiredHeight);
                 desireheight?.Get(out _desired_height);
-
-                imageMap?.Dispose();
-                image?.Dispose();
                 desireheight?.Dispose();
 
                 return _desired_height;
@@ -899,7 +879,9 @@ namespace Tizen.NUI.BaseComponents
                 if (_desired_height != value)
                 {
                     _desired_height = value;
-                    UpdateImage(0, null);
+                    PropertyValue setValue = new PropertyValue(value);
+                    UpdateImage(ImageVisualProperty.DesiredHeight, setValue);
+                    setValue?.Dispose();
                 }
             }
         }
@@ -927,14 +909,9 @@ namespace Tizen.NUI.BaseComponents
             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 = _imagePropertyMap?.Find(ImageVisualProperty.ReleasePolicy);
+                releasePoli?.Get(out ret);
                 releasePoli?.Dispose();
 
                 return (ReleasePolicyType)ret;
@@ -974,15 +951,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 = _imagePropertyMap?.Find(ImageVisualProperty.WrapModeU);
+                wrapModeU?.Get(out ret);
+                wrapModeU?.Dispose();
 
                 return (WrapModeType)ret;
             }
@@ -1022,14 +994,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 = _imagePropertyMap?.Find(ImageVisualProperty.WrapModeV);
+                wrapModeV?.Get(out ret);
                 wrapModeV?.Dispose();
 
                 return (WrapModeType)ret;
@@ -1190,6 +1157,14 @@ namespace Tizen.NUI.BaseComponents
                 _border = null;
                 borderSelector?.Reset(this);
                 resourceUrlSelector?.Reset(this);
+                _imagePropertyUpdatedFlag = false;
+                if (_imagePropertyUpdateProcessAttachedFlag)
+                {
+                    ProcessorController.Instance.ProcessorOnceEvent -= UpdateImage;
+                    _imagePropertyUpdateProcessAttachedFlag = false;
+                }
+                _imagePropertyMap?.Dispose();
+                _imagePropertyMap = null;
             }
 
             base.Dispose(type);
@@ -1225,8 +1200,11 @@ namespace Tizen.NUI.BaseComponents
                 string resource = Tizen.Applications.Application.Current.DirectoryInfo.Resource;
                 value = value.Replace("*Resource*", resource);
             }
-            _resourceUrl = value;
-            UpdateImage(ImageVisualProperty.URL, new PropertyValue(value));
+            if(_resourceUrl != value)
+            {
+                _resourceUrl = value;
+                UpdateImage(ImageVisualProperty.URL, new PropertyValue(value));
+            }
         }
 
         private void SetBorder(Rectangle value)
@@ -1235,81 +1213,116 @@ 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>
+        /// Lazy call to UpdateImage.
+        /// Collect Properties need to be update, and set properties that starts the Processing.
+        /// </summary>
+        private void UpdateImage(int key, PropertyValue value)
         {
-            PropertyMap imageMap = new PropertyMap();
+            // If we set ResourceUrl as empty, Unregist visual.
+            if (key == ImageVisualProperty.URL && string.IsNullOrEmpty(_resourceUrl))
+            {
+                // If previous resourceUrl was already empty, we don't need to do anything. just ignore.
+                // Unregist and dettach Process only if previous resourceUrl was not empty
+                string currentResourceUrl = "";
+                PropertyValue currentResourceUrlValue = _imagePropertyMap?.Find(ImageVisualProperty.URL);
+                if((currentResourceUrlValue?.Get(out currentResourceUrl) ?? false) && string.IsNullOrEmpty(currentResourceUrl))
+                {
+                    PropertyValue resourceUrl = new PropertyValue(_resourceUrl);
+                    PropertyMap imageMap = new PropertyMap();
+                    imageMap.Insert(ImageVisualProperty.URL, resourceUrl);
+                    PropertyValue setValue = new PropertyValue(imageMap);
+                    SetProperty(ImageView.Property.IMAGE, setValue);
 
-            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);
+                    // Image visual is not exist anymore. We should ignore lazy UpdateImage
+                    _imagePropertyUpdatedFlag = false;
+                    if(_imagePropertyUpdateProcessAttachedFlag)
+                    {
+                        ProcessorController.Instance.ProcessorOnceEvent -= UpdateImage;
+                        _imagePropertyUpdateProcessAttachedFlag = false;
+                    }
+                    // Update resourceUrl as null
+                    _imagePropertyMap[ImageVisualProperty.URL] = resourceUrl;
 
-            imageMap?.Dispose();
-            image?.Dispose();
-            setValue?.Dispose();
+                    resourceUrl?.Dispose();
+                    setValue?.Dispose();
+                    imageMap?.Dispose();
+                }
+                return;
+            }
+
+            // Update image property map value as inputed value.
+            if (key != 0)
+            {
+                if (_imagePropertyMap == null)
+                {
+                    _imagePropertyMap = new PropertyMap();
+                }
+                _imagePropertyUpdatedFlag = true;
+                _imagePropertyMap[key] = value;
+
+                // Lazy update only if _resourceUrl is not empty and ProcessAttachedFlag is false.
+                if (!string.IsNullOrEmpty(_resourceUrl) && !_imagePropertyUpdateProcessAttachedFlag)
+                {
+                    _imagePropertyUpdateProcessAttachedFlag = true;
+                    ProcessorController.Instance.ProcessorOnceEvent += UpdateImage;
+                    // Call process hardly.
+                    ProcessorController.Instance.Awake();
+                }
+            }
         }
 
-        private void UpdateImage(int key, PropertyValue value)
+        /// <summary>
+        /// Callback function to Lazy UpdateImage.
+        /// Or, We can call UpdateImage() function directly if we need.
+        /// </summary>
+        private void UpdateImage(object source, EventArgs e)
         {
-            PropertyMap imageMap = new PropertyMap();
+            UpdateImage();
+            _imagePropertyUpdateProcessAttachedFlag = false;
+        }
 
-            if (_alphaMaskUrl != null)
-            {
-                PropertyValue alphaMaskUrl = new PropertyValue(_alphaMaskUrl);
-                imageMap?.Insert(ImageVisualProperty.AlphaMaskURL, alphaMaskUrl);
-                alphaMaskUrl?.Dispose();
-            }
+        private void UpdateImage()
+        {
+            if(!_imagePropertyUpdatedFlag) return;
 
-            if (string.IsNullOrEmpty(_resourceUrl))
+            _imagePropertyUpdatedFlag = false;
+
+            if(_imagePropertyMap == null)
             {
-                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;
+                _imagePropertyMap = new PropertyMap();
             }
 
             if (_border == null)
             {
                 PropertyValue image = new PropertyValue((int)Visual.Type.Image);
-                imageMap?.Insert(Visual.Property.Type, image);
+                _imagePropertyMap[Visual.Property.Type] = image;
                 image?.Dispose();
             }
             else
             {
                 PropertyValue nPatch = new PropertyValue((int)Visual.Type.NPatch);
-                imageMap?.Insert(Visual.Property.Type, nPatch);
+                _imagePropertyMap[Visual.Property.Type] = nPatch;
                 nPatch?.Dispose();
                 PropertyValue border = new PropertyValue(_border);
-                imageMap?.Insert(NpatchImageVisualProperty.Border, border);
+                _imagePropertyMap[NpatchImageVisualProperty.Border] = border;
                 border?.Dispose();
             }
 
-            if(key != Visual.Property.VisualFittingMode && _fittingMode != VisualFittingModeType.Fill)
-            {
-                PropertyValue fittingMode = new PropertyValue((int)_fittingMode);
-                imageMap?.Insert(Visual.Property.VisualFittingMode, fittingMode);
-                fittingMode?.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)));
+                    _imagePropertyMap[Visual.Property.CornerRadius] = cornerRadius;
+                    _imagePropertyMap[Visual.Property.CornerRadiusPolicy] = new PropertyValue((int)(backgroundExtraData.CornerRadiusPolicy));
                 }
             }
 
@@ -1319,17 +1332,12 @@ 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);
+                    _imagePropertyMap[Visual.Property.BorderlineWidth] = borderlineWidth;
+                    _imagePropertyMap[Visual.Property.BorderlineColor] = borderlineColor;
+                    _imagePropertyMap[Visual.Property.BorderlineOffset] = borderlineOffset;
                 }
             }
 
-            if (value != null)
-            {
-                imageMap?.Insert(key, value);
-            }
-
             // Do Fitting Buffer when desired dimension is set
             if (_desired_width != -1 && _desired_height != -1)
             {
@@ -1353,13 +1361,13 @@ namespace Tizen.NUI.BaseComponents
                         }
 
                         PropertyValue returnWidth = new PropertyValue(adjustedDesiredWidth);
-                        imageMap?.Insert(ImageVisualProperty.DesiredWidth, returnWidth);
+                        _imagePropertyMap[ImageVisualProperty.DesiredWidth] = returnWidth;
                         returnWidth?.Dispose();
                         PropertyValue returnHeight = new PropertyValue(adjustedDesiredHeight);
-                        imageMap?.Insert(ImageVisualProperty.DesiredHeight, returnHeight);
+                        _imagePropertyMap[ImageVisualProperty.DesiredHeight] = returnHeight;
                         returnHeight?.Dispose();
                         PropertyValue scaleToFit = new PropertyValue((int)FittingModeType.ScaleToFill);
-                        imageMap?.Insert(ImageVisualProperty.FittingMode, scaleToFit);
+                        _imagePropertyMap[ImageVisualProperty.FittingMode] = scaleToFit;
                         scaleToFit?.Dispose();
                     }
                     else
@@ -1370,13 +1378,28 @@ namespace Tizen.NUI.BaseComponents
                 }
             }
 
-            UpdateImageMap(imageMap);
+            UpdateImageMap();
+        }
+        private void UpdateImageMap()
+        {
+            PropertyMap imageMap = new PropertyMap();
+
+            PropertyValue image = Tizen.NUI.Object.GetProperty(SwigCPtr, ImageView.Property.IMAGE);
+            image?.Get(imageMap);
+            imageMap.Merge(_imagePropertyMap);
+            PropertyValue setValue = new PropertyValue(imageMap);
+            SetProperty(ImageView.Property.IMAGE, setValue);
+
+            // Sync local PropertyMap
+            // TODO: Do we need to use GetProperty(SwigCPtr, ImageView.Property.IMAGE); here?
+            _imagePropertyMap.Dispose();
+            _imagePropertyMap = new PropertyMap(imageMap);
 
             imageMap?.Dispose();
-            imageMap = null;
+            image?.Dispose();
+            setValue?.Dispose();
         }
 
-
         private void OnResourceLoaded(IntPtr view)
         {
             ResourceLoadedEventArgs e = new ResourceLoadedEventArgs();
index 1578d1b..d6613fa 100755 (executable)
@@ -44,9 +44,8 @@ namespace Tizen.NUI.BaseComponents
             var imageView = (ImageView)bindable;
             string ret = "";
 
-            PropertyMap imageMap = new PropertyMap();
-            Tizen.NUI.Object.GetProperty((HandleRef)imageView.SwigCPtr, ImageView.Property.IMAGE).Get(imageMap);
-            imageMap.Find(ImageVisualProperty.URL)?.Get(out ret);
+            imageView._imagePropertyMap?.Find(ImageVisualProperty.URL)?.Get(out ret);
+
             return ret;
         }));
 
@@ -94,6 +93,14 @@ namespace Tizen.NUI.BaseComponents
                 }
                 if (imageView._border == null)
                 {
+                    // Image properties are changed hardly. We should ignore lazy UpdateImage
+                    imageView._imagePropertyUpdatedFlag = false;
+                    imageView._imagePropertyMap?.Dispose();
+                    imageView._imagePropertyMap = null;
+                    if(map != null)
+                    {
+                        imageView._imagePropertyMap = new PropertyMap(map);
+                    }
                     Tizen.NUI.Object.SetProperty((HandleRef)imageView.SwigCPtr, ImageView.Property.IMAGE, new Tizen.NUI.PropertyValue(map));
                 }
             }
@@ -104,7 +111,14 @@ namespace Tizen.NUI.BaseComponents
             if (imageView._border == null)
             {
                 PropertyMap temp = new PropertyMap();
-                Tizen.NUI.Object.GetProperty((HandleRef)imageView.SwigCPtr, ImageView.Property.IMAGE).Get(temp);
+
+                // Sync as current properties.
+                imageView.UpdateImage();
+                if(imageView._imagePropertyMap != null)
+                {
+                    temp.Merge(imageView._imagePropertyMap);
+                }
+
                 return temp;
             }
             else
@@ -180,6 +194,15 @@ namespace Tizen.NUI.BaseComponents
             var imageView = (ImageView)bindable;
             if (newValue != null)
             {
+                if(oldValue != null)
+                {
+                    bool oldBool = (bool)oldValue;
+                    bool newBool = (bool)newValue;
+                    if(oldBool == newBool)
+                    {
+                        return;
+                    }
+                }
                 imageView.UpdateImage(NpatchImageVisualProperty.BorderOnly, new PropertyValue((bool)newValue));
             }
         },
@@ -187,9 +210,9 @@ namespace Tizen.NUI.BaseComponents
         {
             var imageView = (ImageView)bindable;
             bool ret = false;
-            PropertyMap imageMap = new PropertyMap();
-            Tizen.NUI.Object.GetProperty((HandleRef)imageView.SwigCPtr, ImageView.Property.IMAGE).Get(imageMap);
-            imageMap.Find(ImageVisualProperty.BorderOnly)?.Get(out ret);
+
+            imageView._imagePropertyMap?.Find(NpatchImageVisualProperty.BorderOnly)?.Get(out ret);
+
             return ret;
         }));
 
@@ -200,14 +223,26 @@ namespace Tizen.NUI.BaseComponents
             var imageView = (ImageView)bindable;
             if (newValue != null)
             {
-                imageView._synchronousLoading = (bool)newValue;
-                imageView.UpdateImage(NpatchImageVisualProperty.SynchronousLoading, new PropertyValue((bool)newValue));
+                if(oldValue != null)
+                {
+                    bool oldBool = (bool)oldValue;
+                    bool newBool = (bool)newValue;
+                    if(oldBool == newBool)
+                    {
+                        return;
+                    }
+                }
+                imageView.UpdateImage(ImageVisualProperty.SynchronousLoading, new PropertyValue((bool)newValue));
             }
         },
         defaultValueCreator: (bindable) =>
         {
             var imageView = (ImageView)bindable;
-            return imageView._synchronousLoading;
+            bool ret = false;
+
+            imageView._imagePropertyMap?.Find(ImageVisualProperty.SynchronousLoading)?.Get(out ret);
+
+            return ret;
         });
 
         /// This will be public opened in tizen_7.0 after ACR done. Before ACR, need to be hidden as inhouse API.
@@ -217,14 +252,26 @@ namespace Tizen.NUI.BaseComponents
             var imageView = (ImageView)bindable;
             if (newValue != null)
             {
-                imageView._synchronousLoading = (bool)newValue;
-                imageView.UpdateImage(NpatchImageVisualProperty.SynchronousLoading, new PropertyValue((bool)newValue));
+                if(oldValue != null)
+                {
+                    bool oldBool = (bool)oldValue;
+                    bool newBool = (bool)newValue;
+                    if(oldBool == newBool)
+                    {
+                        return;
+                    }
+                }
+                imageView.UpdateImage(ImageVisualProperty.SynchronousLoading, new PropertyValue((bool)newValue));
             }
         },
         defaultValueCreator: (bindable) =>
         {
             var imageView = (ImageView)bindable;
-            return imageView._synchronousLoading;
+            bool ret = false;
+
+            imageView._imagePropertyMap?.Find(ImageVisualProperty.SynchronousLoading)?.Get(out ret);
+
+            return ret;
         });
 
         /// Intenal used, will never be opened.
@@ -234,6 +281,15 @@ namespace Tizen.NUI.BaseComponents
             var imageView = (ImageView)bindable;
             if (newValue != null)
             {
+                if(oldValue != null)
+                {
+                    bool oldBool = (bool)oldValue;
+                    bool newBool = (bool)newValue;
+                    if(oldBool == newBool)
+                    {
+                        return;
+                    }
+                }
                 imageView.UpdateImage(ImageVisualProperty.OrientationCorrection, new PropertyValue((bool)newValue));
             }
         },
@@ -242,9 +298,8 @@ namespace Tizen.NUI.BaseComponents
             var imageView = (ImageView)bindable;
 
             bool ret = false;
-            PropertyMap imageMap = new PropertyMap();
-            Tizen.NUI.Object.GetProperty((HandleRef)imageView.SwigCPtr, ImageView.Property.IMAGE).Get(imageMap);
-            imageMap?.Find(ImageVisualProperty.OrientationCorrection)?.Get(out ret);
+
+            imageView._imagePropertyMap?.Find(ImageVisualProperty.OrientationCorrection)?.Get(out ret);
 
             return ret;
         }));