webpack 代码拆分,css拆分,webpack分析打包优化
nuxt build --analyze # webpack 分析
// nuxt.config.jsexport default {build: {// extractCSS: true,// orextractCSS: { // 提取cssignoreOrder: true}extend(config, { isClient }) {// 设置这个在 nuxt start 时有可能报错config.optimization.splitChunks.maxInitialRequests = 20; // for HTTP2config.optimization.splitChunks.maxAsyncRequests = 20; // for HTTP2if (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.jsconfig.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, footerif (CACHED.has('baseData')) {// 存在缓存,使用缓存数据let data = CACHED.get('baseData')data = JSON.parse(data)banner = data.bannerfooter = 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' },
]
}
