微信小程序开发之压缩实践
凌雪 2018-10-10 来源 :网络 阅读 2220 评论 0

摘要:本文将带你了解微信小程序开发之压缩实践,希望本文对大家学微信有所帮助。

本文将带你了解微信小程序开发之压缩实践,希望本文对大家学微信有所帮助。


微信小程序依靠微信巨大的用户流量优势,吸引来了众多第三方开发者。几乎每个公司都会想通过小程序拉到新的用户群体。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   都会被同步加载,所以不用担心打包成一个文件后会延长小程序加载时间。那么打包压缩工具具体做了什么工作呢?小程序有一个统一的入口是 app.js ,而每个页面都有自己的入口 page.js利用   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) ,页面也没注册啊。这就是要达到的目的,继续往后看。将所有这些入口 require 到一个统一的入口文件中,然后用   webpack 打包压缩输出到 bundle.js 。require('app.js')
    require('page1.js')
    require('page2.js')
    ...
      现在 page.js 里的代码都打包到单一文件 bundle.js 里了。将 page.js 内容替换成 global['p'   +   index]() ,这样第三步中的 Page(pageOpt) 不就可以执行注册页面了。最后一步,替换 app.js 内容为 require('./bundle.js') 即大功告成。压缩   WXML、WXSS、JSONWXML/<!--((.|\n|\r)*?)-->/gm 去除注释/\"\n\s*/g 去除换行WXSS直接用 uglifycssJSON直接 JSON.stringify(JSON.parse(...))这里,有些读者会可能提出两个疑问:空白字符、换行能有多少,减不了多少吧?开发者工具为什么不做对这些文件的压缩?关于第一个问题,一个约   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   的可用空间。结语希望此次在小程序整合上做的,工程化抽取公共逻辑、规范业务代码,通过工具进行针对性的代码打包压缩的实践能给大家带来一定的帮助。    

本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标移动开发之微信频道!

本文由 @凌雪 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式AI+学习就业服务平台 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved