GVKun编程网logo

微信小程序压缩实践(微信小程序压缩实践怎么做)

22

想了解微信小程序压缩实践的新动态吗?本文将为您提供详细的信息,我们还将为您解答关于微信小程序压缩实践怎么做的相关问题,此外,我们还将为您介绍关于1-微信小程序开发(安装软件和运行第一个微信小程序)、u

想了解微信小程序压缩实践的新动态吗?本文将为您提供详细的信息,我们还将为您解答关于微信小程序压缩实践怎么做的相关问题,此外,我们还将为您介绍关于1 - 微信小程序开发 (安装软件和运行第一个微信小程序)、uni-app开发微信小程序使用微信小程序的插件、uniapp微信小程序内部跳转其他微信小程序、【微信小程序】图片压缩-纯质量压缩,非长宽裁剪压缩的新知识。

本文目录一览:

微信小程序压缩实践(微信小程序压缩实践怎么做)

微信小程序压缩实践(微信小程序压缩实践怎么做)

OSC 请你来轰趴啦!1028 苏州源创会,一起寻宝 AI 时代

微信小程序依靠微信巨大的用户流量优势,吸引来了众多第三方开发者。几乎每个公司都会想通过小程序拉到新的用户群体。3 月份接到公司任务,需要将公司各业务线小程序整合到一个小程序中。但摆在面前的问题是空间完全不够。当时微信小程序的使用空间是 1024KB(现在已升为 2M),各个业务线独立的小程序都不小,『机票火车票汽车票』小程序更是超过 900KB。如何整合和压缩才能使 size 达标,成了最大的挑战。

我们经过考虑,准备从两个方面进行整合和压缩,一是通过工程化的方式实现代码复用 —— 提取公共业务逻辑,公共组件;二是通过工具进行自定义化代码打包压缩处理。

工程规范制定

为了节省开发时间,我们尽量整合现有业务线小程序代码,减少业务改动。

目录结构

同时为了后期计算各业务占用空间情况方便,我们直接将各业务线小程序工程代码拷贝到各自业务线目录下,最终的目录结构如下:

.
├── common # 通用模块/公共业务
├── home   # 首页
├── flight # 机票
├── train  # 火车票
├── bus    # 汽车票
├── hotel  # 酒店
└── ticket # 门票

common 模块即工程的复用部分,具体业务代码都在各自目录下。总体架构如下:

公共组件、API

微信小程序其实并没有提供组件化开发的方式。只是提供了 template 的方式,所以我们只提供了为数不多的页面及组件,例如:城市定位、日历组件等。但是收益却是非常明显的,像这些页面大小都在 20KB~30KB,如果每个业务自己整一套可能将徒增上百 KB 代码。

公共 API 我们提供了统一的 Watcher 监控、 Requester 请求、 Loading 加载转态、 Navigation 导航等。这些公共逻辑的抽取,为整个项目整合节省了巨大的空间,使 size 达标看起来不那么难了。

工程复用上节省了很大一部分空间。但是空间是有限的,业务需求是无限的。而且,size 的大小会影响用户加载的速度,包括下载最新版本代码的速度和小程序初始化的速度,所以还需要进一步进行代码压缩。

打包压缩工具

微信开发者工具

我们知道微信小程序开发者工具本身提供了『代码压缩上传』功能。

但是个人觉得它是个『假的压缩选项』。因为在阅读开发者工具的源码逻辑之后,发现它的压缩,只是将 JavaScript 用 uglify 进行混淆压缩。而对 WXML、WXSS 没有进行任何压缩处理。同时,对资源路径中的无用文件也没有做处理。

小程序的构建

在小程序开发者工具的 Sources 面板,查看 JavaScript 脚本,会发现:项目中所有的 JavaScript 都会被 同步加载 ,不管是否被 require 。

每个脚本都会被套上如下代码:

define("some.js", function(require,module){
    // 原本的代码
});

这种加载方式类似 AMD,但是跟标准的 AMD 又有些不同,缺少了依赖部分的声明。

而对于 WXSS 和 WXML 文件,则被开发者工具自动转换为 JavaScript 后加载,其中:

WXSS:主要处理的是 import 逻辑,然后生成的 CSS,通过脚本的形式插入页面使用。

WXML:类似于 React Naitive 的 JSX,被编译成 createElement 类似的形式。

一些技巧

在 MacOS 系统中,右键开发者工具『Show Contents』(显示包内容),就能在 Resources/app.nw/ 下找到相应的源码,完成路径如下: /Applications/wechatwebdevtools.app/Contents/Resources/app.nw/ 。

源码都是压缩过后的 JavaScript 脚本,可以使用 js-beautity 进行格式化,以便于阅读。

// 在源码目录的 app 目录下执行
find . -type f -name ''*.js'' -exec js-beautify -r -s 2 -p -f ''{}'' \;
  • 在资源目录下: app/dist/app.js 的第 37 行 window.addEventListener("resize", function() {}) 之前,加入 nw.Window.get().showDevTools(); 。之后每次打开微信开发者工具时,会自动启动针对『开发者工具』的开发者工具,并可以通过它调试微信的开发者工具。

  • 在打印日志时,不要用 console.log ,请使用 global.contentWindow.console.log 。这样,才能输出到上面所说的开发者工具的开发者工具的控制台里。(NW.js 的 Node JS Context 和 Webkit JS Context 是分开的, JavaScript 脚本运行在 Node 的 JS Context 中,因此,打印其实打印在 Node 的输出中,并不在 Webkit 的开发者工具的控制台中。 global.contentWindow 获取的是 Webkit 的 JS Context 里的 Window)

使用这两点技巧,读者们可以优雅地去阅读微信开发者工具的源码了。

在阅读源码,知道微信小程序的内部加载构建方式之后,我们可以针对性的对 JavaScript、WXML、WXSS 等代码文件进行打包压缩。

压缩 JavaScript

由于微信只是将 js 进行了混淆压缩,并没有打包合并成一个文件。所以我们提供了打包压缩工具将 js 文件合并压缩成一个 bundle.js 文件。合并成一个文件有以下好处:

  • require 的长路径没了,脚本压缩效率变高
  • 代码合并在一起,混淆性越大
  • 文件合并,减少了 IO 次数,提升了加载效率

上文说了 JavaScript 都会被同步加载,所以不用担心打包成一个文件后会延长小程序加载时间。

那么打包压缩工具具体做了什么工作呢?

  1. 小程序有一个统一的入口是 app.js ,而每个页面都有自己的入口 page.js
  2. 利用 AST,将 page.js 里页面注册 Page(pageOpt) 代码改成 global.YPage(pageName, pageIndex)(pageOpt)

    pageName 页面路由

    pageIndex 是打包工具根据页面路由内部自动维护的

    // global.YPage 函数
    global.YPage = (pageName, index)=> {
        return (pageOpt) => {
            // 其他处理逻辑
            global[''p'' + index] = ()=> {
                Page(pageOpt);
            }
        }
    }

    这样 page.js 里实际是这样的代码

    global[''p'' + index] = ()=> {
           Page(pageOpt);
    }

    这样并不会执行 Page(pageOpt) ,页面也没注册啊。这就是要达到的目的,继续往后看。

  3. 将所有这些入口 require 到一个统一的入口文件中,然后用 webpack 打包压缩输出到 bundle.js 。

    require(''app.js'')
    require(''page1.js'')
    require(''page2.js'')
    ...
  4. 现在 page.js 里的代码都打包到单一文件 bundle.js 里了。将 page.js 内容替换成 global[''p'' + index]() ,这样第三步中的 Page(pageOpt) 不就可以执行注册页面了。

  5. 最后一步,替换 app.js 内容为 require(''./bundle.js'') 即大功告成。

压缩 WXML、WXSS、JSON

WXML

  • /<!--((.|\n|\r)*?)-->/gm 去除注释
  • /\"\n\s*/g 去除换行

WXSS

  • 直接用 uglifycss

JSON

  • 直接 JSON.stringify(JSON.parse(...))

这里,有些读者会可能提出两个疑问:

  1. 空白字符、换行能有多少,减不了多少吧?
  2. 开发者工具为什么不做对这些文件的压缩?

关于第一个问题,一个约 1000KB 的代码,空白字符和换行大概有 10KB。在有上限的情况之下,10 KB 也是要珍惜的。

关于第二个问题,个人认为微信开发者工具的开发者觉得没有必要去做。因为,WXML 和 WXSS 都会被转义成 JavaScript 脚本,在此过程中,不管 WXML 和 WXSS 是否被压缩,它们的转化结果是相同的。因此,压缩与否,对于最终产物是没有影响的(最终产物指在服务器二次打包后的结果,也是用户真正使用的)。但是,Size 是以本地打包上传的内容进行计算的,不进行此步压缩,会使微信服务端判定的 Size 增大。

删除无用文件

工程庞大了,肯定会存在很多无用的空目录,空文件,没有被 import 的 js 、 wxml 、 wxss 文件。

删除这些无用文件不仅可以减小 size,还可以提升小程序加载时间。上文说了这些文件都会被转成 JavaScript 进行加载的,是会占用加载时间的。

删除无用 JavaScript

由于通过 webpack 打包,除了 page.js 、 bundle .js 文件,其他 js 文件都可以删掉。

删除无用 WXML

打包压缩工具在打包时,已经记录了所有页面的路由。遍历分析所有路由下的 wxml 文件,通过 xmldom 解析代码记录其他被 import 的 wxml 文件。最后遍历所有 wxml 文件,删除不在 import 列表里的无用 wxml 文件。

删除无用 WXSS

类似处理 WXML。遍历分析所有路由下的 wxss 文件,通过正则 /@import\s*["'']([^"'']+)["'']/g 分析代码记录其他被 import 的 wxss 文件。最后遍历所有 wxss 文件,删除不在 import 列表里的无用 wxss 文件。

代码级优化

除了利用工具进行压缩,在编写代码时,也可以通过一些方法来减小体积,在这里简单列几点:

  • 使用 ES6 时,尽量不使用依赖 Runtime/Polyfill 的语法,例如 import 和 class 。
  • 图标使用 Iconfont。
  • 等等…

最终效果

经过打包工具的极限压缩处理,还有代码设计上的可复用性,目前我们七个业务线的微信小程序整合后代码编译包大小维持在 1300KB 左右。

还剩余 730KB 的可用空间。

结语

希望此次在微信小程序整合上做的,工程化抽取公共逻辑、规范业务代码,通过工具进行针对性的代码打包压缩的实践能给大家带来一定的帮助

1 - 微信小程序开发 (安装软件和运行第一个微信小程序)

1 - 微信小程序开发 (安装软件和运行第一个微信小程序)

https://developers.weixin.qq.com/miniprogram/dev/

 

 

 

 

 

 

 

 

 

 

我的

 

 

 

 

 

 

 

 

 打开

 

 

 

 

 

 

 

 

 

 上传成功后

 

 

 

 

 

 

 

 

 

 

uni-app开发微信小程序使用微信小程序的插件

uni-app开发微信小程序使用微信小程序的插件

假如使用uni-app开发微信小程序需要用到官方插件----OCR插件,
插件地址如下:
OCR插件

申请方式见插件地址介绍。本文主要记录调用方式
1.在manifest.json的“mp-weixin”里添加

"plugins": {
   "ocr-plugin": {
        "version": "3.0.1",
        "provider": "wx4418e3e031e551be"
    }
}

2.在pages.json的globalStyle添加

"usingComponents": {
    "ocr-navigator": "plugin://ocr-plugin/ocr-navigator"
}

3.在需要的调用插件的页面中调用,根据微信的插件接入文档,该插件对外暴露自定义组件的UI载体为button,所以这里我使用button包住一个字体图标

<ocr-navigator @onSuccess="success" certificateType="idCard" :opposite="false">
  <button type="primary"><i>&#xe62c;</i></button>
</ocr-navigator>

插件调用成功之后的回调,在这里面接受返回的参数

success(res) {
    console.log(res)
    this.realname = res.detail.name.text
    this.idcard = res.detail.id.text
},

完毕

uniapp微信小程序内部跳转其他微信小程序

uniapp微信小程序内部跳转其他微信小程序

 uniapp小程序内点击某个按钮跳转另外一个小程序连接,具体实现步骤如下:

 

<view@click="goNativeindex">
      <imagesrc="../../static/images/icon1.png" mode=""></image>
      <view>开源字节</view>
</view>

按钮事件

goNativeindex(){
    uni.navigateToMiniProgram({
        appId:'''',// 此为 开源字节 appid
        path:''/pages/index/index'',// 此为开源字节首页路径
        envVersion:"release",
        success: res => {
             // 打开成功
             console.log("打开成功", res);
        },
        fail: err => {
             console.log(err);
        }
    })
}

 

需要记住的是,需要填写另外一个小程序的AppID哦!

如若转载,请注明出处:开源字节   https://sourcebyte.vip/article/299.html

 

【微信小程序】图片压缩-纯质量压缩,非长宽裁剪压缩

【微信小程序】图片压缩-纯质量压缩,非长宽裁剪压缩

原理:利用canvas来实现,将图片绘制到canvas上,然后canvas转图片时,微信提供的一个方法wx.canvasToTempFilePath(Object object, Object this),此方式可以指定生成图片的质量,下图是从官方API截的图:

其中quality可以指定图片的质量,quality的值越小,图片越模糊,通过此方法可以实现图片的压缩

注意

1.quality设置只对jpg格式的图片有效,使用时要将fileType设置为“jpg”, 此举可能会导致其它格式的图片变为jpg格式

2.透明背景的png图片,绘制到canvas上使用此方式导出的图片是黑色背景,有需求的话是需要canvas先设置背景色的,请小伙伴们注意爬坑。

有了这个参数,压缩就简单很多了,下面是代码:

wxml

<view>
  <button bindtap="chooseImage">选择图片</button>
</view>

<!-- 展示压缩后的图片 -->
<view>
  <image width="50" mode="widthFix" src="{{imagePath}}"></image>
</view>

<button wx:if="{{imagePath.length>0}}" bindtap="save">点击下载压缩后的图片</button>

<!-- 用来渲染的canvas --> 
<canvas canvas-id=''attendCanvasId''myCanvas''width:{{cWidth}}px;height:{{cHeight}}px;position: fixed;top: -9999px;left: -9999px;''></canvas>

js

Page({
  data: {
    imagePath: '''',
    quality: 0.2
  },
  onLoad: function (options) {
  
  },
  /**
  * 选项添加图片事件
  */
  chooseImage: function (e) {
    var that = this;
    wx.chooseImage({
      sizeType: [''compressed''],  //可选择原图或压缩后的图片
      sourceType: [''album'', ''camera''], //可选择性开放访问相册、相机
      success: result => {
        wx.getImageInfo({
          src: result.tempFilePaths[0],
          success: function (res) {
            that.setData({
              cWidth: res.width,
              cHeight: res.height
            })
            that.getCanvasImg(result.tempFilePaths, res.width, res.height, that.data.quality, function (res) {
              that.setData({
                imagePath: res.tempFilePath
              });
            });
          }
        })
      }
    })
  },
  /**
   * 质量压缩
   */
  getCanvasImg(tempFilePaths, canvasWidth, canvasHeight, quality, callback) {
    var that = this; 
    const ctx = wx.createCanvasContext(''attendCanvasId'');
    ctx.clearRect(0, 0, canvasWidth, canvasHeight);
    ctx.drawImage(tempFilePaths[0], 0, 0, canvasWidth, canvasHeight);
    ctx.draw(false, function () {
      wx.canvasToTempFilePath({
        canvasId: ''attendCanvasId'',
        fileType: ''jpg'',
        quality: quality,
        success: function success(res) {
          callback && callback(res)
        }, fail: function (e) {
          wx.showToast({
            title: ''图片上传失败,请重新上传!'',
            icon: ''none''
          })
        }
      });
    });
  },
  /**
   * 图片保存到相册
   */
  save(e) {
    let that = this;
    wx.saveImageToPhotosAlbum({
      filePath: that.data.imagePath,
      success: function (res) {
        console.log(''图片已保存'');
      },
      fail: function (res) {
        console.log(''保存失败'');
      }
    })
  },
})

注意点

  1. 注意设置canvas-id=''attendCanvasId''
  2. canvas要离屏渲染,就是移出屏幕之外,但是元素还是显示的,position: fixed;top: -9999px;left: -9999px; 不能使用 display: none; 这样是获取不到canvas元素的。

最后

h5页面中也有提供这样的方法

例如这样子:

let canvas = document.createElement(''canvas'');
let ctx = canvas.getContext(''2d'');
ctx.drawImage(imagePath, 0, 0, w, h);
canvas.toDataURL(''image/jpeg'', quality);

需要的小伙伴也可以自己研究研究哈...

源码-欢迎star

感谢

ok, 结束,

今天关于微信小程序压缩实践微信小程序压缩实践怎么做的分享就到这里,希望大家有所收获,若想了解更多关于1 - 微信小程序开发 (安装软件和运行第一个微信小程序)、uni-app开发微信小程序使用微信小程序的插件、uniapp微信小程序内部跳转其他微信小程序、【微信小程序】图片压缩-纯质量压缩,非长宽裁剪压缩等相关知识,可以在本站进行查询。

本文标签: