面试官:SPA(单页应用)首屏加载速度慢怎么解决?

2023-11-05

一、什么是首屏加载

首屏时间(First Contentful Paint),指的是浏览器从响应用户输入网址地址,到首屏内容渲染完成的时间,此时整个网页不一定要全部渲染完成,但需要展示当前视窗需要的内容

首屏加载可以说是用户体验中最重要的环节

关于计算首屏时间

利用performance.timing提供的数据:

通过DOMContentLoad或者performance来计算出首屏时间

// 方案一:
document.addEventListener('DOMContentLoaded', (event) => {
    console.log('first contentful painting');
});
// 方案二:
performance.getEntriesByName("first-contentful-paint")[0].startTime

// performance.getEntriesByName("first-contentful-paint")[0]
// 会返回一个 PerformancePaintTiming的实例,结构如下:
{
  name: "first-contentful-paint",
  entryType: "paint",
  startTime: 507.80000002123415,
  duration: 0,
};

二、加载慢的原因

在页面渲染的过程,导致加载速度慢的因素可能如下:

  • 网络延时问题

  • 资源文件体积是否过大

  • 资源是否重复发送请求去加载了

  • 加载脚本的时候,渲染内容堵塞了

三、解决方案

常见的几种SPA首屏优化方式

  • 减小入口文件积

  • 静态资源本地缓存

  • UI框架按需加载

  • 图片资源的压缩

  • 组件重复打包

  • 开启GZip压缩

  • 使用SSR

减小入口文件体积

常用的手段是路由懒加载,把不同路由对应的组件分割成不同的代码块,待路由被请求的时候会单独打包路由,使得入口文件变小,加载速度大大增加

vue-router配置路由的时候,采用动态加载路由的形式

routes:[ 
    path: 'Blogs',
    name: 'ShowBlogs',
    component: () => import('./components/ShowBlogs.vue')
]

以函数的形式加载路由,这样就可以把各自的路由文件分别打包,只有在解析给定的路由时,才会加载路由组件

静态资源本地缓存

后端返回资源问题:

  • 采用HTTP缓存,设置Cache-ControlLast-ModifiedEtag等响应头

  • 采用Service Worker离线缓存

前端合理利用localStorage

UI框架按需加载

在日常使用UI框架,例如element-UI、或者antd,我们经常性直接饮用整个UI

import ElementUI from 'element-ui'
Vue.use(ElementUI)

但实际上我用到的组件只有按钮,分页,表格,输入与警告 所以我们要按需引用

import { Button, Input, Pagination, Table, TableColumn, MessageBox } from 'element-ui';
Vue.use(Button)
Vue.use(Input)
Vue.use(Pagination)

组件重复打包

假设A.js文件是一个常用的库,现在有多个路由使用了A.js文件,这就造成了重复下载

解决方案:在webpackconfig文件中,修改CommonsChunkPlugin的配置

minChunks: 3

minChunks为3表示会把使用3次及以上的包抽离出来,放进公共依赖文件,避免了重复加载组件

图片资源的压缩

图片资源虽然不在编码过程中,但它却是对页面性能影响最大的因素

对于所有的图片资源,我们可以进行适当的压缩

对页面上使用到的icon,可以使用在线字体图标,或者雪碧图,将众多小图标合并到同一张图上,用以减轻http请求压力。

开启GZip压缩

拆完包之后,我们再用gzip做一下压缩 安装compression-webpack-plugin

cnmp i compression-webpack-plugin -D

vue.congig.js中引入并修改webpack配置

const CompressionPlugin = require('compression-webpack-plugin')

configureWebpack: (config) => {
        if (process.env.NODE_ENV === 'production') {
            // 为生产环境修改配置...
            config.mode = 'production'
            return {
                plugins: [new CompressionPlugin({
                    test: /\.js$|\.html$|\.css/, //匹配文件名
                    threshold: 10240, //对超过10k的数据进行压缩
                    deleteOriginalAssets: false //是否删除原文件
                })]
            }
        }

在服务器我们也要做相应的配置 如果发送请求的浏览器支持gzip,就发送给它gzip格式的文件 我的服务器是用express框架搭建的 只要安装一下compression就能使用

const compression = require('compression')
app.use(compression())  // 在其他中间件使用之前调用

使用SSR

SSR(Server side ),也就是服务端渲染,组件或页面通过服务器生成html字符串,再发送到浏览器

从头搭建一个服务端渲染是很复杂的,vue应用建议使用Nuxt.js实现服务端渲染

小结:

减少首屏渲染时间的方法有很多,总的来讲可以分成两大部分 :资源加载优化 和 页面渲染优化

下图是更为全面的首屏优化的方案

大家可以根据自己项目的情况选择各种方式进行首屏渲染的优化

参考文献

  • https://zhuanlan.zhihu.com/p/88639980?utm_source=wechat_session

  • https://www.chengrang.com/how-browsers-work.html

  • https://juejin.cn/post/6844904185264095246

  • https://vue3js.cn/docs/zh

面试官VUE系列总进度:8/33

面试官:说说你对vue的理解?

面试官:说说你对SPA(单页应用)的理解?

面试官:说说你对双向绑定的理解?

面试官:说说你对Vue生命周期的理解?

面试官:Vue组件间通信方式都有哪些?

面试官:Vue中的v-show和v-if怎么理解?

面试官:为什么Vue中的v-if和v-for不建议一起用?

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

面试官:SPA(单页应用)首屏加载速度慢怎么解决? 的相关文章

  • 更新 Google 地图流量层而无需重新加载页面

    我的页面中嵌入了 Google 地图 我使用 initMap js 函数来初始化地图 function initMap var map new google maps Map document getElementById t map zo
  • EJS在JS onload函数中访问express变量

    我知道你可以像这样获取 ejs 文件中变量的值 h1 h1 如果我要在同一个 ejs 页面的 onload javascript 函数中使用相同的标题变量 我将如何使用它 例如 这个函数产生一个控制台错误说 未捕获的语法错误 意外的标识符
  • 如何将函数传递给 JavaScript Web Worker

    我想通过一个 或多个 函数传递postMessage 给网络工作者 因为我无法引用常规文件 为了启动 Web Worker 我将一个对象 URL 从 Blob 创建 传递给Worker构造函数 然后我传递一条消息 但到目前为止还没有在消息中
  • 从网站存储数据的最简单方法(在服务器端)

    我有一个非常简单的网站 实际上是单页 有一个输入字段和一个按钮 我需要将用户提交的数据存储在服务器端的某个位置 完美的方法可能是简单的文本文件 并在每次单击按钮后附加新行 日志文件也可以 据我了解 JavaScript 本身是不可能的 我在
  • 如何检查元素的内容是否为空,如果是,则在 jquery 中删除该元素

    我目前正在尝试选择某个 div 内没有内容的任何 h2 元素并将其删除 这是我的 html 代码 div class skipToContainer h2 class vidSkipTo Hello h2 h2 class vidSkipT
  • 更改时触发跨度文本/html

    jQuery 或 JavaScript 中是否有任何事件在以下情况下触发span标签 text html 已更改 Code span class user location span user location change functio
  • 通过 jQuery 从输入类型=“文件”多个中删除文件

    我在使用 PHP 和 jQuery 上传文件时遇到问题 表单可以一次上传多个图像 这些图像可以在滑块中预览 表单还包含两个字段标题和描述 滑块通过 jQuery 工作 当用户通过单击选择文件来选择多个图像时
  • toLocaleDateString() 在 Chrome 中如何工作?

    我理解了javascript方法toLocaleDateString 使用的计算机设置 让我们来W3Schools 示例 http www w3schools com jsref tryit asp filename tryjsref to
  • 如何修复 getImageData() 错误画布已被跨源数据污染?

    我的代码在本地主机上运行得很好 但在网站上却不起作用 我从控制台收到此错误 对于这一行 getImageData x y 1 1 data Uncaught SecurityError Failed to execute getImageD
  • 如何使用 Jest 测试对象键和值的相等性?

    我有一个mapModule我在其中导入组件并导出它们 import ComponentName from components ComponentName export default name ComponentName 我该如何测试ma
  • 如何设置旋转元素背面的样式?

    我有一个figure它是可旋转的 通过用户输入任意角度 该旋转明显地使用transition财产 当该元件旋转超过 90 度 90 度时 元件的背面可见 我想对元素的通常隐藏的一面进行与正面不同的设计 但我不确定如何实现这一点 figure
  • 响应式导航栏隐藏其下方的元素

    我创建了一个响应式导航栏 但它使下面的元素 Flexslider 插件 消失 在我制作导航栏之前 下面的 Flexslider 可以正常显示 但现在不行 导航栏的 z index 为 2 所以我不知道问题是什么 我应该如何 更改什么才能允许
  • 跨浏览器:禁用输入字段的不同行为(文本可以/不能复制)

    我有一个被禁用的输入 html 字段 在某些浏览器 Chrome Edge Internet Explorer 和 Opera 中可以选择并复制文本 但至少在 Firefox 中这是不可能的 您可以通过在不同浏览器中执行以下代码来测试
  • 如何修复nodejs Express服务器中的“MulterError:意外字段”?

    我正在设置一个服务器来从客户端上传 zip 文件 服务器运行express和multer来执行此操作 上传文件时 服务器抛出 MulterError 意外字段 错误 我无法弄清楚是什么导致了它 我尝试过使用 png 图像 效果很好 但对于
  • 如何更改 Shiny 中 navbarPage 折叠的断点

    我想用shiny navbarPage collapsible TRUE 当在小屏幕上查看我的 Shiny 应用程序时 将导航元素折叠到菜单中 默认情况下 当浏览器宽度小于 940 像素时会触发折叠 有什么方法可以改变这一点 以便在稍大的浏
  • 两种颜色边框

    客户想要两种颜色的边框以获得浮雕外观 我可以在一个元素上执行此操作吗 我希望避免堆叠两个具有单独边框的 DOM 元素 是的 使用outline财产 它充当您边界之外的第二个边界 但请注意 它可能会以一种奇怪的方式与边距 填充和阴影进行交互
  • 使用 JavaScript onclick 添加表格行

    我正在尝试使用 javascript 添加下面找到的完全相同的元素 我已经尝试了这里找到的所有解决方案 我什至尝试用php echo但没有运气 无需更改任何输入名称或类似内容 只需单击该按钮即可向表中添加另一行 仅此而已 这是该元素 tr
  • 如何设置 Firebase 用户的显示名称?

    根据Firebase网站上的JS Auth文档 它只展示了如何获取 displayName 以及如何更新 displayName 所以我尝试更新它 但这有点不合逻辑 因为你怎么能在不创建某些东西的情况下更新它呢 所以我的问题是 如何设置注册
  • CSS:缩放字体大小以适应父块元素的高度

    我发现的几乎每个问题和答案都谈到了视口大小 这确实不是我的问题 拿着这支笔 https codepen io njt1982 pen pZjZNM https codepen io njt1982 pen pZjZNM 我有一个非常基本的
  • NodeJS:如何获取服务器的端口?

    您经常会看到 Node 的示例 hello world 代码 它创建一个 Http Server 开始侦听端口 然后执行以下操作 console log Server is listening on port 8000 但理想情况下你会想要

随机推荐

  • C#实现DLT直接线性变换(Direct Linear Transform)算法

    C 实现DLT直接线性变换 Direct Linear Transform 算法 参考资料 1 武大版 工业测量技术与数据处理 P100 P106 2 转载博文 MATLAB实现DLT Direct Linear Transform 算法
  • 蓝桥杯每日一题(15):莱布尼茨计算圆周率(python)

    Topic 历史上有许多计算圆周率pai的公式 其中 格雷戈里和莱布尼茨发现了下面的公式 pai 4 1 1 3 1 5 1 7 参见图 这个公式简单而优美 但美中不足 它收敛的太慢了 如果我们四舍五入保留它的两位小数 那么 累积1项是 4
  • android Q支持的EAP方法配置

    1 supplicant external wpa supplicant 8 wpa supplicant android config CONFIG EAP MD5 y CONFIG EAP MSCHAPV2 y CONFIG EAP T
  • HTML <thead> 标签

    实例 带有 thead tbody 以及 tfoot 元素的 HTML 表格 table border 1 thead tr th Month th th Savings th tr thead tfoot tr td Sum td td
  • Tomcat多实例和负载均衡动静分离

    目录 一 Tomcat多实例部署 二 负载均衡动静分离 2 1 动静分离 2 11 nginx负载均衡 192 168 30 203 2 22 Tomcat服务器 192 168 30 200 2 23 Tomcat服务器 192 168
  • java g1垃圾收集器_深入理解G1垃圾收集器

    G1 GC是Jdk7的新特性之一 Jdk7 版本都可以自主配置G1作为JVM GC选项 作为JVM GC算法的一次重大升级 DK7u后G1已相对稳定 且未来计划替代CMS 所以有必要深入了解下 不同于其他的分代回收算法 G1将堆空间划分成了
  • Ubuntu22.10 安装微信方法

    Ubuntu22 10 安装微信方法 Ubuntu操作系统中 我尝试过用wine方式安装数次都没有能够启动成功 方法如下 在Ubuntu上安装微信需要使用Wine Wine是一款可以在Linux系统上运行Windows应用程序的兼容层 以下
  • 修改redis配置文件重新启动redis服务启动不了

    一 迁移一个新的配置文件 cat redis conf grep v grep v gt redis test conf 二 修改redis test conf配置 三 启动 redis server etc redis test conf
  • Springboot结合前端上传图片保存到数据库读取

    前言 最近在做一个前后端分离系统 也是闲的无聊做个好玩的练练手 就突然想着之前想了一天的问题 前端怎么去发送图片到后端保存 不是专业前端 轻点喷 图片到底是保存在本地还是存在oss上 保存图片的方式又是什么 这些问题想到我头皮发麻 最后 还
  • 学习经验分享之五:YOLOv5数据集划分以及YOLO格式转换

    问 题 有不少学YOLOv5算法的朋友咨询我 发现部分朋友犯了一个很大的错误 就是只是划分了训练集和验证集 没有测试集 并且没有意识到自己的实验设置是错误的 不科学的 这是非常可怕的 意味着可能前期的工作都白做了 浪费了宝贵的时间和精力 部
  • Linux——进程的四大特性

    一 进程的四大特性 竞争性 独立性 并行性 并发性 1 竞争性 系统进程数码众多 而CPU的资源只有固定的那些 很少 比如说CPU 一般情况下CPU只有一个 所以进程之间是具有竞争属性的 为了高效的完成任务 更合理竞争相关的资源 便具有了优
  • IT工程师学习方法和发展路线

    前言 从需求 即招聘 面试入手 了解行业所需 再到个人部分 学习大佬们的学习方法 书写自己的简历 提升自我技能 或通过考证锻炼学习的学习方法 或通过技能提高工作效率 简述几个方面的特点 梳理下发展路线 通过利器提高办公效率 Tips Mar
  • 区块链基于电商的发展

    区块链技术的发展现状 2008年10月31日 中本聪 Satoshi Nakamoto 的比特币白皮书正式发布 标 志着基于区块链技术的第一个应用比特币 一个去中心化的电子现金系统 正式诞生 这一应用的诞生向世人展示了区块链技术的巨大价值和
  • CLR Via 读书笔记

    CLR Via 读书笔记 第四章 类型基础 记录C 学习过程中的一些语法知识 2023 9 3 第四章 类型基础 点击跳转
  • Mathsphere Note: 好用的Markdown for Latex 文档编辑器

    背景描述 Markdown是一种轻量化的标记语言 非常适合于撰写技术博客类文档 而Markdown for Latex顾名思义 是在Markdown语法的基础上做了增量 适配了Latex的语法 能够对论文进行排版 本文将简要介绍一款Mark
  • JHipster介绍:一个适用于Java和JavaScript的全栈框架

    JHipster介绍 Java和JavaScript的全栈框架 JHipster是一个用于生成混合Java和JavaScript应用程序的成熟框架 它支持你所喜爱的开发工具 并提供监控和其他开箱即用的管理功能 JHipster是一个历史悠久
  • 数据库中几种易混淆的字符串类型

    目录 1 char 2 nchar 3 varchar 4 nvarchar 总结 在数据库中有char varchar nchar nvarchar等几种类型 其中这四种非常类似 但表示的意义稍有不同 1 char char 是普通字符编
  • 解决cv2没有face模块

    人脸识别报错解决 AttributeError module cv2 cv2 has no attribute face 人脸识别报错如下 AttributeError module cv2 cv2 has no attribute fac
  • Scrapy介绍及入门

    一 Scrapy简介 Scrapy是一个为了爬取网站数据 提取结构性数据而编写的应用框架 可以应用在包括数据挖掘 信息处理或存储历史数据等一系列的程序中 其最初是为了页面抓取 更确切来说 网络抓取 所设计的 也可以应用在获取API所返回的数
  • 面试官:SPA(单页应用)首屏加载速度慢怎么解决?

    一 什么是首屏加载 首屏时间 First Contentful Paint 指的是浏览器从响应用户输入网址地址 到首屏内容渲染完成的时间 此时整个网页不一定要全部渲染完成 但需要展示当前视窗需要的内容 首屏加载可以说是用户体验中最重要的环节