webpack 代码拆分,css拆分,webpack分析打包优化
nuxt build --analyze # webpack 分析
// nuxt.config.js
export default {
build: {
// extractCSS: true,
// or
extractCSS: { // 提取css
ignoreOrder: true
}
extend(config, { isClient }) {
// 设置这个在 nuxt start 时有可能报错
config.optimization.splitChunks.maxInitialRequests = 20; // for HTTP2
config.optimization.splitChunks.maxAsyncRequests = 20; // for HTTP2
if (isClient) {
config.optimization.splitChunks.maxSize = 200000 // 代码拆分
}
}
}
}
vue-lazyload
https://www.npmjs.com/package/vue-lazyload
http2
window.chrome.loadTimes()输出的connectionInfo 和 npnNegotiatedProtocol 是h2就说明使用的是http2
commitLoadTime: (...)
connectionInfo: "h2"
finishDocumentLoadTime: (...)
finishLoadTime: (...)
firstPaintAfterLoadTime: (...)
firstPaintTime: (...)
navigationType: (...)
npnNegotiatedProtocol: "h2"
no-ssr结构拆分
<template>
<div>
<!-- 顶部banner -->
<banner :banner="banner" />
<!-- 非首屏所需结构,通过no-ssr组件达到不在服务端渲染目的-->
<no-ssr> <!-- 商品列表 -->
<prod-list :listData="listData"/>
</no-ssr>
</div>
</template>
小图片转换Img
// nuxt.config.js
config.module.rules.forEach(item => {
if (item.use && item.use.length) {
item.use.forEach(temp => {
if (temp.loader === 'url-loader') {
// 将小图片转成base64,减少请求数
temp.options.limit = 7000
}
})
}
})
Nuxt Prefetch 优化
// 默认是带了prefetch功能的,但是注意 2.9.x 版本,引入时生成的js并不是prefetch的,会影响onload ,注意不需要 预加载,可以关掉
// 默认的 prefetch 会生成 vendors.pages文件夹,可能会提前加载不需要的内容
<NuxtLink to="/about" no-prefetch>About page not pre-fetched</NuxtLink>
// nuxt.config.js 全局禁用预取
export default {
router: {
prefetchLinks: false
}
}
Nuxt 接口级别缓存,组件基本缓存,页面级缓存
接口级别缓存 适用于与 用户信息 无关的内容
const LRU = require('lru-cache')
let cachePage = new LRU({
max: 100, // 缓存队列长度
maxAge: 1000 * 60 // 缓存1分钟
})
import LRU from 'lru-cache'
const CACHED = new LRU({
max: 100, // 缓存队列长度
maxAge: 1000 * 60 // 缓存时间
})
export default {
async asyncData({ app, query }) {
try {
let banner, footer
if (CACHED.has('baseData')) {
// 存在缓存,使用缓存数据
let data = CACHED.get('baseData')
data = JSON.parse(data)
banner = data.banner
footer = data.footer
} else {
// 获取页面顶部轮播图信息
const getBanner = () => {
return app.$axios.$get('zz/zy/banner')
} // 获取底部配置信息
const getFooter = () => {
return app.$axios.$get('zz/zy/footer', {
params: {
smark: query.smark
}
})
}
[banner, footer] = await Promise.all([getBanner(), getFooter()])
// 将数据写入缓存
CACHED.set('baseData', JSON.stringify({ banner: banner, footer: footer}))
}
return {mods: mods, footer: footer}
} catch (e) {
console.log('interface timeout or format error => ', e)
return {}
}
}
}
组件级别缓存
将渲染后的组件DOM结构存入缓存,定时刷新,有效期通过缓存获取组件DOM结构,减小生成DOM结构所需时间;
适用于渲染后结构不变或只有几种变换、并不影响上下文的组件。
适合缓存的最常见的组件类型是在大v-for列表中重复的组件。由于这些组件通常由数据库集合中的对象驱动,因此它们可以使用一种简单的缓存策略:使用它们的唯一 id 加上最后更新的时间戳生成它们的缓存键
serverCacheKey: props => props.item.id + '::' + props.item.last_updated
如果组件依赖于很多的全局状态,或者状态取值非常多,缓存会因频繁被设置而导致溢出,这样的组件做缓存就没有多大意义了;
另外组件缓存,只是缓存了dom结构,如created等钩子中的代码逻辑并不会被缓存,如果其中逻辑会影响上下边变更,是不会再执行的,此种组件也不适合缓存。
请注意,可缓存组件还必须定义唯一name选项。使用唯一名称,缓存键因此是针对每个组件的:您无需担心两个组件返回相同的键。
从返回的键serverCacheKey应该包含足够的信息来表示渲染结果的形状。如果渲染结果仅由props.item.id. 但是,如果具有相同 id 的项目可能会随着时间的推移而改变,或者如果渲染结果也依赖于另一个 prop,那么您需要修改您的serverCacheKey实现以将这些其他变量考虑在内。
返回一个常量会导致组件总是被缓存,这对于纯静态组件是好的。
https://ssr.vuejs.org/guide/caching.html#component-level-caching
const LRU = require('lru-cache')
module.exports = {
render: {
bundleRenderer: {
cache: LRU({
max: 1000, // 缓存队列长度
maxAge: 1000 * 60 // 缓存1分钟
})
}
}
}
// 需要做缓存的组件
// 如何验证组件是否被缓存 查看源码,查看class="date-now" 对应的值,此时并不是每次刷新都更新,用此方法可以验证
// 此缓存不影响客户端的执行,客户端的值每次都会变
<template>
<div class="date-now">{{ Date.now() }}</div>
</template>
export default {
name: 'zzZyHome',
props: ['type'],
serverCacheKey: props => props.type
asyncData() {
// 缓存组件不影响asyncData
return {}
}
}
页面级别缓存
当整个页面与用户数据无关,依赖的数据基本不变的情况下,可以对整个页面做缓存,减小页面获取时间;
页面整体缓存前提是在使用Nuxt.js脚手架工具create-nuxt-app初始化项目时,必须选择集成服务器框架,如express、koa,只有这样才具有服务端中间件扩展的功能。
// middleware/page-cache.js
const LRU = require('lru-cache')
let cachePage = new LRU({
max: 100, // 缓存队列长度
maxAge: 1000 * 60
// 缓存1分钟
})
export default function(req, res, next) {
let url = req._parsedOriginalUrl
let pathname = url.pathname
// 通过路由判断,只有首页才进行缓存
if (['/home'].indexOf(pathname) > -1) {
const existsHtml = cachePage.get('homeData')
if (existsHtml) {
return res.end(existsHtml.html, 'utf-8')
} else {
res.original_end = res.end
// 重写res.end
res.end = function (data) {
if (res.statusCode === 200) {
// 设置缓存
cachePage.set('homeData', { html: data})
}
// 最终返回结果
res.original_end(data, 'utf-8')
}
}
}
next()
}
// nuxt.config.js
{
serverMiddleware: [
{ path: '/home', handler: '~/middleware/page-cache.js' },
]
}