< 前端性能优化: 资源加载优化 >_前端资源加载优化-程序员宅基地

技术标签: 面试知识点分享  性能优化  前端  每日小技巧  

前端性能优化


前言

众所周知,前端是由HTML、CSS、JS等文件资源共同作用下渲染构建出来的。现今前端项目,大多为单页面应用,单页面应用的优点非常多(点击跳转 SPA单页面讲解),但是也并非没有缺点 。由于单页面的原因,项目所需资源都需要在初次加载首屏时被加载,这就造成了首屏加载性能受到影响!

对于首屏性能优化,就衍生出了相关需要思考的问题。如何将首屏加载的资源,分段将需要的资源及时加载出来,避免页面内容不显示的同时,又能避免加载多余并非立刻需要使用的资源呢?

接下来,带着问题去阅读本篇文章,由小温梳理了一下有关资源加载优化方面的优化,希望各位小伙伴们能有所收获!

一、路由懒加载

懒加载就是延时加载(也称为按需加载),即在当资源使用时,再进行加载的原理。

例如:当我们访问页面时,先将img图片的路径替换成一张占位图的路径,这样就只需请求一次,而当图片进入可视区域时才把其图片的路径替换为真正的路径,从而显示图片,达到懒加载的效果。(即:懒加载就是使用同一张占位图进行占位,然后按需获取图片真正的路径,从而实现懒加载)

在SPA 单页应用项目中,一个路由对应一个页面,如果不做处理,项目打包后,会把所有页面打包成一个文件,当用户打开首页时,会一次性加载所有的资源,造成首页加载很慢,降低用户体验

那么,我们如何去通过懒加载的方式去加载这些资源呢? 这就要请出本小节的 关键人物 了,ES6的动态地加载模块——import()。其次,要实现懒加载,就得先将进行懒加载的子模块分离出来,打包成一个单独的文件!

调用 import() 之处,被作为分离的模块起点,意思是,被请求的模块和它引用的所有子模块,会分离到一个单独的 chunk 中
——摘自《webpack——模块方法》的import()小节

> 实现代码

// 通过webpackChunkName设置分割后代码块的名字
const Home = () => import(/* webpackChunkName: "home" */ "@/views/home/index.vue");
const MetricGroup = () => import(/* webpackChunkName: "metricGroup" */ "@/views/metricGroup/index.vue");
…………
const routes = [
  {
    
      path: "/",
      name: "home",
      component: Home
   },
   {
    
      path: "/metricGroup",
      name: "metricGroup",
      component: MetricGroup
   },
   …………
]

webpackChunkName 作用是 webpack 在打包的时候,对异步引入的库代码(lodash)进行代码分割时,设置代码块的名字。webpack 会将任何一个异步模块与相同的块名称组合到相同的异步块中。

> 处理前后各文件大小情况

处理前
前
处理后

后

处理前

前
处理后
后

二、组件懒加载

除了路由的懒加载外,组件的懒加载在很多场景下也有重要的作用。

例如: 在某个页面中,弹窗组件并非在页面加载时就需要显示,而是在用户点击弹窗时显示。这里我们就可以使用懒加载,使得弹窗组件对应的资源,在用户点击时再加载。以提高首页加载速度,减少首屏加载的白屏时间!

同样,在这里我们也照样是使用 import() 去实现组件的懒加载功能!

但是,所有事都是有利有弊的,懒加载也同样。 随着懒加载资源的增多,会导致浏览器资源请求过于频繁,对服务器负担也会加重!其次是在懒加载某些局部资源量大的组件,在打开时,会有少许延迟,不过从观感上来说,影响并不大!

> 实现代码

<script>
const dialogInfo = () => import(/* webpackChunkName: "dialogInfo" */ '@/components/dialogInfo');
export default {
    
  name: 'homeView',
  components: {
    
    dialogInfo
  }
}
</script>

使用懒加载后,弹窗对应的资源只有在第一次点击弹窗时进行加载!
弹窗资源加载

> 适用场景

  1. 该页面的 JS 文件体积大,导致页面打开慢,可以通过组件懒加载进行资源拆分,利用浏览器并行下载资源,提升下载速度(如:首页、大屏、工作台各流程页面
  2. 该组件不是一进入页面就展示,需要一定条件下才触发(如:弹框组件、自定义组件
  3. 该组件复用性高,很多页面都有引入,利用组件懒加载抽离出该组件,一方面可以很好利用缓存,同时也可以减少页面的 JS 文件大小(如:表格组件、图形组件等

三、骨架屏优化白屏时长

使用骨架屏,可以缩短白屏时间,提升用户体验。国内大多数的主流网站都使用了骨架屏,特别是手机端的项目。

SPA 单页应用,无论 vue 还是 react,最初的 html 都是空白的,需要通过加载 JS 将内容挂载到根节点上,这套机制的副作用:会造成长时间的白屏。

常见的骨架屏插件就是基于这种原理,在项目打包时将骨架屏的内容直接放到 html 文件的根节点中
使用骨架屏插件,打包后的 html 文件(根节点内部为骨架屏)。

如果只是小范围使用,推荐使用 elementUi里面的骨架屏组件。

点击跳转:骨架屏文档地址

四、JavaScript 的6种加载方式

1. 正常模式

<script src="index.js"></script>

这种情况下 JS 会阻塞 dom 渲染,浏览器必须等待 index.js 加载和执行完成后才能去做其它事情

2. async 模式

<script async src="index.js"></script>

async 模式下,它的加载是异步的,JS 不会阻塞 DOM 的渲染,async 加载是无顺序的,当它加载结束,Js 会立即执行

使用场景:若该 JS 资源与 DOM 元素没有依赖关系,也不会产生其他资源所需要的数据时,可以使用async 模式,如:埋点统计。

3. defer 模式

<script defer src="index.js"></script>

defer 模式下,JS 的加载也是异步的,defer 资源会在 DOMContentLoaded 执行之前,并且 defer 是有顺序的加载

如果有多个设置了 defer 的 script 标签存在,则会按照引入的前后顺序执行,即便是后面的 script 资源先返回

所以 defer 可以用来控制 JS 文件的执行顺序,比如 element-ui.jsvue.js,因为 element-ui.js 依赖于 vue,所以必须先引入 vue.js,再引入 element-ui.js

<script defer src="vue.js"></script>
<script defer src="element-ui.js"></script>

defer 使用场景:一般情况下都可以使用 defer,特别是需要控制资源加载顺序时。

4. module 模式

<script type="module">import {
       a } from './a.js'</script>

在主流的现代浏览器中,script 标签的属性可以加上 type="module",浏览器会对其内部的 import 引用发起 HTTP 请求,获取模块内容。这时 script 的行为会像是 defer 一样,在后台下载,并且等待 DOM 解析

Vite 就是利用浏览器支持原生的 es module 模块,开发时跳过打包的过程,提升编译效率。

5. preload 模式

<link rel="preload" as="script" href="index.js">

link 标签的 preload 属性:用于提前加载一些需要的依赖,这些资源会优先加载(如下图红框)
在这里插入图片描述

例如:在 Vue2 项目打包生成的 index.html 文件,会自动给首页所需要的资源,全部添加 preload,实现关键资源的提前加载。
在这里插入图片描述

> preload 特点:

  1. preload 加载的资源是在浏览器渲染机制之前进行处理的,并且不会阻塞 onload 事件;

  2. preload 加载的 JS 脚本其加载和执行的过程是分离的,即 preload 会预加载相应的脚本代码,待到需要时自行调用;

6. prefetch

<link rel="prefetch" as="script" href="index.js">

prefetch 是利用浏览器的空闲时间,加载页面将来可能用到的资源的一种机制;通常可以用于加载其他页面(非首页)所需要的资源,以便加快后续页面的打开速度。

> prefetch 特点:

  1. pretch 加载的资源可以获取非当前页面所需要的资源,并且将其放入缓存至少5分钟(无论资源是否可以缓存)

  2. 当页面跳转时,未完成的 prefetch 请求不会被中断

> 加载方式总结

asyncdeferscript 标签的专属属性,对于网页中的其他资源,可以通过 linkpreloadprefetch 属性来预加载。

如今现代框架已经将 preloadprefetch 添加到打包流程中了,通过灵活的配置,去使用这些预加载功能,同时我们也可以审时度势地向 script 标签添加 asyncdefer 属性去处理资源,这样可以显著提升性能

五、图片资源处理

> 图片大小控制 或 使用云存储

在页面中,在不影响图片的查看的同时,适当调整图片的分辨率大小。能够很大程度上的减少资源加载所需时间,如下图所示,不同分辨率下的图片占用资源大小:

在这里插入图片描述
在这里插入图片描述

> 图片懒加载

对于一些图片量比较大的首页,用户打开页面后,只需要呈现出在屏幕可视区域内的图片,当用户滑动页面时,再去加载可视窗口内的图片,以优化图片的加载效果。

最常见的例子就是:淘宝、今日头条等等,数据量大的页面资源加载。

> 图片懒加载实现原理:

由于浏览器会自动对页面中的 img 标签的 src 属性发送请求并下载图片,可以通过 html5 自定义属性 data-xxx 先暂存 src 的值,然后在图片出现在屏幕可视区域的时候,再将 data-xxx 的值重新赋值到 img 的 src 属性即可。

<img src="" alt="" data-src="./images/1.jpg">
<img src="" alt="" data-src="./images/2.jpg">

这里以 vue-lazyload 插件为例。

// 安装 
npm install vue-lazyload 
// main.js 注册
import VueLazyload from 'vue-lazyload'
Vue.use(VueLazyload)
// 配置项
Vue.use(VueLazyload, {
    
  preLoad: 1.3,
  error: 'dist/error.png', // 图片加载失败时的占位图
  loading: 'dist/loading.gif', // 图片加载中时的占位图
  attempt: 1
})
// 通过 v-lazy 指令使用
<ul>  
    <li v-for="img in list">
        <img v-lazy="img.src" :key="img.src" >
    </li>
</ul>

总结

感谢各位小伙伴们,能够认真看到这里。通过本篇文章,相信大伙都对前端资源加载优化方面有了更加深入的了解!即使优化方案稍微有些简单,但是优化后的效果卓著。

相信还有更多有关前端性能优化相关的内容,在等待我们的挖掘! 仅以此文抛砖引玉,希望大家不要吝啬你们手中的赞,给小温一点支持吧!

参考文献

往期内容

< element-Ui表格组件:表格多选功能回显勾选时因分页问题,导致无法勾选回显的全部数据 >

< 每日闲谈:你真的了解 “ ChatGPT ” 嘛 ? >

< 每日算法 - JavaScript解析:搜索旋转排序数组 >

< CSS小技巧:类似photoShop的混合模式(mix-blend-mode / background-blend-mode)使用 >

<开源: 推荐10个开源的前端低代码项目>

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/MrWen2395772383/article/details/130223468

智能推荐

CTFHub SSRF-程序员宅基地

文章浏览阅读649次,点赞3次,收藏4次。CTFHub SSRFSSRF简介漏洞攻击方式CTFHub SSRF靶场第一部分(Http、Dict和file等协议的利用)内网访问伪协议读取文件端口扫描SSRF简介SSRF (Server-Side Request Forgery,服务器端请求伪造) 是一种由攻击者构造请求,由服务端发起请求的安全漏洞,一般情况下,SSRF攻击的目标是外网无法访问的内网系统,也正因为请求是由服务端发起的,所以服务端能请求到与自身相连而与外网隔绝的内部系统,也就是说可以利用一个网络请求的服务,当作跳板进行攻击_ctfhub ssrf

【ZYNQ入门】第十篇、基于FPGA的图像白平衡算法实现_基于fpga的白平衡-程序员宅基地

文章浏览阅读1.7k次,点赞29次,收藏44次。step1、分别对图像的R、G、B三通道的数据进行求和得到Rsum、Gsum、Bsum;step2、获取图像的R、G、B三通道的平均值Rv,Gv,Bv;imag_width:当前图像的宽,imag_high:当前图像的高度。step3、将求得的Rv、Gv、Bv 进行加和取平均值,得到step4、分别将R、G、B三通道的数据带入公式进行计算,得到新的值G通道:B通道:step5、最后将计算后的图片显示出来,便是白平衡后的图像。_基于fpga的白平衡

FPGA快速入门3——verilog可编程进阶_verilog中<=电路-程序员宅基地

文章浏览阅读685次。前两节主要介绍了Verilog一些基础的知识点,本节给大家介绍一些高级的进阶知识点。高级进阶知识点包括阻塞赋值和非阻塞赋值、assign和always语句差异、什么是锁存器、状态机、模块化设计等。阻塞赋值和非阻塞赋值在Verilog中有两种类型的赋值语句:阻塞赋值语句(“=”)和非阻塞赋值语句(“<=”)。正确地使用这两种赋值语句对于Verilog的设计和仿真非常重要。Veril..._verilog中<=电路

Android 通过JNI实现守护进程(上)_android 手机锁屏之后后台运行 jni实现-程序员宅基地

文章浏览阅读585次。来源:LeBron_Six 链接:blog.csdn.net/yyh352091626/article/details/50542554开发一个需要常住后台的App其实是一件非常头疼的事情,不仅要应对国内各大厂商的ROM,还需要应对各类的安全管家… 虽然不断的研究各式各样的方法,但是效果并不好,比如任务管理器把App干掉,服务就起不来了…网上_android 手机锁屏之后后台运行 jni实现

Windows Server 2008 搭建自带的FTP服务_windows server 2008没有ftp服务吗-程序员宅基地

文章浏览阅读3.9k次。ftp在其他的地方解释一大堆,其实没那么麻烦,FTP其实就是做一个数据传输的服务,有很多时候在咱们大数据中,涉及到数据的交换,或者集群升级之类的,原有的数据不可能直接下载在上传新的环境,所以最常用的就是ftp,下面我们看一下咱们搭建一、启用FTP服务FTP服务在Windows server 2008中默认是没有装载的,但是提供了装载方式,我们需要依次打开控制面板->..._windows server 2008没有ftp服务吗

mysql主从灾备_mysql查看主备状态-程序员宅基地

文章浏览阅读2.9k次,点赞4次,收藏6次。个人分类:数据库相关双机热备的概念简单说一下,就是要保持两个数据库的状态自动同步。对任何一个数据库的操作都自动应用到另外一个数据库,始终保持两个数据库数据一致。 这样做的好处多。 1. 可以做灾备,其中一个坏了可以切换到另一个。 2. 可以做负载均衡,可以将请求分摊到其中任何一台上,提高网站吞吐量。 对于异地热备,尤其适合灾备。废话不多说了。我们直接进入主题。 我们会主要介绍两部分内容:..._mysql查看主备状态

随便推点

pandas DataFrame 用法--查看和选择数据_pandas中对dataframe的数据如何进行查询-程序员宅基地

文章浏览阅读5.4k次。1.使用 .head() 查看 DataFrame 头部数据2.使用 .tail() 查看 DataFrame 尾部数据3.使用 .describe() 查看 DataFrame 统计数据4.使用 .T查看 DataFrame 转置数据5. 使用 .sort_index() 查看按照轴排序的数据6. 使用 .sort_values() 查看按照值排序的数据7.at 函数:通过行名和列名来取值(取行名为a, 列名为A的值)8.iat 函数..._pandas中对dataframe的数据如何进行查询

CreateFont函数关于字符集与字体的两个参数_createfont字符集怎么设置-程序员宅基地

文章浏览阅读5.8k次。对于fdwCharSet和lpszFace两个参数以及他们的关系,刚开始不是很理解,所以google了一些资料,对这个问题有了一点自己的认识。_createfont字符集怎么设置

小米格机9008救砖后如何跳过nv损坏进入MIUI系统写基带并修临时基带_9008备份基带-程序员宅基地

文章浏览阅读2.7k次。我k40刷完后虽然串号这些都有了也识别卡了但是没信号是因为modem分区用的工厂包的文件还是我手机坏了或者qcn有问题如果你在没有改qcn的情况下刷回原系统的modem分区文件你又会进入nv损坏无限重启[doge]这时你就会发现电脑设备管理器会出现新的4个新设备端口打开QPST就可以刷基带了(k40在正常的系统我觉得应该也可以用这种方式开启端口备份基带,改串号可以用星海之类的软件正常勿改)。以上都是经验之谈具体看个人[坏笑][坏笑][坏笑][坏笑]从折腾了这几天的红米k40来看。从k40救砖经验来看。_9008备份基带

参与CSDN1024程序员节活动-程序员宅基地

文章浏览阅读4k次。有幸参与了CSDN主办的1024程序员活动-岳麓对话,聆听各位专家畅谈中国软硬件产业的根技术以及前沿科技的发展现状和未来。听程序员们聊技术,都比较实在落地,在谈到如果你有个孩子在读大学你会推荐他学什么专业和技术时,各位大佬都集体推荐本专业或本专业的基础学科,都充满了对自己行业的自豪感。小冰CEO李笛说:学习人工智能,未来如果技术被颠覆了,等于是自杀,而不学人工智能,则相当于是他杀。百度副总裁马杰说:我们应站在时代的肩膀上,人工智能在深刻地改变我们的世界,未来会持续产生影响。国科量子副总裁聂际敏说:学

BIM族库下载——10套知名地产Revit样板文件_地暖bim效果图-程序员宅基地

文章浏览阅读1.2k次。【资源介绍】资源名称:10套知名地产Revit样板文件资源分类: BIM族库、Revit族库其他简介:10套知名地产Revit样板文件【资源下载】链接:https://pan.baidu.com/s/1qsTHMbhGkiXztPQDmJlKfQ提取码:wb33【资源截图】【免责申明】本站提供的资源下载链接均来自互联网,仅供学习研究之用,不得用于商业,请在24小时内删除!资源版权归原作者及其公司所有,如果你喜欢,请购买正版。..._地暖bim效果图

西电软件体系结构——01绪论-程序员宅基地

文章浏览阅读288次。课程简介软件体系结构的主题是针对复杂软件系统的高层结构、组织单元之间的相互关系的描述,以及围绕这种描述开展的各项活动,如设计、评估、实现、管理等。课程目标_西电软件体系结构