经过10多天的努力修改UniApp与新增Webpack插件,终于实现ES6语法的JS异步化、Vue组件异步化。
用法如下:
// pkg-b/b.js
const myFunc = async () => {
const { yourFunc } = await import('@/pkg-a/a.js');
}
// pkg-d/d.vue
// Vue组件经过特殊处理,不需要 import(). 缺点是不兼容h5动态import,后续有空再优化.
import YourComp from '@/pkg-c/c.vue';
export default {
components: {
YourComp
}
}
继续阅读→
最近使用Create React App创建一个APP,使用react-app-polyfill/stable
完成Polyfill,但是,发现string.replaceAll()函数一直没有polyfill。打开core-js/stable/index.js,发现已经包含了require('../modules/es.string.replace-all')。第一次遇到这种情况,相对懵逼。
经过一番的查阅,最后在babel官网看到一条消息(https://babeljs.io/docs/en/babel-preset-env#corejs):
By default, only polyfills for stable ECMAScript features are injected: if you want to polyfill proposals, you have three different options:
* when using useBuiltIns: "entry", you can directly import a proposal polyfill: import "core-js/proposals/string-replace-all".
继续阅读→
使用Nginx搭建前端静态资源服务时,有时想在服务端收集一些前端的严重错误。如果不想搭建或引用其它服务来处理上报的错误日志,可以将简要的错误信息放到HTTP Header中,然后使用Nginx的 $http_xxx
变量打印到 access_log 中。在没有新增其它Nginx模块时,Nginx是无法直接访问HTTP Body中的内容,但是Header中内容可以直接访问。
Nginx配置:
log_format reportError escape=none '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" '
'"$http_fe_href" "$http_fe_error"';
server {
location = /api/reportError {
# Methods Limit
limit_except POST {
deny all;
}
expires epoch;
### Log the error
access_log /var/log/nginx/access.log reportError;
return 200;
}
}
继续阅读→
这几天,从react-app-rewired切换到CRACO, 发现在重写 webpack 配置函数中也需要相似的 overrides 函数。于是写了一个简单的:
const overrides =
(...funcArray) =>
(webpackConfig, { env, paths }) =>
funcArray.reduce((config, func) => func(config, { env, paths }), webpackConfig);
继续阅读→
目前,在低版本的Android模拟器中,比较稳定的 vConsole 版本有:3.3.4 与 1.0.x。
vConsole依赖MutationObserver,在Android 4.4及以上版本中不需要Polyfill。但是,在Android 4.3中,需要引入MutationObserver Polyfill,勉强可以打开vConsole,如下:
<link href="https://cdn.bootcdn.net/ajax/libs/normalize/8.0.1/normalize.min.css" rel="stylesheet">
<script crossorigin="anonymous" src="https://polyfill.io/v3/polyfill.min.js?version=3.46.0&features=default%2Ces6%2Ces7%2CMutationObserver"></script>
总的来说,Android 4.3 与 4.4 浏览器之间的差异还是比较大,见 Can I use 。
继续阅读→
前段时间,我们开发一款toC的小收据,选择微信小程序插件的方式进行开发。起初的目的是避免主程序过大、容易被别的小程序集成,做新的独立APP时避免重复开发,也选择团队中大部分人熟悉的Taro + React技术栈。
但是,在产品迭代过程中,隔三差五就需要改动这个小收据插件,麻烦就出现了。要发布新功能时,需先插件提审,插件通过之后在主程序中更新插件的版本号,最后才是主程序提审、发布,发布流程漫长。
继续阅读→
去年的时候,为了提升用户首屏显示时间,我们使用React SSR。但是,前段时间用户访问量比较大,发现用户导航之后首屏很久才出来。查看链路追踪,发现后端接口的响应时间远大于平常。
SSR的目的是为了让用户更快地看到内容,但是后端接口超时就白屏很久。为了解决这个问题,在SSR请求后端接口时,也启动一个超时Promise。如果超时先返回,立刻给用户返回CSR HTML模板,确保用户尽快能够看得界面。还没有数据的Loading界面,总比一直白屏好。
继续阅读→
以前没有真正学过Android或iOS客户端开发,只使用React开发过H5页面,但是H5页面的性能远比不上Native,即使使用React Native也达不到60 FPS。
刚好Flutter可以实现一套代码在Android与iOS上运行,性能是最接近Native。于是参考微信的布局,使用Flutter实现一个Demo:主屏4个页面、一个子页面、网络请求。
继续阅读→
这段时间使用Flutter写一个移动客户端,也学习一下Dart语言。Dart语言也是类C高级编程语言,在熟悉C++或Java的基础上,非常容易上手。
Dart也可以写服务端程序,于是写一个小小的后端服务给移动端使用。虽然其性能比不上GoLang、生态系统不及NodeJS,自己学习语法时玩玩也不错。
继续阅读→
为了提升用户体验,前端首屏使用NodeJS SSR。为了容易观测多个环境NodeJS层的网络调用链与性能,我们加入了Jaeger链路追踪,这也是微服务开发中常用的手段。
通过Jaeger UI观察,我们很容易发现首屏SSR与API转发有以下问题:
- 多段接口依次执行,有先后次序依赖,没有发挥并发请求的优势。
- 未区分用户类型,有多余的网络请求。
- 转发的API请求,也请求多余的用户信息等。
如果使用以前打日志的方式,缺少可视化的分析手段,定位问题的周期比较长。处理以上的问题之后,首屏SSR与API转发的网络性能提升50%,给后端的请求数分别减少3/8与3/4。在并发量比较大的情况下,可以很大程度上减轻服务器的压力。
目前,用户量比较少,在云上后端接口返回在50ms时,首屏SSR可以在100ms内处理完成(不算用户到服务器的网络延时)。这也是我目前性能优化的极限了。
继续阅读→