摘要:一需求场景最近闲来无事,提出了一个要求,研究相关代码并完成一个关于编辑图片功能的性能优化,该功能的主要界面展示如下通过了几分钟的短暂试用,发现就是一个简单的裁剪并保存用户选择并上传的图片作为用户头像的功能。
一、需求场景:
最近闲来无事,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结构如下:
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个字不断在努力。而前端的一切的方案和手段,最终目的都是为了提升用户体验。
毕竟,我们做出的是最接近用户的产品。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/1518.html
摘要:那想要优化这一点,唯一的方法就是利用内容高度来撑开而非,这个方案跟消除浮动所用的方案非常相似给容器添加一个子元素伪元素,并把子元素伪元素的设为,使其实际高度相当于容器的宽度,如此一来,便能把容器的高度撑至与宽度一致了。 一个基础却又容易混淆的css知识点 本文依赖于一个基础却又容易混淆的css知识点:当margin/padding取形式为百分比的值时,无论是left/right,还是t...
摘要:并且,一些伪元素可以使开发者获取到不存在于源文档中的内容比如常见的还可以为伪元素定制样式。。中新增加的伪元素必须用伪类使用一个冒号例如。就本文而言,我们将把我们探讨的范围限制在和这两个伪元素的巧用上。 作为一门前端er,你肯定熟知 a:hover a:visited.....我还记得在小本本上记着诀窍:love 与 hate 纠缠不休,大家都懂的吧。。。。 伪类和...
阅读 717·2023-04-25 19:43
阅读 3914·2021-11-30 14:52
阅读 3790·2021-11-30 14:52
阅读 3857·2021-11-29 11:00
阅读 3787·2021-11-29 11:00
阅读 3874·2021-11-29 11:00
阅读 3561·2021-11-29 11:00
阅读 6117·2021-11-29 11:00