前端性能优化系列 | 加载优化(下)

简介: 1. 资源加载优先级在浏览器发起网络请求时,并非每个字节都具有相同的优先级,所以,浏览器通常会对所要加载的内容进行推测,将相对重要的信息先呈现给用户。比如浏览器一般会先加载CSS,再去加载JavaScript脚本和图像文件。当然,浏览器的判断并不一定都是准确的,下面就来看看如何影响浏览器对资源加载的优先级。

(3)Intersection Observer实现

Intersection Observer是HTML5新增的API,可以用来实现图片懒加载。MDN中对Intersection Observer的解释:


IntersectionObserver接口 (从属于Intersection Observer API) 提供了一种异步观察目标元素与其祖先元素或顶级文档视窗(viewport)交叉状态的方法。祖先元素与视窗(viewport)被称为根(root)。

当一个IntersectionObserver对象被创建时,其被配置为监听根中一段给定比例的可见区域。一旦IntersectionObserver被创建,则无法更改其配置,所以一个给定的观察者对象只能用来监听可见区域的特定变化值;然而,你可以在同一个观察者对象中配置监听多个目标元素。


上面使用节流来解决了scroll频繁触发的问题,这也说明传统的图片懒加载方案是存在一定问题的;而Intersection Observer不需要监听scroll事件,可以做到只要图片元素出现在可视区域内,就能进行回调,具体如下:


document.addEventListener("DOMContentLoaded", function() {
  var lazyImages = [].slice.call(document.querySelectorAll("img.lazy"));
  if ("IntersectionObserver" in window) {
    let lazyImageObserver = new IntersectionObserver(function(entries, observer) {
      entries.forEach(function(entry) {
        if (entry.isIntersecting) {
          let lazyImage = entry.target;
          lazyImage.src = lazyImage.dataset.src;
          lazyImage.srcset = lazyImage.dataset.srcset;
          lazyImage.classList.remove("lazy");
          lazyImageObserver.unobserve(lazyImage);
        }
      });
    });
    lazyImages.forEach(function(lazyImage) {
      lazyImageObserver.observe(lazyImage);
    });
  } 
});
复制代码

上面就是使用Intersection Observer完成图片懒加载的方法,该方法唯一的缺点就是兼容性还不是很好,如果需要兼容版本较低的浏览器,则要根据浏览器的版本封装更通用的方法。


(4)第三方库实现

除了上面介绍的一些延迟加载方法之外,还可以借助一些已经封装好的第三方库,下面是一些成熟的第三方库:

  • lozad.js 是超轻量级且只使用 Intersection Observer 的库, 因此它的性能极佳,但如果要在旧版本浏览器上使用,则需要配置polyfill。
  • lazysizes 是功能全面的延迟加载库,其使用的模式与本文所示的代码示例非常相似,会自动与 <img> 元素上的lazyload 类绑定,然后在data-src 和/或 data-srcset 属性中指定图像网址,该库还可以通过许多插件进行扩展,执行延迟各种资源等操作。
  • 如果使用React框架,可以使用 react-lazyload来进行图片懒加载操作,这个库是React图片懒加载的主流解决方案。
  • 如果使用Vue框架,可以使用 vue-lazyload 来进行图片懒加载操作,这个库是Vue图片懒加载的主流解决方案。


3. 首屏加载优化


随着Vue、React等框架的盛行,SPA单页面应用越来越多,多数的SPA应用的结构都很类似。由于SPA页面打包之后的JavaScript文件很大,等这个巨大的JavaScript文件加载完之后,首屏才能渲染,这就导致出现了白屏的问题。在移动端,一些需要快速迭代的开发项目都是使用HTML5开发的,同样首屏加载白屏问题非常的严重。下面就来看一下针对首屏渲染白屏的解决方案。


(1)骨架屏

骨架屏就是指在未加载完时,先简单的用图形勾勒出页面的大概布局,给用户一个视觉上更好一点的体验,等页面加载完成之后,再将骨架屏替换掉即可,如下图所示:

网络异常,图片无法展示
|


实现骨架屏的方式有很多种,下面来看下常见的几种:

  • 绘制静态骨架屏

最直接的实现方案就是直接绘制出一张骨架屏的图片,在资源加载完毕之后,页面内容直接替换这张图片即可。我们知道,base64格式的图片可以直接插入到HTML中,并且可以节约一次HTTP请求,所以,可以把骨架屏的静态图片直接转化为base64格式并插入到HTML文件中。只要监听onLoad事件,当完成之后,将图片替换掉即可。

  • 代码绘制骨架屏

通过代码绘制骨架屏会比绘制静态图片更加灵活,可定制化程度高。可以根据自己的需要,绘制需要的样式。只需要根据首屏的大致轮廓绘制一个对应HTML结果,再用CSS填充上合适的背景色即可。除此之外,还可以通过改动CSS,为这个骨架图添加一些动态的效果(加载动画),这样用户体验会更好。

  • 自动化解决方案

如果需要给多个页面添加骨架图,那么就需要绘制多个骨架图,这样就比较麻烦。不过,现在已经有以下比较成熟的解决方案,目前使用比较广泛的是 page-skeleton-webpack-plugin插件,该插件是一个webpack插件,可以根据具体的页面生成对应的骨架屏,使用起来非常方便。除此之外,Ant Design也提供了骨架屏的方案:Skeleton骨架屏


(2)资源预加载

上面提到了预加载,MDN中对资源预加载的解释:

页面资源预加载(Link prefetch)是浏览器提供的一个技巧,目的是让浏览器在空闲时间下载或预读取一些文档资源,用户在将来将会访问这些资源。一个 Web 页面可以对浏览器设置一系列的预加载指示,当浏览器加载完当前页面后,它会在后台静悄悄的加载指定的文档,并把它们存储在缓存里。当用户访问到这些预加载的文档后,浏览器能快速的从缓存里提取给用户。


简单来说就是当页面加载完成后或者其他空闲的时间,可以加载之后页面中用到的资源。


1)rel="preload"

可以使用rel属性,<link> 元素的 rel 属性的属性值preload能够让我们在HTML页面中 <head>元素内部书写一些声明式的资源获取请求,可以指明哪些资源是在页面加载完成后即刻需要的。


<link rel="preload" href="style.css" as="style">
<link rel="preload" href="main.js" as="script">
复制代码

这样,我们预加载了css和js文件,在随后的页面渲染的时候,如果需要使用这两个文件,直接使用即可,因为已经缓存好了。不仅是这些文件可以预加载,字体,图片,音视频文件都可以进行预加载。


2)rel="subresource"

除此之外,我们还可以使用 subresource 属性。subresource 和 preload 属性相比,它的优先级是最高的,使用方法和 preload 基本相同,如下:


<link rel="subresource" href="styles.css">
复制代码

因此,如果资源需要马上用到或者是当前页面急需的资源,就可以使用subresource。当然在实际的开发当中 preload 属性用的较多一些


3) rel="prerender"

prerender 可以指定加载一个页面的所有资源,使用方法如下:

<link rel="prerender"  href="/result.html" />
复制代码

prerender 的效果就和默认打开了一个隐藏的 tab 一样,会下载所有的资源、创建 DOM、渲染页面、执行 JS 等。如果用户进入指定的链接,隐藏的这个页面就会进入马上进入用户的视线。这个属性虽然强大,但是却不能乱用,一定要确定这个页面用户的确会进行点击,才可以进行设置。否则用户不点,就浪费了大量的宽带资源去下载了一个无用的页面,这样反而得不偿失。


4. 视频加载优化


(1)延迟加载视频

图片和视频这类静态资源资源占比都比较大。与图片一样,视频同样可以延迟加载,来达到优化性能的目的。正常情况下加载视频,使用的是<video>标签,那么对于一些需要由用户自己播放的视频,最好指定<video>标签的preload属性为none,这样浏览器就不会预加载任何视频数据。为了占用空间,可以使用poster属性为<video>占位。实现如下:


<video controls preload="none" poster="replace.jpg">
  <source src="main.webm" type="video/webm">
  <source src="main.mp4" type="video/mp4">
</video>
复制代码


(2)视频代替GIF动画

在业务开发中,我们应尽量使用视频代替尺寸过大的GIF动画,虽然GIF动画应用范围很广, 但是其在输出文件大小、图像色彩质量等方面均不如视频。GIF动画相对于视频具有三个附加的特性:没有音轨、连续循环播放、加载完自动播放,替换成视频后类似于:


<video controls autoplay loop muted playsinline>  
  <source src="main.webm" type="video/webm">
  <source src="main.mp4" type="video/mp4">
</video>
复制代码


其中video标签中附加的属性的含义分别为:autoplay自动播放、muted静音播放、loop循环播放、playsinline用于在ios系统中自动播放。这样,视频就基本实现了一个GIF动画的效果。


实际上,很多浏览器并不能像Chrome浏览器一样,能自动进行延迟加载。下面就来通过一些配置,使得该场景的视频也能延迟加载。首先需要修改HTML标签:

<video controls autoplay loop muted playsinline height:"500" width: "800" poster="replace.jpg">  
  <source data-src="main.webm" type="video/webm">
  <source data-src="main.mp4" type="video/mp4">
</video>
复制代码


这里为video标签添加了poster属性,用来指定图片为视频延迟加载出现前的占位,还使用了类似于图像懒加载的方式,将视频的真实地址放在了data-src中。下面就基于 Intersection Observer,用JavaScript实现对延迟加载的控制:


Document.addEventListener("DOMContentLoaded", () => {
    const lazyVideos = [].slice.call(document.querySelectorAll("video.lazy"));
    if("IntersectionObserver" in window) {
      const lazyVideoObserver = new IntersectionObserver((entries, observer) => {
          entries.forEach((video) => {
              if(video.isIntersecting) {
                for(const source in video.target.children) {
                    const videoSrc = video.target.children[source];
                    if (typeof videoSrc.tagName === "string" && videoSrc.tagName === " source") {
                        videoSrc.src = videoSrc.dataset.src;
                    }
                }
                video.target.load();
                video.target.classList.remove("lazy");
                lazyVideoObserver.unobserve(video.target);
              }
          })
      }) 
      lazyVideos.forEach((lazyVideo) => {
          lazyVideoObserver.observe(lazyVideo);
      });
    }
})
复制代码


对于视频的延迟加载有点类似于图片的懒加载,需要对所有source子元素进行迭代解析,将data-src的属性值迁移到src上。不同的是,需要额外显示调用元素的load方法来触发加载,然后视频才会根据autoplay属性开始进行自动播放,这样就能使用低于GIF动画的流量消耗,进行资源的延迟加载。

相关文章
|
前端开发 JavaScript API
(前端3D模型开发)网页三维CAD中加载和保存STEP模型
本文介绍了如何使用`mxcad3d`库在网页上实现STEP格式三维模型的导入与导出。首先,通过官方教程搭建基本项目环境,了解核心对象如MxCAD3DObject、Mx3dDbDocument等的使用方法。接着,编写了加载和保存STEP模型的具体代码,包括HTML界面设计和TypeScript逻辑实现。最后,通过运行项目验证功能,展示了从模型加载到保存的全过程。此外,`mxcad3d`还支持多种其他格式的三维模型文件操作。
1625 122
|
缓存 前端开发 UED
如何优化前端性能以提高加载速度
前端性能优化对提升网站加载速度至关重要,直接影响用户体验、SEO排名和转化率。本文介绍了优化前端加载速度的关键技巧,包括最小化HTTP请求、使用CDN、优化图片、利用浏览器缓存、压缩文件和实现懒加载。通过这些方法,可以显著减少页面加载时间,提高网站的整体性能和用户满意度。
|
前端开发 JavaScript 索引
前端性能优化:虚拟滚动技术原理与实战
前端性能优化:虚拟滚动技术原理与实战
1625 80
|
缓存 监控 前端开发
前端性能优化:现代框架的关键策略
前端性能优化:现代框架的关键策略
543 74
|
前端开发 JavaScript 开发者
前端 CSS 优化:提升页面美学与性能
前端CSS优化旨在提升页面美学与性能。通过简化选择器(如避免复杂后代选择器、减少通用选择器使用)、合并样式表、合理组织媒体查询,可减少浏览器计算成本和HTTP请求。利用硬件加速和优化动画帧率,确保动画流畅。定期清理冗余代码并使用缩写属性,进一步精简代码。这些策略不仅加快页面加载和渲染速度,还提升了视觉效果,为用户带来更优质的浏览体验。
|
10月前
|
存储 前端开发 安全
实现“永久登录”:针对蜻蜓Q系统的用户体验优化方案(前端uni-app+后端Laravel详解)-优雅草卓伊凡
实现“永久登录”:针对蜻蜓Q系统的用户体验优化方案(前端uni-app+后端Laravel详解)-优雅草卓伊凡
389 5
|
缓存 前端开发 JavaScript
前端性能优化:打造流畅的用户体验
前端性能优化:打造流畅的用户体验
|
人工智能 JavaScript 前端开发
Vue 性能革命:揭秘前端优化的终极技巧;Vue优化技巧,解决Vue项目卡顿问题
Vue在处理少量数据和有限dom的情况下技术已经非常成熟了,但现在随着AI时代的到来,海量数据场景会越来越多,Vue优化技巧也是必备技能。 博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
机器学习/深度学习 前端开发 算法
婚恋交友系统平台 相亲交友平台系统 婚恋交友系统APP 婚恋系统源码 婚恋交友平台开发流程 婚恋交友系统架构设计 婚恋交友系统前端/后端开发 婚恋交友系统匹配推荐算法优化
婚恋交友系统平台通过线上互动帮助单身男女找到合适伴侣,提供用户注册、个人资料填写、匹配推荐、实时聊天、社区互动等功能。开发流程包括需求分析、技术选型、系统架构设计、功能实现、测试优化和上线运维。匹配推荐算法优化是核心,通过用户行为数据分析和机器学习提高匹配准确性。
1315 4
|
缓存 监控 前端开发
探索前端性能优化:关键策略与代码实例
本文深入探讨前端性能优化的关键策略,结合实际代码示例,帮助开发者提升网页加载速度和用户体验,涵盖资源压缩、懒加载、缓存机制等技术。

热门文章

最新文章

  • 1
    前端如何存储数据:Cookie、LocalStorage 与 SessionStorage 全面解析
    1239
  • 2
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(九):强势分析Animation动画各类参数;从播放时间、播放方式、播放次数、播放方向、播放状态等多个方面,完全了解CSS3 Animation
    553
  • 3
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(八):学习transition过渡属性;本文学习property模拟、duration过渡时间指定、delay时间延迟 等多个参数
    427
  • 4
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(七):学习ransform属性;本文学习 rotate旋转、scale缩放、skew扭曲、tanslate移动、matrix矩阵 多个参数
    428
  • 5
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(六):全方面分析css的Flex布局,从纵、横两个坐标开始进行居中、两端等元素分布模式;刨析元素间隔、排序模式等
    539
  • 6
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(五):背景属性;float浮动和position定位;详细分析相对、绝对、固定三种定位方式;使用浮动并清除浮动副作用
    719
  • 7
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(四):元素盒子模型;详细分析边框属性、盒子外边距
    1397
  • 8
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(三):元素继承关系、层叠样式规则、字体属性、文本属性;针对字体和文本作样式修改
    308
  • 9
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(二):CSS伪类:UI伪类、结构化伪类;通过伪类获得子元素的第n个元素;创建一个伪元素展示在页面中;获得最后一个元素;处理聚焦元素的样式
    1164
  • 10
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(一):CSS发展史;CSS样式表的引入;CSS选择器使用,附带案例介绍
    497