配个人密钥:
命令:
ssh-keygen -t rsa -C ""
cat ~/.ssh/id_rsa.pub
npm config get registry 查看当前源
npm config setregistryhttps://registry.npm.taobao.org切换淘宝源
如果安装途中遇到ejs的报错,需要在node-modules —>
ejs-compiled-loader —> package.json —> dependencies 下,将GitHub的地址改
husky@0.15.0-rc.13
Node_sass设置内网下载地址
npm config set sass_binary_site 地址
npm config set sass_binary_site null
npm i node-sass@4.9.3 --verbose
有状态的对象: mixin
高阶函数: render-props
跨组件的逻辑复用: hooks
function-based API
在多个组件中清晰的复用逻辑
grid search
Object.defineProperty
Const obj = {};
Let realValue = 123;
onFooChanged(()=> {
Console.log(obj,foo);
}); —> 订阅者
Let currentEffect;
Function onFooChanged((effect)=> {
currentEffect = effect;
Effect();
currentEffect = null;
});
Const subs = [];
Object.defineProperty(obj, ‘foo’,{
Enumerable: false;
Configurable: false;
get(){
// trackDependency();
if (currentEffect){
fooSubs.push(currentEffect);}
Return realValue},
set(newValue){
realValue = newValue;
// notifyChange();
Subs.forEach(effect = >
effect());},
);
Const proxy = new Proxy(obj,{
get() {};
set() {};
deleteProperty() {};
has() {};
});
Render machism
Template
Complied into render function
returns Visual dom
Actual dom
Render function
Returns new visual Dom
Diffed against old virtual Dom Domupdates
Applied to actual Dom
Actual dom
[obj,HTMLDivElement];
expensive browser native object
Visual dom (创建对象,再遍历)
[tag:
div,data: {attracts: {},…},children: []];
Cheep javascript object
vdom 最大瓶颈: 垃圾回收
Function render(){}
性能
web性能
根据URL缓存
304 没有更新,只有请求头,速度快
app webview优化思路
提前初始化webview
客户端代理数据请求
js异步加载async/defer
将全局变量存储在局部变量中:因为全局变量总是存在于执行环境作用域链的最末端
尽量避免使用with,try-catch,eval等动态作用域语法,因为javascript引擎无法通过静态分析的方法进行优化
使用对象字面量代替对象
使用h5
web workers 来允许多线程工作
新特性beacon,不堵塞队列的异步数据发送
For in 循环性能最差
forEach比数组循环慢
当判断多余2个时,使用switch,否则用if-else
在JavaScript中,switch使用全等操作符
把最可能出现的条件放在首位
把递归算法该用迭代算法实现
缓存:避免重复性工作,手动实现缓存
dom操作相关优化
批量修改dom时,使用document fragment
事件委托进行时间绑定
使用原生选择器API: querySeletorAll()和querySeletor()
减少访问dom的次数,把运算尽量在js层面作处理,譬如virtualDOM
使用children代替childNodes
用element.cloneNode()代替document.createElement(),稍快一点
避免不必要重绘重排
css优化
能用css3实现的不要用图片
避免通配符,删除多余修饰语
避免使用后代选择其,特别是那些制定多余祖先的,css嵌套不宜超过4层
使用class选择其代替后代选择器
选择器解析是从右向左的,因此避免使用标签选择器,特别是div,否则会先查找该页面所有的div,是十分消耗性能的
打包慢的原因
业务模块多
多个第三方依赖包
依赖包内容太多
webpack版本低
UglifyJS单线程打包
HappyPack,多个任务
ParalleUglifyPlugin
New ParalleUglifyPlugin({
UglifyJS:{},
Test:/.js&/g,
Include:[],
Exclude:[],
cacheDir:’’,
worderCount:‘’, 进程数
sourceMap: false,
}) 分发的作用,执行的是UglifyJS
cacheDirectory
用noParse跳过文件解析
用resolve减短搜索目录和路径
用fast-sass-loader,fast-css-loader
webpack.base.conf.js
```js
'use strict'
// 使用happypack
const HappyPack = require('happypack');
const os = require('os');
const path = require('path')
const utils = require('./utils')
const config = require('../config')
const vueLoaderConfig = require('./vue-loader.conf')
const webpack = require('webpack')
const vuxLoader = require('vux-loader')
const happyThreadPool = HappyPack.ThreadPool({
size: os.cpus().length,
});
function resolve (dir) {
return path.join(__dirname, '..', dir)
}
const createLintingRule = () => ({
test: /\.(js|vue)$/,
loader: 'eslint-loader',
enforce: 'pre',
include: [resolve('src'), resolve('test')],
options: {
formatter: require('eslint-friendly-formatter'),
emitWarning: !config.dev.showEslintErrorsInOverlay
}
})
var webpackConfig = {
context: path.resolve(__dirname, '../'),
entry: utils.getEntries('./src/module', 'main.js'),
output: {
path: config.build.assetsRoot,
filename: '[name].js',
publicPath: process.env.NODE_ENV === 'production'
? config.build.assetsPublicPath
: config.dev.assetsPublicPath
},
resolve: {
extensions: ['.js', '.vue', '.json'],
alias: {
vue$: 'vue/dist/vue.esm.js',
'@': resolve('src'),
src: path.resolve(__dirname, '../src'),
assets: path.resolve(__dirname, '../src/assets'),
config: path.resolve(__dirname, '../src/config'),
api: path.resolve(__dirname, '../src/api'),
components: path.resolve(__dirname, '../src/components'),
views: path.resolve(__dirname, '../src/views'),
store: path.resolve(__dirname, '../src/store'),
module: path.resolve(__dirname, '../src/module'),
lib: path.resolve(__dirname, '../src/lib'),
util: path.resolve(__dirname, '../src/util'),
service: path.resolve(__dirname, '../src/service'),
},
},
module: {
rules: [
...(config.dev.useEslint ? [createLintingRule()] : []),
{
test: /\.vue$/,
loader: 'vue-loader',
options: vueLoaderConfig
},
{
test: /\.js$/,
loader: 'babel-loader?cacheDirectory=true',
include: [resolve('src'), resolve('node_modules/webpack-dev-server/client'), resolve('node_modules/neo/src')],
},
{
test: /\.json$/,
loader: 'json-loader',
},
{
test: /\.ejs$/,
loader: 'ejs-compiled-loader',
include: [resolve('src'), resolve('test')],
exclude: /node_modules/
},
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
use: [
{
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('img/[name].[hash:7].[ext]')
}
}
]
},
{
test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('media/[name].[hash:7].[ext]')
}
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
}
}
]
},
node: {
// prevent webpack from injecting useless setImmediate polyfill because Vue
// source contains it (although only uses it if it's native).
setImmediate: false,
// prevent webpack from injecting mocks to Node native modules
// that does not make sense for the client
dgram: 'empty',
fs: 'empty',
net: 'empty',
tls: 'empty',
child_process: 'empty'
},
plugins:[
new webpack.DllReferencePlugin({
context: __dirname,
manifest: require(`../${config.dll.path}/libs-mainfest.json`) // 指向生成的manifest.json
}),
new HappyPack({
// 用id来标识 happypack处理类文件
id: 'happyBabel',
// 如何处理 用法和loader 的配置一样
loaders: ['babel-loader?cacheDirectory=true'],
// loaders: ['babel-loader'],
// 共享进程池
threadPool: happyThreadPool,
// 允许 HappyPack 输出日志
verbose: true,
}),
]
}
module.exports = vuxLoader.merge(webpackConfig, {
plugins: [
{
name: 'vux-ui'
},
{
name: 'duplicate-style'
}
]
});
// module.exports = vuxLoader.merge(webpackConfig, {
// plugins: ['vux-ui', 'duplicate-style']
// })
```