记录一次小程序中讨厌的拍照上传的优化
Posted Cyan_Con
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了记录一次小程序中讨厌的拍照上传的优化相关的知识,希望对你有一定的参考价值。
背景
工作中出现了一个业务,需要用户拍照并上传base64格式的图片内容供后台识别。项目并非从零开始,一通配置后跑了起来。自测了一会,下班时间到,开溜。
就在回家路上,打开手机分享图片时傻眼了,相册里全是自测的时候拍摄的照片,感到不舒服,这个项目之前据说已经交付过,我觉得用户肯定和我一样不舒服。
就这样
折腾劲来了~
目标
这次要折腾的目标很明确: 不影响逻辑(已有的代码能不动就不动)、不能再保存拍摄过的照片到相册中。
调研结果
现有代码中通过调用wx.chooseMedia
来进行拍照上传,微信小程序没有相关配置项,是否保存到相册等等。所以要改用其他的api来实现: 借助camera元素及其api
实现
-
新建一个page,在wxml中插入camera元素及拍摄按钮,还可以放置其他必要的元素,例如提示框等;
-
声明一个page的方法,例如
getCameraContent
用来获取camera相机内容,将此方法绑定到拍摄按钮中;
代码案例:
// wxml
<view class="camera-wrap">
<camera mode="normal" device-position="front" flash="auto" class="camera"></camera>
<button type="primary" class="take-btn" bindtap="getCameraContent">
拍照
</button>
</view>
// page.js
getCameraContent()
return new Promise((resolve) =>
const cameraContext = wx.createCameraContext();
cameraContext.takePhoto(
quality: \'high\',
success: (res) =>
resolve(res.tempImagePath);
)
)
这样在调用getCameraContent().then()
时就会拿到微信提供的本地临时路径,后续转换为Base64通过接口发送即可。其他地方逻辑并没有改变,只是改变了从点击上传到调用上传接口之间的逻辑。
这里通过新建页面的方式来实现,因为在之前wx.chooseMedia
调用时,会出现相机全屏的行为,我们新方案给了个新页面,行为一致,对用户影响较小。初次之外还可以在页面中插入一些自定义内容,定制化方面很友好。
为什么要改?
我们在微信拍照时通常都是身份证、人脸、银行卡等一些敏感信息,此类信息在处理时更应该注意安全。
记录一次EF优化
问题描述:1、第一次加载过慢(EntityFramework 6 code-first)。2、一段时间间不访问页面同样变慢。
原因分析:1、第一次启动(Code First)会对比程序中的Model与数据库表(database initializer ),生成Model与数据库的映射视图
2、EF程序集没有生成本地镜像,这样每次程序启动,EF的代码都会通过just-in-time (JIT) compiler(即时编译器)把MSIL中间代码编译成本机能识别的本地代码。因为这个生成的本地代码存在程序运行的进程里面的内存中,它将回收当程序进程被终止(例如:iis程序池回收,程序池默认是按需触发运行的,没人访问它就不启动了)。由于EF框架还是比较大的,EF6文件大小到4-5M了,所以每次启动都要重写编译本地代码有比较明显的性能影响。
(https://www.fusonic.net/en/blog/3-steps-for-fast-entityframework-6.1-code-first-startup-performance/)
3、iis程序池回收或站点更新需要重新加载;
解决方案:
1、预生成映射视图(EF6.0+):
//预生成映射视图 using (var dbcontext = new yourDbContext()) { var objectContext = ((IObjectContextAdapter)dbcontext).ObjectContext; var mappingCollection = (StorageMappingItemCollection)objectContext.MetadataWorkspace.GetItemCollection(DataSpace.CSSpace); mappingCollection.GenerateViews(new List<EdmSchemaError>()); }
参考:http://www.cnblogs.com/dudu/p/entity-framework-warm-up.html;
实际情况可能要用到反射:
更多参考:http://www.cnblogs.com/yujiajun/p/EF_PreHeat.html
2、禁止EF第一次查询对__MigrationHistory访问(检查数据库和model是否匹配)(
- SELECT
- [GroupBy1].[A1] AS [C1]
- FROM ( SELECT
- COUNT(1) AS [A1]
- FROM [dbo].[__MigrationHistory] AS [Extent1]
- ) AS [GroupBy1]
- GO
- SELECT TOP (1)
- [Extent1].[Id] AS [Id],
- [Extent1].[ModelHash] AS [ModelHash]
- FROM [dbo].[EdmMetadata] AS [Extent1]
- ORDER BY [Extent1].[Id] DESC
- GO
)
:Database.SetInitializer<yourDbContext>(null);
3、使用n-gen 生成本地镜像 (to avoid jitting)
更多参考:https://msdn.microsoft.com/en-us/data/dn582034
cd <Solution directory>\\packages\\EntityFramework.6.0.2\\lib\\net45 %WINDIR%\\Microsoft.NET\\Framework\\v4.0.30319\\ngen install EntityFramework.SqlServer.dll %WINDIR%\\Microsoft.NET\\Framework64\\v4.0.30319\\ngen install EntityFramework.SqlServer.dll
4、application-initialization(IIS8内置)
Application Initialization Module for IIS 7.5
设置:application pool-StartModel 设置为 AlwaysRunning;WebSites:DoAppInitAfterRestart、Preload;
IIS程序池回收重启的时候就完成了加载,这样外部访问就不会“第一次访问”。
另外:为了减少重新编译dll带来的性能影响建议把各部分都单独的分层,编译成单独的dll;IIS可以设加大应用程序池的”闲置超时“的参数值。
以上是关于记录一次小程序中讨厌的拍照上传的优化的主要内容,如果未能解决你的问题,请参考以下文章
如何在不完全影响主屏幕绘图性能的情况下每 200/250 毫秒更新一次小部件?