webpack 代码拆分,css拆分,webpack分析打包优化

  1. nuxt build --analyze # webpack 分析
  1. // nuxt.config.js
  2. export default {
  3. build: {
  4. // extractCSS: true,
  5. // or
  6. extractCSS: { // 提取css
  7. ignoreOrder: true
  8. }
  9. extend(config, { isClient }) {
  10. // 设置这个在 nuxt start 时有可能报错
  11. config.optimization.splitChunks.maxInitialRequests = 20; // for HTTP2
  12. config.optimization.splitChunks.maxAsyncRequests = 20; // for HTTP2
  13. if (isClient) {
  14. config.optimization.splitChunks.maxSize = 200000 // 代码拆分
  15. }
  16. }
  17. }
  18. }

vue-lazyload

https://www.npmjs.com/package/vue-lazyload

http2

window.chrome.loadTimes()输出的connectionInfo 和 npnNegotiatedProtocol 是h2就说明使用的是http2

  1. commitLoadTime: (...)
  2. connectionInfo: "h2"
  3. finishDocumentLoadTime: (...)
  4. finishLoadTime: (...)
  5. firstPaintAfterLoadTime: (...)
  6. firstPaintTime: (...)
  7. navigationType: (...)
  8. npnNegotiatedProtocol: "h2"

no-ssr结构拆分

  1. <template>
  2. <div>
  3. <!-- 顶部banner -->
  4. <banner :banner="banner" />
  5. <!-- 非首屏所需结构,通过no-ssr组件达到不在服务端渲染目的-->
  6. <no-ssr> <!-- 商品列表 -->
  7. <prod-list :listData="listData"/>
  8. </no-ssr>
  9. </div>
  10. </template>

小图片转换Img

  1. // nuxt.config.js
  2. config.module.rules.forEach(item => {
  3. if (item.use && item.use.length) {
  4. item.use.forEach(temp => {
  5. if (temp.loader === 'url-loader') {
  6. // 将小图片转成base64,减少请求数
  7. temp.options.limit = 7000
  8. }
  9. })
  10. }
  11. })

Nuxt Prefetch 优化

  1. // 默认是带了prefetch功能的,但是注意 2.9.x 版本,引入时生成的js并不是prefetch的,会影响onload ,注意不需要 预加载,可以关掉
  2. // 默认的 prefetch 会生成 vendors.pages文件夹,可能会提前加载不需要的内容
  3. <NuxtLink to="/about" no-prefetch>About page not pre-fetched</NuxtLink>
  4. // nuxt.config.js 全局禁用预取
  5. export default {
  6. router: {
  7. prefetchLinks: false
  8. }
  9. }

Nuxt 接口级别缓存,组件基本缓存,页面级缓存

接口级别缓存 适用于与 用户信息 无关的内容

  1. const LRU = require('lru-cache')
  2. let cachePage = new LRU({
  3. max: 100, // 缓存队列长度
  4. maxAge: 1000 * 60 // 缓存1分钟
  5. })
  6. import LRU from 'lru-cache'
  7. const CACHED = new LRU({
  8. max: 100, // 缓存队列长度
  9. maxAge: 1000 * 60 // 缓存时间
  10. })
  11. export default {
  12. async asyncData({ app, query }) {
  13. try {
  14. let banner, footer
  15. if (CACHED.has('baseData')) {
  16. // 存在缓存,使用缓存数据
  17. let data = CACHED.get('baseData')
  18. data = JSON.parse(data)
  19. banner = data.banner
  20. footer = data.footer
  21. } else {
  22. // 获取页面顶部轮播图信息
  23. const getBanner = () => {
  24. return app.$axios.$get('zz/zy/banner')
  25. } // 获取底部配置信息
  26. const getFooter = () => {
  27. return app.$axios.$get('zz/zy/footer', {
  28. params: {
  29. smark: query.smark
  30. }
  31. })
  32. }
  33. [banner, footer] = await Promise.all([getBanner(), getFooter()])
  34. // 将数据写入缓存
  35. CACHED.set('baseData', JSON.stringify({ banner: banner, footer: footer}))
  36. }
  37. return {mods: mods, footer: footer}
  38. } catch (e) {
  39. console.log('interface timeout or format error => ', e)
  40. return {}
  41. }
  42. }
  43. }

组件级别缓存

  1. 将渲染后的组件DOM结构存入缓存,定时刷新,有效期通过缓存获取组件DOM结构,减小生成DOM结构所需时间;
  2. 适用于渲染后结构不变或只有几种变换、并不影响上下文的组件。
  3. 适合缓存的最常见的组件类型是在大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' },
  ]
}