巧用css的border属性完成对图片编辑功能的性能优化
一、需求場景:
最近閑來無事,boss提出了一個要求,研究相關代碼并完成一個關于編輯圖片功能的性能優化,該功能的主要界面展示如下:
通過了幾分鐘的短暫試用,發現就是一個簡單的裁剪并保存用戶選擇并上傳的圖片作為用戶頭像的功能。
主要功能點如下:
初步一看,貌似沒有什么值得優化的地方,通過與boss深入了解后知曉,在選擇容量較大(超過10MB)的圖片時,瀏覽器響應速度會變得異常緩慢,具體表現是
拖動中間選擇區域的位置或者大小時,大約3-4秒才響應一次,嚴重影響了使用者的用戶體驗,作為一名專(zhuang)業(bi)的前端人員來說,是完全不能容忍的。
二、性能分析:
作為一名專(zhuang)業(bi)的前端人員來說,遇到問題的首要肯定是先進行性能分析。一般來說瀏覽器的性能問題無非就是CPU和內存消耗占用。
通過對比查看性能管理器中的chrome內存占用后發現,選擇大容量圖片前,chrome的內存占用是883MB,而選擇大容量圖片后,chrome的內存占用達到了2232MB,
內存占用暴漲將近了200%!這就是出現性能問題的所在。事不宜遲,開始著手研究并解決問題。
三、查看代碼:
通過查看代碼,發現實現該功能的程序猿(也可能是媛)是通過在背景渲染一張完整的image,前景的圖片選擇區域設置一個透明度為0.3的蒙版(圖中的黑色背景區域),
然后在選擇區域(圖中綠色方框)的背景區域再渲染一張image,再通過動態設置background-position的top、left和size來達到預覽并獲取選中區域圖片的目的。
html結構如下:
<div class="pic_area" style="display:block" ng-show="roomPhotoEdit.file"><div class="pic_editor"><!-- upload image --><span class="pic" id="editing_pic"><!-- 渲染的第一張圖片 -->
<img onload="angular.element(this).scope().roomPhotoEdit.initCrop()" ng-src="{{roomPhotoEdit.file}}" alt="">
</span>
<!-- 黑色蒙版背景區域 --><span class="crop_dimmed"></span>
<!-- 圖中綠色方框區域 --><span class="crop_box" ng-style="roomPhotoEdit.cropLayout" style="top:75px;left:75px">
<!-- 渲染的第二張圖片 --><span class="drag_area" ng-style="roomPhotoEdit.edited"></span><button class="drag_handle handle_lt" data-type="lt"></button><button class="drag_handle handle_rt" data-type="rt"></button><button class="drag_handle handle_lb" data-type="lb"></button><button class="drag_handle handle_rb" data-type="rb"></button></span></div>
</div>
javascript代碼如下(基于AngularJS):
scope.roomPhotoEdit.edited = {'background-image': 'url(' currentImage.attr('src') ')', // 這里多渲染了一張圖片'background-position': backgroundPositionOption[imageSizeType], // 動態設置top和left'background-size': backgroundSizeOption[imageSizeType] // 設置預覽區域的尺寸 }通過代碼可以很明顯的看到通過在class為drag_area的區域額外渲染一張背景圖片并動態修改background-position和background-size來達到預覽選擇區域圖片的目的。
由于額外渲染了一張圖片,如果用戶選擇的容量超大的圖片,則會導致瀏覽器內存占用暴漲,如果能只渲染一張圖片,應該就能極大減少內存占用,可以從此入手。
四、嘗試優化:
首先就是去除拖放區域中額外渲染的背景圖片。
可以從上圖中看到去除了背景圖片之后,拖放區域被黑色蒙版遮蓋住了,沒有預覽的效果了。
通過度娘之后得知可以通過動態設置黑色蒙版區域的border-width、border-style、border-color來達到顯示拖放區域的預覽圖片效果。
話不多說,先來直接看看效果。
再來看之前drag_area區域的html結構,可以發現,之前的背景圖片等樣式全部被去除了。
?取而代之的之前的黑色蒙版區域crop_dimmed的樣式,可以看到設置了border-width、border-style和border-color,來達到顯示中間預覽區域的效果。
最后要做的只是,在預覽區域的拖放事件中動態去設置drop_dimmed區域的border-width屬性即可。
該屬性主要的計算規則如下(其中layoutTop為綠色方框區域的top屬性,layoutLeft為綠色方框區域的left屬性,containerWidth為外部容器的寬度,containerHeight為外部容器的高度,position.size為綠色方框區域的寬高,在這里拖放區域只能等比拖放,所以是個正方形,寬高一致):
border-top-width: layoutTop "px" border-right-width: containerWidth - layoutLeft - position.size "px" border-bottom-width: containerHeight - layoutTop - position.size "px" border-left-width: layoutLeft "px"五、驗收
代碼改完了最后一步當然是驗收了,通過查看修改后的內存占用發現,即使選擇了大容量的圖片之后,內存占用也穩定在了800MB左右,而且操作比之前流暢多了。
搞定,收工!
六、總結:
從最初的純粹為了圖片裁剪區域的預覽,而額外渲染了一張圖片開始,到最后的去除額外圖片渲染,而采用border-width的方案來達到裁剪區域預覽的目的。
前端er們做的事情無非為了用戶體驗這4個字不斷在努力。而前端的一切的方案和手段,最終目的都是為了提升用戶體驗。
畢竟,我們做出的是最接近用戶的產品。
更多專業前端知識,請上 【猿2048】www.mk2048.com
總結
以上是生活随笔為你收集整理的巧用css的border属性完成对图片编辑功能的性能优化的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: CSS-定位
- 下一篇: 开放才能进步!Angular和Wijmo