dns-prefetch、serviceWorker、webworker、提高网页性能

1、dns-prefetch ---预解析,提高网页加载速度,使用方法如下,参考文档https://blog.csdn.net/qq_35432904/article/details/83988726

<link rel="dns-prefetch" href="https://restapi.amap.com"/> 

<link rel="dns-prefetch" href="https://webapi.amap.com"/> 

<link rel="dns-prefetch" href="https://vdata.amap.com"/>

2、webworker,插件worker-loader,当页面中有比较耗时(比如需要处理的数据多达几万条)的事件,可以将事件放到webworker中处理,这样页面就不会有卡顿甚至白屏的现象

插件worker-loader可以将js脚本注册为webworker

1) 在项目中安装插件worker-loader

npm i worker-loader -D

2) 配置worker-loader,在webpack.conf.js中的module.rules中配置以下规则:

{
  test: /\.worker\.js$/, // 以.worker.js结尾的文件将被worker-loader加载
  // use: { loader: 'worker-loader' }
  // include: [resolve('node_modules/@pa_hcz/umc-ui-pc/src/')],
  loader: 'worker-loader',
  options: {
     inline: true,
     fallback: false,
     publicPath: assetsPublicPath   // 项目的路径
   }
 }

3)在你的项目中新建a.worker.js---该文件用于生成work对象的,并且在里面处理比较耗时的事件,onmessage用于工作线程接收主线程的消息,postMessage()用于工作线程向主线程发送消息

onmessage = function (evt) {
    // 工作线程收到主线程的消息,evt是从主线程传过来的自定义数据
    var { arr, type, expand } = evt.data
    var departmentTreeIdArr
    // 根据不同的行为做相应的事件处理
    if (type === 'initData') {
        // 从接口拿到数据后,需要初始化结构
        departmentTreeIdArr = getDepts(arr, expand)
    } else if (type === 'choose') {
        // 去重
        departmentTreeIdArr = removeRepeatData(arr)
    }
    // 事件处理完之后,工作线程向主线程发送消息,返回处理后的结果
    postMessage({
        departmentTreeIdArr,
        type
    })
}

function getDepts(arr, expand) {
    // toDo something
    // egs.
    return arr
}

function removeRepeatData(arr) {
  // to do something
  // egs.
  return arr
}

4)在需要引进worker的vue文件中,引进该文件,并生成worker对象,像工作线程发送消息,并监听工作线程发送的信息

a)  比如和a.worker.js同级目录下有文件b.vue,在该文件中引进文件a.worker.js

import Woker from './a.worker.js'

b)  在mounted里面创建work对象

data: () => {
   return {
     work: null
   }
},
mounted() {
  this.work = new Woker()
}

c)  当接口返回数据之后,主线程通过postMessage向工作线程发送消息

  getDepartments(data) {
      let url = '接口路径' 
      this.$rootStore.state.loading.status = true
      this.http(url).get().then((res) => {
        // res的数据达到2万多条,所以放worker处理,要不然页面会被卡死 
        this.worker.postMessage({ 
          arr: res, 
          type: 'initData', 
          expand: this.expand 
        }) 
      }) 
    }

d)  在mounted中监听工作线程向主线程发送处理完数据之后消息

    this.worker.addEventListener('message', function (event) { 
      let {departmentTreeIdArr, type} = event.data
      if (type === 'initData') { 
        vm.dataTree = departmentTreeIdArr 
      } else if (type === 'choose') {
        vm.$emit('on-choose-more-department', departmentTreeIdArr) 
        } 
      })
    }

至此,在项目中使用web-worker的流程就说完了

注意1,如果说说在引进的npm包里面的组件有用worker,那么配置应该写成下面的形式,添加include属性

npm包不管是源码发布还是编译打包之后发布,include的路径都是下面去引

{
  test: /\.worker\.js$/, // 以.worker.js结尾的文件将被worker-loader加载
  // use: { loader: 'worker-loader' }
  include: [resolve('node_modules/@pa_hcz/umc-ui-pc/src/')],
  loader: 'worker-loader',
  options: {
     inline: true,
     fallback: false,
     publicPath: assetsPublicPath   // 项目的路径
   }
 }

开发的npm包,组件中有用worker,如果本地link包进行开发,时时看效果,那么配置的webpack不生效,可以先在项目里面把组件开发好,然后在将代码复制到npm包的项目里面,只是worker-loader的配置有点区别,如上面两个配置项

注意2,在a.worker.js文件中,不能有HTMlElment,否则会报错:大致意思是不能引进HTMLElement

比如,在使用iview中tree组件的时候,需要拿到数据之后,自定义模版,在数据中添加item.render属性,这时候有HTMLElement就会报错

解决方法:在tree组件中使用props:render

3、Navigator.serviceWorker---未完待续

猜你喜欢

转载自blog.csdn.net/tangxiujiang/article/details/110295467