一、需求场景:

最近闲来无事,boss提出了一个要求,研究相关代码并完成一个关于编辑图片功能的性能优化,该功能的主要界面展示如下:

通过了几分钟的短暂试用,发现就是一个简单的裁剪并保存用户选择并上传的图片作为用户头像的功能。

主要功能点如下:

  1. 选择图片并上传。
  2. 拖动中间选择区域的位置或者大小选择设置的图片区域。
  3. 点击确定按钮,完成图片设置。

初步一看,貌似没有什么值得优化的地方,通过与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属性完成对图片编辑功能的性能优化相关推荐

  1. 巧用CSS的Border属性

    . 作者:冯永曜 来源:黄山村夫 制作过网页的人都有为画线而烦恼的经历,本文介绍的小技巧也许对你有所帮助.我们先来认识一下"Border"(画边框),它是CSS的一个属性,用它可以 ...

  2. 巧用CSS的Border属性制作特效菜单

    许多应用软件的主菜单都具有这样的效果,通常是暗色的,一旦鼠标移到菜单上,立即变明亮:鼠标不在菜单上时是平面的,一旦鼠标移到菜单上,菜单条立即变为立体,从而增强了菜单的效果.你是否也想使网页中的导航菜单 ...

  3. border属性 php,使用CSS的border属性构建变形边框的方法总结

    border是最常用的用来制作各种各样p边框的CSS属性,这里我们整理了使用CSS的border属性构建变形边框的方法总结,最主要的还是基于三角形的一些图形变换: border基础回顾border 顾 ...

  4. css边框(border)属性

    border属性 代码如下: border:边框宽度 边框风格 边框颜色; 如:border:5px solid #555; 属性: (1)边框宽度: border-width:5px; (2)边框颜 ...

  5. IT:前端进阶技术路线图(初级→中级→高级)之初级(研发工具/HTML/CSS/JS/浏览器)/中级(研发链路/工程化/库/框架/性能优化/工作原理)/高级(搭建/中后台/体验管理等)之详细攻略

    IT:前端进阶技术路线图(初级→中级→高级)之初级(研发工具/HTML/CSS/JS/浏览器)/中级(研发链路/工程化/库/框架/性能优化/工作原理)/高级(搭建/Node/IDE/中后台/体验管理/ ...

  6. border属性 php,如何通过CSS的border属性为图片设置边框效果

    如何为通过css为图片设置一个边框呢,HTML中是通过标记的border属性值,给图片添加边框的,css中是通过border属性,为图片设置各式各样的边框样式,border-style定义边框的样式, ...

  7. css鼠标拖拉卡顿_JavaScript实现元素拖动性能优化

    前言:前几天没事干写了个小网站,打算用原生的javascript实现元素的拖动,但是事情并没有想象的那么顺利,首先是实现了拖动的元素卡的不能再卡,简直不能够,上图~~ 看见没?这就是效果,简直让人欲哭 ...

  8. 舞动你的文字,巧用CSS中marquee属性

    语法:<marquee> -</marquee> 使用移动属性marquee,不仅仅可以舞动你的文字,还可以应用于图片,表格等等. <marquee direction= ...

  9. CSS:不可思议的border属性

    原文:Magic of CSS border property 译文:不可思议的CSS border属性 译者:dwqs 在CSS中,其border属性有非常多的规则. 对于一些事物,比如三角形或者其 ...

最新文章

  1. 通过ddmlib杀死某个android进程的方法
  2. 【推荐系统】深入理解YouTube推荐系统算法
  3. GitChat · 大数据 | 一步一步学习大数据:Hadoop 生态系统与场景
  4. 【数据结构与算法】之深入解析“路径总和II”的求解思路与算法示例
  5. “赋值”与“初始化”
  6. Nginx+Php-fpm+MySQL+Redis源码编译安装指南
  7. 十一届蓝桥杯国赛 美丽的2-枚举
  8. win7 下安装oracle 10g
  9. spring-102-spring全注解快速实现事务
  10. Docker--------企业级最佳入门
  11. 要求在ASP.NET Core 2.2中确认电子邮件——第2部分
  12. php 用户数,php-获得最高数量,产品/用户数
  13. peterson算法p0流程图_Dekker算法与Peterson算法
  14. Jsp 中taglib标签的妙用
  15. 第二百三十二节,Bootstrap排版样式
  16. MATLAB图像形状识别
  17. Scrapy 官方文档中文版
  18. android换手机通讯录,技巧:要换新手机了 通讯录如何搬家?
  19. centos7时间校准
  20. POJ 1625 Censored! (AC自己主动机 + 高精度 + DP)

热门文章

  1. Java多线程(1)--基本概念:程序、进程、线程
  2. Spring的IOC底层实现
  3. 团队作业_1_博客1(分工理解)
  4. ls 显示目录下的内容和文件相关属性信息
  5. Linux下用ls和du命令查看文件以及文件夹大小
  6. ffmpeg摄像头推流
  7. 如何设置浏览器禁止使用UC浏览器
  8. 设计模式之单件模式(Singleton Pattern)
  9. easyui源码翻译1.32--ValidateBox(验证框)
  10. C++ operator操作符重载(++,--,-,+,())