0
点赞
收藏
分享

微信扫一扫

混合开发问题

RockYoungTalk 2022-01-17 阅读 55
javascript
作者内容时间
JJ混合开发问题20220117

样式适配问题

在这里插入图片描述
同一页面,同一元素,展示出左右2中形态(华为mate30pro设备分辨率1176*2400,宽度单位使用的rem)。

大家思考下,为什么会有这个问题?

引申一下

像素分类:设备像素和CSS像素

  1. 设备像素(device independent pixels): 设备屏幕的物理像素,任何设备的物理像素的数量都是固定的
  2. CSS像素(CSS pixels): 又称为逻辑像素,是为web开发者创造的,在CSS和javascript中使用的一个抽象的层
  3. 每一个CSS声明和几乎所有的javascript属性都使用CSS像素,因此实际上从来用不上设备像素 。

在桌面端,css的1个像素往往都是对应着电脑屏幕的1个物理像素

​
手机端,由于屏幕尺寸的限制,缩放是经常性的操作。

缩小操作时,一个设备像素覆盖了多个CSS像素

放大操作时,一个CSS像素覆盖了多个设备像素

​ 不论缩小或放大,元素设置的CSS像素(如width:300px)是始终不变的,而一个CSS像素对应多少个设备像素是根据当前的缩放比例来决定的。

在HTML中不得不提到viewport,经常会设置viewport的width=device-width,那这个device-width的值是多少呢?

<meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no"/>  

​ 在iphone5下device-width=320,iphone6下是375,iphone6+下是414。

DPR:

	设备像素比DPR(devicePixelRatio)是默认缩放为100%的情况下,设备像素和CSS像素的比值

dpr,也被成为device pixel ratio,即物理像素与逻辑像素的比,那也就不难理解:iphone6下dpr=2,iphone6+下dpr=3(考虑的是栅格化时的像素,并非真实的物理像素;
在这里插入图片描述

问题原因:

​ 由于华为浏览器版本问题,低版本华为浏览器支持最小像素为12px,高版本则无限制。

如何规避类似问题:

​ 采用postcss-pxtorem 和 flexible
​ postcss-pxtorem作用:将px转换为rem
flexible 作用:计算根font-size (flexible.js )

postcss-pxtorem使用方法:

main.js中

// 引入 flexible 用于设置 rem 基准值
import 'lib-flexible/flexible.js';

.postcssrc.js配置

module.exports = {
"plugins": {
"postcss-import": {},
"postcss-url": {},
// to edit target browsers: use "browserslist" field in package.json
"autoprefixer": {},
'postcss-pxtorem': {
rootValue({ file }) {
return file.indexOf('vant') !== -1 ? 37.5 : 117.6;(width/10
},
"propList": ['*'],
   "selectorBlackList": ['.norem']  // 过滤掉 .norem 开头的 class,不进行转换
}
}
}

1px 边框(vant)

<!-- 上边框 --> 
<div class="van-hairline--top"></div>

移动端1px实现方案( https://zhuanlan.zhihu.com/p/100752129 )

性能优化

路由懒加载

一、定义

​ 懒加载简单来说就是延迟加载或按需加载,即在需要的时候的时候进行加载。

二、写法

常用的懒加载方式有两种:即使用vue异步组件ES中的import

未懒加载写法:import index from '@/pages/index/index.vue';
懒加载写法1const index = () => import('@/pages/index/index.vue');
	routes: [
    {
      path: '/',
      name: 'index',
	  component:index
	}]
懒加载写法2
	routes: [
    {
      path: '/',
      name: 'index',
      component: resolve=>(require(["@/pages/index/index.vue"],resolve))
    }]

三、打包后区别

未做懒加载dist包中js文件夹
在这里插入图片描述
修改为懒加载dist包中js文件夹
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-se2SOEwe-1640224085403)(C:\Users\0oo0\Desktop\技术分享\懒加载.jpg)]

图片压缩(https://tinypng.com/)

开启gzip

一、配置

config/index.js/productionGzip: true (打包效果如上图)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-d6aC5y2e-1640224085403)(C:\Users\0oo0\Desktop\技术分享\开启gzip.jpg)]

二、效果

在这里插入图片描述
在这里插入图片描述
​ 当 HTML 文档解析完成就会触发 DOMContentLoaded,而所有资源加载完成之后,load事件才会被触发。 jQuery 中经常使用的 $(document).ready(function() { // …代码… }); 其实监听的就是 DOMContentLoaded 事件,而 $(document).load(function() { // …代码… }); 监听的是 load 事件。

三、使用安卓壳cdr缓存

在这里插入图片描述
在这里插入图片描述

组件按需加载

一、vant按需加载

在这里插入图片描述

二、echarts按需加载

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pbvRgKC1-1640224085405)(C:\Users\0oo0\Desktop\技术分享\echarts1.jpg)]
main.js中
在这里插入图片描述

使用cdn缓存(网络限制未使用)

一、资源引入

在index.html中,添加CDN资源,例如bootstrap上的资源:

 <body>
	<div id="app"></div>
	<script src="https://cdn.bootcss.com/vue/2.5.2/vue.min.js"></script>
	<script src="https://cdn.bootcss.com/vue-router/3.0.1/vue-router.min.js"></script>
</body>

二、添加配置

在bulid/webpack.base.conf.js文件中,增加externals,将引用的外部模块导入,如下:

module.exports = {
	entry: {app: './src/main.js'},
	externals:{'vue': 'Vue','vue-router': 'VueRouter'}
}

三、去掉原有的引用

去掉import、去掉Vue.use(XXX)等如:

// import Vue from 'vue'
// import Router from 'vue-router'
// Vue.use(Router)

交互优化

一、增加超时时间

ajax.js中,

ajax.defaults.timeout = 10000;

二、增加超时提示

ajax.js后置拦截器error中,增加

	if (error && error.stack.indexOf('timeout') > -1) {
       		Toast.fail({message: '连接超时,请检查你的网络'});} 
		else if (error && error.stack.indexOf('Network Error') > -1) {        
			Toast.fail({ message: '当前网络不可用,请检查你的网络'});    
	}

weixin-js-sdk用法

npm i -S weixin-js-sdk

使用

//引入
import wx from 'weixin-js-sdk';
//请求接口获取jsapi_ticket
const params = {
    //当前页面url
    url:location.href.split('#')[0],
    //随机字符串
    noncestr:Math.random().toString(36)
    .substr(2, 15),
    //时间戳
    timestamp:parseInt(new Date().getTime() / 1000)
};
//接口返回票据后注册
   wx.config({
       debug: false,
       appId: 'wld341060039',
       timestamp:params.timestamp,
       nonceStr: params.noncestr,
       signature: res.ticket,
       //注册事件 选择照片/拍照  获取本地照片数据
       jsApiList: ['chooseImage', 'getLocalImgData']
   	});
    // 通过ready接口处理成功验证
    wx.ready(function () {
        console.log(666);
    });
    // 通过error接口处理失败验证
    wx.error(function (res) {
        console.log('error', res);
    });
    // 判断当前客户端版本是否支持指定JS接口
    wx.checkJsApi({
        // 需要检测的JS接口列表,所有JS接口列表见附录2,
        jsApiList: ['chooseImage', 'getLocalImgData'],
        success: function (res) {
            console.log(res);
            // 以键值对的形式返回,可用的api值true,不可用为false
            // 如:{"checkResult":{"chooseImage":true},"errMsg":"checkJsApi:ok"}
        }
	});

拍照或从手机相册中选图接口

wx.chooseImage({
    count: 1, // 默认9
    sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有
    sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
    quality: 0.8, //压缩质量,范围0~1,数值越小,质量越低,压缩率越高(仅对jpg有效)
    success: function (res) {
    	// 返回选定照片的本地ID列表(绝对路径),localId可以作为img标签的src属性显示图片
   		 var localIds = res.localIds; 
    }
});

获取本地图片接口

wx.getLocalImgData({
localId: '', // 图片的localID
success: function (res) {
//localData是图片的base64数据,可以用img标签显示
let localData = res.localData;
//ios与安卓兼容问题
if (localData.indexOf('data:image') != 0) {
// 判断是否有这样的头部
localData = `data:image/jpeg;base64,${localData}`;
}
localData = localData.replace(/\r|\n/g, '').replace('data:image/jgp', 'data:image/jpeg');
}
});

ios压缩图片问题

图片压缩方法

 cutImageBase64(base64, w, callback) {
      const newImage = new Image();
      let quality = 0.6; // 压缩系数0-1之间
      newImage.src = base64;
      newImage.setAttribute('crossOrigin', 'Anonymous'); // url为外域时需要
      let imgWidth, imgHeight;
      newImage.onload = function () {
      imgWidth = this.width;
      imgHeight = this.height;
      const canvas = document.createElement('canvas');
      const ctx = canvas.getContext('2d');
      if (Math.max(imgWidth, imgHeight) > w) {
          if (imgWidth > imgHeight) {
                  canvas.width = w;
                  canvas.height = w * imgHeight / imgWidth;
              } else {
                  canvas.height = w;
                  canvas.width = w * imgWidth / imgHeight;
              }
          } else {
              canvas.width = imgWidth;
              canvas.height = imgHeight;
              quality = 0.6;
      }
      ctx.clearRect(0, 0, canvas.width, canvas.height);
      ctx.drawImage(this, 0, 0, canvas.width, canvas.height);
      let base64 = canvas.toDataURL('image/jpeg', quality); // 压缩语句
      // 如想确保图片压缩到自己想要的尺寸,如要求在50-150kb之间,请加以下语句,quality初始值根据情况自定
      while (base64.length / 1024 > 150) {
          quality -= 0.01;
          base64 = canvas.toDataURL('image/jpeg', quality);
      }
      // 防止最后一次压缩低于最低尺寸,只要quality递减合理,无需考虑
      while (base64.length / 1024 < 50) {
          quality += 0.001;
          base64 = canvas.toDataURL('image/jpeg', quality);
      }
      	// 必须通过回调函数返回,否则无法及时拿到该值
      	callback(base64);
      };
  }

使用压缩图片

this.cutImageBase64(base64, 700, this.uploadImgbas);

压缩后的数据

uploadImgbas(base64) {	console.log(base64)}

ios注意事项

在IOS中,canvas绘制图片是有两个限制的:
  首先是图片的大小,如果图片的大小超过两百万像素,图片也是无法绘制到canvas上的,调用drawImage的时候不会报错,但是你用toDataURL获取图片数据的时候获取到的是空的图片数据。
  再者就是canvas的大小有限制,如果canvas的大小大于大概五百万像素(即宽高乘积)的时候,不仅图片画不出来,其他什么东西也都是画不出来的。
  应对上面两种限制,我把图片宽度、高度压缩控制在1000px以内,这样图片最大就不超过两百万像素了。在前端开发中,1000px*1000px基本可以满足绝大部分的需求了。当然了还有更完美的瓦片式绘制的方法,我们这里就说瓦片式绘制方法了。
  如此一来就解决了IOS上的两种限制了。

除了上面所述的限制,还有两个坑,一个就是canvas的toDataURL是只能压缩jpg的,当用户上传的图片是png的话,就需要转成jpg,也就是统一用canvas.toDataURL(‘image/jpeg’, 0.5) , 类型统一设成jpeg,而压缩比就自己控制了。

另一个就是如果是png转jpg,绘制到canvas上的时候,canvas存在透明区域的话,当转成jpg的时候透明区域会变成黑色,因为canvas的透明像素默认为rgba(0,0,0,0),所以转成jpg就变成rgba(0,0,0,1)了,也就是透明背景会变成了黑色。解决办法就是绘制之前在canvas上铺一层白色的底色。

举报

相关推荐

0 条评论