首页 > 编程语言 >【原子样式实践】第8篇 升级微信小程序原子样式工具的实时生成能力-20ms响应

【原子样式实践】第8篇 升级微信小程序原子样式工具的实时生成能力-20ms响应

时间:2022-10-23 12:02:50浏览次数:56  
标签:11 10 23 样式 微信 02 原子 gray text

前文的示例教学中给出了全量生成为微信小程序原子样式的过程,但生成时间在你100-300ms之间,延迟页面生效,页面有较为明显的抖动。为了增强工具的实用性,本文探讨如何进行10ms以内的页面级响应。


1 工作原理

1.1 全量生成和部分生成

初次生成微信小程序原子样式时必须使用全量生成,建立缓存数据。后续生成时基于缓存数据,可以使用部分生成,达到页面级响应。

为了方便描述,主文件分为三个函数。

(1)fullBuild 为全量生成函数,仅在初始化完成后执行。

(2)partiallyUpdate 为部分生成函数,在监测文件变化后执行,复用了全量函数生成的页面样式缓存结果。

(3)匿名函数为主函数,直接执行。

编码采用无状态函数、箭头函数、Promise风格,主文件中除了三个输入参数(配置文件、自定义配置参数、系统文件事件参数)、返回值和错误值外,没有其他参数,没有流程图也可以方便的理解逻辑。

import "https://deno.land/x/[email protected]/mod.ts";
import "https://deno.land/[email protected]/fs/mod.ts";
import {printError, log, timing} from "./util.ts"
import {OptionalRunningConfig, WxRunningConfig} from "./data.config.ts";
import * as wx from "./mod.wx.ts";

const fullBuild = (config: WxRunningConfig): Promise<number> => {
log("[task] start auto generation after started");
const time = timing()
return Promise.all([
wx.parseGlobalStyleNames(config),
wx.parseMiniProgramPages(config).then(wx.batchPromise(wx.parsePageClassNames, config)),
wx.parseComponentPages(config).then(wx.batchPromise(wx.parseComponentClassNames, config)),
]).then(wx.mergeTargetClassNames(config))
.then(wx.generateContent(config))
.then(wx.saveContent(config))
.then(wx.finishAndPrintCostTime(config, time))
.then(() => log("service ready, Press Ctrl-C to exit"))
.catch(printError(time))
}

const partiallyUpdate = (config: WxRunningConfig, fileEvents: string[]): Promise<number> => {
const time = timing()
return wx.generateClassNamesFromFileEvents(config, fileEvents)
.then(wx.generateContent(config))
.then(wx.saveContent(config))
.then(wx.finishAndPrintCostTime(config, time))
.catch(printError(time))
}

(function () {
log("==========================================================");
log(" wxmp-atomic-css: wechat mini program atomic css kit");
log("==========================================================");
log("starting wxmp-atomic-css");

const sigIntHandler = () => {
log("wxmp-atomic-css service closed");
Deno.exit();
};
Deno.addSignalListener("SIGINT", sigIntHandler);

wx.readRunningConfig("data/config.json", {
// debugOption: {showPageClassNames: true, showPageTaskBegin: true, showPageTaskResult: true}
} as OptionalRunningConfig)
.then(wx.ensureWorkDir)
.then(wx.printRunningConfig)
.then((config: WxRunningConfig) => fullBuild(config)
.then(() => wx.watchMiniProgramPageChange(config, partiallyUpdate)))
.catch((e: unknown) => log(e))
})()

匿名主函数的流程为:(1)打印启动日志;(2)注册中断函数;(3)读取配置,检查小程序目录,打印配置,全量生成样式文件,监测小程序目录生成样式文件。

fullBuild 全量生成函数的流程为:(1)读取全局样式,读取组件页面样式,读取并计算主包、分包页面需要生成的样式,(2)合并计算需要生成的样式;(3)生成样式内容;(4)保存内容到文件;(5)缓存结果,打印耗时。

partiallyUpdate 部分生成函数的流程为:(1)根据事件更新的页面需要生成的样式,合并缓存获得全部需要生成的样式;(2)生成样式内容;(3)保存内容到文件;(4)缓存结果,打印耗时。


1.2 主要参数定义

1.2.1 运行参数定义
export interface WxRunningConfig {

/**
* working dir, default value is ".", should detect if contains correct contents
*/
workDir: string

/**
* temp data, which store global rules and themes
*/
tempData: TempData

/**
* mini program file structure
*/
fileStructure: FileStructure

/**
* mini program file extension
*/
fileExtension: FileExtension

/**
* css options
*/
cssOption: CssOption

/**
* debug options, each default value is false
*/
debugOption: DebugOption

/**
* data file or uri
*/
dataOption: DataOption

/**
* watch options
*/
watchOption: WatchOption

/**
* process options, e.g. promise
*/
processOption: ProcessOption
}


/**
* debug option
*/
export interface DebugOption {
/**
* print configuration
*/
printConfigInfo: boolean
/**
* print rules
*/
printRule: boolean
/**
* print themes
*/
printThemes: boolean
/**
* show page files' class names
*/
showPageClassNames: boolean
/**
* show page class attributes
*/
showPageClassAttribute: boolean
/**
* show css files' style names
*/
showCssStyleNames: boolean
/**
* show the beginning of page task
*/
showPageTaskBegin: boolean
/**
* show the result of page task
*/
showPageTaskResult: boolean
/**
* show style task result
*/
showStyleTaskResult: boolean
/**
* show batch task step
*/
showTaskStep: boolean
/**
* show the generated content
*/
showFileContent: boolean
}

/**
* watch option
*/
export interface WatchOption {
/**
* refresh duration after the file changes
*/
delay: number;
/**
* extensions of files which could update global css file
*/
fileTypes: string[];
/**
* refresh order count
*/
refreshCount: number;
}

/**
* process option
*/
export interface ProcessOption {
/**
* promise concurrent limit
*/
promiseLimit: number;
}
1.2.2 样式规则定义
/**
* atomic style rule
*/
export interface AtomicStyleRule {
/**
* package name to manage rules
*/
package: string
/**
* describe the rule, if syntax is not normal
*/
desc?: string
/**
* class name syntax, could use vars, [U]-unit, [C]-color, [N]-number,
* [A]-alpha number, with decimal point as prefix is the true value
*/
syntax: string
/**
* classes name which in global css file and compose to the new style
*/
compose?: string[]
/**
* style declaration for class names, required if compose is undefined or empty
*/
expr?: string,
/**
* dependencies of style names
*/
dependencies?: string[],
/**
* units includes by expr, effected on running
*/
units?: string[],
/**
* colors includes by expr, effected on running
*/
colors?: string[],
/**
* regEx for dynamic expr, which includes [, effected on running
*/
syntaxRegex?: RegExp
}

1.3 并发处理

为了更充分的使用计算机的性能,这里使用了并发处理:

(1)使用 Promise.all 发起了全局样式文件、组件文件、页面文件解析任务。

(2)对于组件文件和页面文件,在页面文件较多的情况下,分别执行了并发(5个,默认值)处理。

可以将处理时间从 1秒减少到200ms左右(个人计算机实测)。

1.4 复用处理 

样式文件目前采用全局生成策略,将各个页面的解析结果进行缓存处理。

缓存保存在 WxRunningSetting 的 tempData 属性中,结构如下。

/**
* temp data
*/
interface TempData {
/**
* effected rule setting cache
*/
ruleSetting?: StyleRuleSetting;
/**
* effected theme map cache
*/
themeMap?: ThemeMap;
/**
* page class names dictionary
*/
pageClassNameMap: { [index: string]: string[] };
/**
* global style names
*/
globalClassNames: string[]
/**
* global style names
*/
tempGlobalClassNames: string[]
}

 在编写单个文件时,伴随编写进行编译,延时200ms(默认值)进行编译,编译可以在3-20ms(个人计算机实测)内完成。


2 运行结果

本文示例中,本地执行分为四个部分,日志如下:

❯ deno run --allow-read --allow-write --watch worker.ts D:\xxx\yyy\miniprogram\
Watcher Process started.
2022-10-23 11:02:10.529 ==========================================================
2022-10-23 11:02:10.531 wxmp-atomic-css: wechat mini program atomic css kit
2022-10-23 11:02:10.531 ==========================================================
2022-10-23 11:02:10.531 starting wxmp-atomic-css
2022-10-23 11:02:10.534 [task] working directory found for app.wxss at D:\repo\ryl-wxmp\miniprogram\
2022-10-23 11:02:10.542 [task] read 15 themes
2022-10-23 11:02:10.545 [task] read 144 rules
2022-10-23 11:02:10.545 [task] start auto generation after started
2022-10-23 11:02:10.576 [task] parse global styles names, found [1] in [font.wxss]
2022-10-23 11:02:10.578 [task] parse global styles names, found [6] in [app.wxss]
2022-10-23 11:02:10.580 [task] read wechat mini program pages from config file, found [34] pages
2022-10-23 11:02:10.580 [task] [parsePageClassNames] begin 34 tasks
2022-10-23 11:02:10.680 [task] [parsePageClassNames] finish 34 tasks
2022-10-23 11:02:10.688 [task] [parseComponentClassNames] begin 11 tasks
2022-10-23 11:02:10.709 [task] [parseComponentClassNames] finish 11 tasks
2022-10-23 11:02:10.710 [data] total found [7] global style names
2022-10-23 11:02:10.710 [data] total found [166] class names from pages
2022-10-23 11:02:10.710 [data] total found [100] class names from components
2022-10-23 11:02:10.712 [data] [4] class names to remove, [tip-blue,tip-green,tip-red,tip-yellow]
2022-10-23 11:02:10.712 [data] new task for generate [190] class names = [-a,active-bg,active-text-day,active-text-week,ai-center,ai-end,ai-start,bg-black,bg-black-a50,bg-blue-1,bg-blue-6,bg-gray-1,bg-gray-2,bg-gray-3,bg-gray-4,bg-gray-5,bg-gray-7,bg-green-7,bg-orange-3-a10,bg-orange-6,bg-orange-6-a30,b
g-primary,bg-primary-a10,bg-red-3-a10,bg-red-7,bg-red-7-a10,bg-white,border,border-2,border-black,border-bottom,border-gray-10,border-green-6,border-orange-6,border-orange-6-a30,border-primary,border-red-6,border-top,border-transparent,c1,c2,c3,currency,day,delay-1000,disable-text,duration-1000,ease-in,
flex-cc,flex-col,flex-col-r,flex-lc,flex-row,g-,gap-10,gap-20,gap-32,gap-4,grid-2c,grid-3c,grid-5c,grid-7c,h-120,h-150,h-20,h-36,h-64,h-80,h-96,jc-around,jc-between,jc-center,jc-end,jc-start,m-32,mb-10,mb-20,mb-32,mh-120,mh-150,mh-200,ml-10,ml-20,ml-32,ml-4,mr-20,mr-32,mr-4,mt-10,mt-20,mt-32,mt-4,mx-20,
mx-32,my-10,my-20,normal-bg,normal-text,number,opacity-60,opacity-70,p-10,p-20,p-32,pb-10,pb-20,pb-32,pb-4,pl-10,pl-20,pl-32,pos-abs,pos-rel,pos-tr,pr-20,pr-32,pr-4,pt-10,pt-20,pt-32,px-10,px-20,px-32,px-37,px-4,px-80,py-10,py-20,py-4,py-90,rotate-180,round,round-10,round-10m,round-20,round-36,round-4,r
ound-8,round-bl-10,round-br-10,round-tl-10,round-tr-10,shadow,text-20,text-24,text-28,text-30,text-32,text-36,text-48,text-black,text-blue-6,text-bold,text-break,text-center,text-gray-6,text-gray-7,text-gray-9,text-green-6,text-line-p150,text-normal,text-orange-6,text-primary,text-red-6,text-right,text-
white,theme,themes,type,userinfo,userinfo-avatar,userinfo-nickname,w-120,w-96,w-full,wh-144,wh-256,wh-36,wh-48,wh-64,wh-72,wh-96,wh-full,wh-screen,wrap,z-,z-1,z-2,z-3,z-4]
2022-10-23 11:02:10.713 [data] new task to create [190] class names
2022-10-23 11:02:10.730 [warnings] 21 class names not matched, -a,active-bg,active-text-day,active-text-week,currency,day,disable-text,g-,normal-bg,normal-text,number,pos-tr,round-10m,theme,themes,type,userinfo,userinfo-avatar,userinfo-nickname,wrap,z-
2022-10-23 11:02:10.731 [data] new task to create [29] unit vars, [0,1,10,12,120,144,150,2,20,200,24,256,28,3,30,32,36,37,4,48,6,64,72,8,80,90,96,d5,p100]
2022-10-23 11:02:10.731 [data] new task to create [26] color vars, [black-1,black-1-50,blue-1,blue-6,gray-1,gray-10,gray-2,gray-3,gray-4,gray-5,gray-5-a05,gray-6,gray-7,gray-9,green-6,green-7,orange-3-10,orange-6,orange-6-30,primary-1,primary-1-10,red-3-10,red-6,red-7,red-7-10,white-1]
2022-10-23 11:02:10.731 [task] begin to write output file
2022-10-23 11:02:10.734 [task] save 1756 chars to var.wxss
2022-10-23 11:02:10.736 [task] save 10754 chars to mini.wxss
2022-10-23 11:02:10.736 [data] job done, cost 191 ms, result = 0
2022-10-23 11:02:10.736 service ready, Press Ctrl-C to exit



2022-10-23 11:02:17.339 [file changed] *D:\xxx\yyy\miniprogram\pages\index\course.wxml
2022-10-23 11:02:17.341 [task] page [D:\xxx\yyy\miniprogram\pages\index\course.wxml] - [wh-screen,z-1,flex-col,py-20,c1,mh-200,text-32,text-black,px-32,px-37,flex-row,ai-center,jc-center,h-96,wh-64,text-30,text-orange-6,mx-20,my-20,shadow,round-20,gap-32,duration-1000,delay-1000,ease-in,my-10,text
-36,text-bold,text-center,wh-144,text-primary,bg-gray-2,round-10,text-gray-7,wh-256,h-20,mt-32,bg-orange-3-a10,jc-around,wh-72,h-36,bg-red-3-a10,safe-bottom]
2022-10-23 11:02:17.342 [data] new task to create [193] class names
2022-10-23 11:02:17.346 [warnings] 23 class names not matched, -a,active-bg,active-text-day,active-text-week,currency,day,disable-text,ff-n,g-,normal-bg,normal-text,number,pop-full,pos-tr,round-10m,theme,themes,type,userinfo,userinfo-avatar,userinfo-nickname,wrap,z-
2022-10-23 11:02:17.347 [data] new task to create [29] unit vars, [0,1,10,12,120,144,150,2,20,200,24,256,28,3,30,32,36,37,4,48,6,64,72,8,80,90,96,d5,p100]
2022-10-23 11:02:17.347 [data] new task to create [26] color vars, [black-1,black-1-50,blue-1,blue-6,gray-1,gray-10,gray-2,gray-3,gray-4,gray-5,gray-5-a05,gray-6,gray-7,gray-9,green-6,green-7,orange-3-10,orange-6,orange-6-30,primary-1,primary-1-10,red-3-10,red-6,red-7,red-7-10,white-1]
2022-10-23 11:02:17.347 [task] begin to write output file
2022-10-23 11:02:17.349 [task] save 1756 chars to var.wxss
2022-10-23 11:02:17.350 [task] save 10819 chars to mini.wxss
2022-10-23 11:02:17.350 [data] job done, cost 11 ms, result = 0
2022-10-23 11:02:17.351 [task] wxmp-atomic-css refresh 1x



2022-10-23 11:02:24.870 [file changed] *D:\xxx\yyy\miniprogram\pages\index\course.wxml
2022-10-23 11:02:24.873 [task] page [D:\xxx\yyy\miniprogram\pages\index\course.wxml] - [wh-screen,z-1,flex-col,py-20,c1,mh-200,text-32,text-black,px-32,px-37,flex-row,ai-center,jc-center,h-96,wh-64,text-30,text-orange-6,text-36,mx-20,my-20,shadow,round-20,gap-32,duration-1000,delay-1000,ease-in,my
-10,text-bold,text-center,wh-144,text-primary,bg-gray-2,round-10,text-gray-7,wh-256,h-20,mt-32,bg-orange-3-a10,jc-around,wh-72,h-36,bg-red-3-a10,safe-bottom]
2022-10-23 11:02:24.874 [data] job terminated, cost 3 ms { code: 1, msg: "page class names already generated" }
2022-10-23 11:02:24.876 [task] wxmp-atomic-css refresh 2x



2022-10-23 11:02:41.979 [file changed] *D:\xxx\yyy\miniprogram\pages\index\course.wxml
2022-10-23 11:02:41.985 [task] page [D:\xxx\yyy\miniprogram\pages\index\course.wxml] - [wh-screen,z-1,flex-col,py-20,c1,mh-200,text-32,text-black,px-32,px-37,flex-row,ai-center,jc-center,h-96,wh-64,text-30,text-orange-6,text-36,text-red-5,mx-20,my-20,shadow,round-20,gap-32,duration-1000,delay-1000
,ease-in,my-10,text-bold,text-center,wh-144,text-primary,bg-gray-2,round-10,text-gray-7,wh-256,h-20,mt-32,bg-orange-3-a10,jc-around,wh-72,h-36,bg-red-3-a10,safe-bottom]
2022-10-23 11:02:41.986 [data] new task to create [194] class names
2022-10-23 11:02:41.990 [warnings] 23 class names not matched, -a,active-bg,active-text-day,active-text-week,currency,day,disable-text,ff-n,g-,normal-bg,normal-text,number,pop-full,pos-tr,round-10m,theme,themes,type,userinfo,userinfo-avatar,userinfo-nickname,wrap,z-
2022-10-23 11:02:41.991 [data] new task to create [29] unit vars, [0,1,10,12,120,144,150,2,20,200,24,256,28,3,30,32,36,37,4,48,6,64,72,8,80,90,96,d5,p100]
2022-10-23 11:02:41.991 [data] new task to create [27] color vars, [black-1,black-1-50,blue-1,blue-6,gray-1,gray-10,gray-2,gray-3,gray-4,gray-5,gray-5-a05,gray-6,gray-7,gray-9,green-6,green-7,orange-3-10,orange-6,orange-6-30,primary-1,primary-1-10,red-3-10,red-5,red-6,red-7,red-7-10,white-1]
2022-10-23 11:02:41.991 [task] begin to write output file
2022-10-23 11:02:41.994 [task] save 1791 chars to var.wxss
2022-10-23 11:02:41.996 [task] save 10865 chars to mini.wxss
2022-10-23 11:02:41.996 [data] job done, cost 17 ms, result = 0
2022-10-23 11:02:41.996 [task] wxmp-atomic-css refresh 3x

为了方便阅读,上面的日志人为添加空白行进行了分割。

(1)启动后的全量生成,编译耗时 191 ms。

(2)增加了几个样式,编译耗时 11 ms。

(3)编写了一些代码,不涉及到样式,编译耗时 3 ms。

(4)编写了一些复杂代码,新增了一个样式,编译耗时 17 ms。


3 小结

使用体验良好的工具,工程化的处理会产生一半以上的工作量。为了追求实时生成体验,追求函数范式,本文说明了使用缓存,使用 promise 并发和顺序执行优化工具编译的过程。

后续展望:在运行的过程中,生成的样式均为全局样式,存在部分样式使用率不高的情况。用户可以手动在页面文件中定义样式,避免自动生成为全局样式。这个部分实际上可以根据用户使用情况让工具进行自动处理,存在优化的空间。

标签:11,10,23,样式,微信,02,原子,gray,text
From: https://blog.51cto.com/u_13556371/5787255

相关文章