Skip to content

经验之谈

H5页面如何进行首屏优化

路由懒加载

  • 适用于SPA(不适用MPA)
  • 路由拆分,优先保证首页加载

服务端渲染 SSR

  • 传统的前后端分离(SPA)渲染页面的过程复杂
  • SSR 渲染页面过程简单
  • 如果是纯 H5 页面,SSR 是性能优化的终极方案

APP 预取

  • 如果 H5 在 APP WebView 中展示,可使用APP预取

  • 用户访问列表页时,APP 预加载文章首屏内容

  • 用户进行 H5 页,直接从 APP 中获取内容,瞬间展示首屏

分页

  • 针对列表页
  • 默认只展示第一页内容
  • 上划加载更多

图片懒加载

  • 针对详情页
  • 默认只展示文本内容,然后触发图片懒加载
  • 注意:提前设置图片尺寸,尽量只重绘不重排

Hybrid

  • 提前将 HTML CSS JS下载到APP内部
  • 在APP webview中使用 file:// 协议加载页面内容
  • 再用 Ajax 获取内容并展示(也结合APP预取)

重点

  • SSR 是 H5 的终极优化方案(但成本高)
  • 移动端H5要结合APP能力去优化
  • 严格来说,Hybrid 不算 H5

后端一次性返回 10w 条数据,你该如何渲染

设计不合理

  • 后端返回 10w 条数据,本身技术方案设计就不合理
  • 主动和面试官沟通
  • 如果非要那么做,再继续寻找解决方案

浏览器能否处理 10w 条数据

  • JS 没问题
  • 渲染到 DOM 会非常卡顿

自定义中间层

  • 自定义 nodejs 中间层,获取并拆分 10w 条数据
  • 前端对接 nodejs 中间层,而不是服务端
  • 成本比较高

虚拟列表

  • 只渲染可视区域的 DOM
  • 其他隐藏区域不显示,只用 div 撑起高度
  • 随着浏览器滚动,创建和销毁 DOM

虚拟列表 - 第三方库

  • 虚拟列表实现起来非常复杂,可借用第三方库
  • Vue-virtual-scroll-list
  • React-virtualiszed

在实际工作中,对vue做过哪些优化

v-if 和 v-show

  • v-if 彻底销毁组件
  • v-show 使用 css 隐藏组件
  • 大部分情况下使用 v-if 更好,不要过度优化

使用 computed 缓存

js
data() {
    return {
        msgList: [...] // 消息列表
    }
},
computed: {
    // 未读消息的数量
    unreadCount() {
        return this.msgList.filter(m => m.read === false).length
    }
}

keep-alive 缓存组件

  • 频繁切换的组件,如 tabs
  • 不要乱用,缓存太多会占用内存,且不好 debug

异步组件

  • 针对体积较大的组件,如编辑器、复杂表格等
  • 拆包,需要时异步加载,不需要时不加载
  • 减少主包的体积,首页会加载更快
vue
<script>
import {defineAsyncComponent} from 'vue'
export default{
    name: 'AsyncComponent'
    components: {
        Child: defineAsyncComponent(() => import('path'))
    }
}
</script>

路由懒加载

项目比较大,拆分路由,保证首页先加载

js
const routes = [
    {
        name: 'Page',
        path: '/page',
        components: () => import('../path')
    }
]

如何统一监听 Vue 组件报错

监听 Error

可以在 App.vue 监听报错

vue
// onerror方式
<script>
export default {
    mounted() {
        window.onerror = function(msg, source, line, column, error) {
            console.info(msg, source, line, column, error)
        }
    }
}
</script>

// addEventListener方式
<script>
export default {
    mounted() {
        window.addEventListener('error', e => {
            console.info(e)
        })
    }
}
</script>

errorCaptured 生命周期

  • 监听所有下级组件的错误
  • 返回 false 会阻止向上传播
vue
<script>
export default {
    errorCaptured(err, vm, info) {
        console.info(err, vm, info)
        return false
    }
}
</script>

errorHandler 配置

在入口文件 main.js 中配置 errorHandler

js
app.config.errorHandler = (err, vm, info) => {
    console.info(err, vm, info)
}

异步错误

  • 异步回调里的错误,errorHandler 监听不到
  • 需要使用 window.onerror

总结

  • errorCaptured 监听下级组件错误,返回 false 组织向上传播
  • errorHandler 监听全局 Vue 组件的错误
  • window.onerror 监听其他 Js 错误,如异步

实际工作中,三者要结合使用,errorCaptured 监听一些重要、有风险组件的错误,window.onerror 和 errorHandler 候补全局监听

Released under the MIT License.