目前咱们h5主要是面向两个app,V(简称)以及W(简称)(都只是安卓端),基本都是基于这两个app的webview作一些活动 W(简称) 面向最低的Android版本是4.1,V(简称) 面向最低的Android版本是4.0。低版本的手机js环境比较老,所以一些咱们要针对低版本的手机作一些polyfill补充(例如babel-polyfill,react-intl的polyfill => intl,vw/vh 等等)。php
咱们的polyfill主要是针对在4.2以及4.2如下的手机.css
这是 V(简称) 的手机型号用户占比: 4.2以及如下的手机uv大概100万,占比大概1.72%
html
这是 W(简称) 的手机型号用户占比: 4.2以及如下的活跃设备数量大概350万,Dau大概120万,4.2如下的设备大概1.5万,占比不到1%
react
目前咱们的方法是统一引入这些polyfill!
这是咱们某个活动页面的build出来的结果,用BundleAnalyzerPlugin查看能够看到,整个活动应用300多kb,而 code-js(babel-polyfill) + react-intl/lib 就已经占了200多kb! 即便gzip以后传输也得66kb。
webpack
由于目前咱们的h5主要是面对于app的webview,app提供给咱们 jsBridge 让咱们拿到手机的版本信息。
咱们没有必要直接统一引入babel-polyfill,由于只有一小部分的用户须要,吸取阿里巴巴的babel-polify动态接入方案,它们提供了对应的polyfill cdn.git
//polyfill.alicdn.com/polyfill.min.js?features=default,es2017,es6,fetch,RegeneratorRuntime
复制代码
而咱们能够在拿到手机的版本后,判断低于4.2及如下的版本,才引入cdn作兼容处理。es6
与babel-polyfill相似,react-intl 须要给没有内嵌intl的手机引入intl包,咱们能够判断window.Intl对象是否存在,不存在就动态下载这个包而且引入(要考虑阻塞渲染的状况)。github
import * as React from 'react';
import request from "request";
import Spinner from "@/component/welike_spinner/welike_spinner"
import { IntlProvider } from "react-intl";
interface Props {
messages: Object;
children: React.ReactNode;
}
/**
* 多语言组件,由于某些浏览器没有内嵌intl,因此会报错,
* 这时候须要动态下载polyfill,避免了不须要intl的用户的冗余加载
*/
const INTL_CDN = '//cdn.polyfill.io/v2/polyfill.js?features=Intl.~locale.en'
export default React.memo<Props>(({ messages, children }) => {
//是否原本就有intl
const hasIntl = !!window.Intl;
const [loading, setLoadingState] = React.useState(!hasIntl);
//若是没有,就去下载
if (!hasIntl) {
request.loadScript(INTL_CDN).then(() => {
//下载完才真正的展示UI
setLoadingState(false);
}).catch(err => {
console.log(err);
})
}
return !loading ? <IntlProvider key={'en'} locale={'en'} messages={messages}>
{children}
</IntlProvider> : <div style={{ position: 'absolute', top: '0', left: '0', width: '100%', height: '100%' }}>
<div style={{
position: 'absolute',
left: '50%',
top: '50%',
transform: 'translate(-50%, -50%)'
}} >
<Spinner />
</div>
</div>
})
复制代码
能够看到,改为动态加载后,少了快40kb的资源!web
不仅是vw,vh. 还有其余的一些css属性也要作兼容,这个得一步步地去测试以及优化了.npm
因为随着咱们项目愈来愈大愈来愈多,咱们须要引入的polyfill的场景以及条件都愈来愈多。
参考咱们的设备占比数据,其实4.2如下的设备占比比较小,因此咱们开发的时候须要取决成本和人力以及收益去判断是否必要去作这些兼容性,若是有些项目不须要兼容,有些项目须要,咱们能够在webpack的entry统一配置是否须要兼容的字段,不须要兼容的,咱们直接默认给一个相似提示更新的优雅降级操做便可。