【前端工程化-性能优化】性能优化系列之用户体验的优化方案(渲染层面)

目录

前言

上一篇我们已经围绕“网络层面”探索页面性能优化的方案,接下来本篇围绕“浏览器渲染层面”继续开展探索。正文开始前,我们思考如下问题:

  1. 浏览器渲染页面会经过哪几个关键环节?“渲染层面”的优化从哪几方面着手?
  2. “渲染层面”的性能优化方案会有哪些?

渲染关键环节

【前端工程化-性能优化】性能优化系列之用户体验的优化方案(渲染层面)

页面渲染过程详见: 《10分钟看懂浏览器的渲染过程及优化》

优化原则

我们了解“页面渲染关键环节”后,便可知晓影响页面渲染性能的因素主要是静态资源:HTML、CSS、JS、图片等。因此“渲染层面”的性能优化方案主要就是围绕静态资源展开探索,其方案制定可围绕下面2个原则展开:

  • 尽可能减少资源个数
  • 尽可能减少资源体积大小

优化方案

【前端工程化-性能优化】性能优化系列之用户体验的优化方案(渲染层面)

HTML 优化

1.减少文件大小(压缩、精简)

  • 压缩处理 HTML,减小HTML体积
  • 精简 HTML:
    • 尽量减少 HMTL 嵌套、iframe/table 使用(table标签比其他html标签占用更多字节,导致下载时间长,占用服务器更多的流量资源)
    • 删除多余的空格、换行符、缩进和不必要注释
    • 删除冗余标签和属性

2.DOM 优化

  • 控制DOM大小:
    • 合理的业务逻辑拆分
    • 先加载可视区,其他延迟加载(懒加载)
  • 减少DOM操作:尽可能对DOM操作统一逻辑处理,或是使用虚拟DOM(借鉴vue/react),再插入到真实DOM(减少重排重绘)

CSS 优化

1. 减少资源请求个数

  • 合并多个 CSS 样式文件
  • 按需加载样式

2. 减少文件大小(压缩)

  • 压缩处理 CSS 文件
  • 在线压缩,例如CSS Minify
  • webpack压缩插件: css-minimizer-webpack-plugin

3. 减少文件大小(编码优化)

  • 位置放在<head>里,尽早地进行样式解析,构建CSSOM 树
  • 简化 CSS 选择器(选择器优先级:!important > 内联 > id > class|属性|伪类 > 标签 | 伪元素)
    • 尽可能减少样式层级数(选择器嵌套)
    • 少用标签选择器,尽量选择高优先级的id/class/属性/伪类选择器代替
    • 少用通配符*,只对需要修改样式的元素进行选择
    • 关注可继承属性,避免重复定义和匹配

可继承属性

  • 所有元素可继承:visibility 和 cursor。
  • 内联元素可继承:letter-spacing、word-spacing、white-space、line-height、color、font、 font-family、font-size、font-style、font-variant、font-weight、text- decoration、text-transform、direction。
  • 块元素可继承:text-indent和text-align。
  • 列表元素可继承:list-style、list-style-type、list-style-position、list-style-image。
  • 表格元素可继承:border-collapse。

总结:CSS继承特性主要是指文本方面的继承,而关于与盒模型相关的属性不支持继承。

  • 优化CSS编码风格,尽可能减少重排重绘
    • 元素显隐操作频繁,可设置 visibility: hidden,让元素占位不变,不会触发重排,仅触发重绘
    • 已知图片的宽高,样式可先设置width、height,避免图片下载后整个页面发生重排
    • 避免使用CSS表达式
    • 避免频繁设置同一div样式,可进行一次性更改
    • 动画使用绝对定位(脱离文档流)定位,避免触发重排

重排重绘具体可参考: github.com/GGXXMM/FE-K…

  • 精简 CSS,从而减少 CSS 文件大小
    • 使用缩写语句,如margin-top/bottom,直接用margin
    • 删除不必要的单位,如0px,直接写0
    • 删除过多分号
    • 删除空格和注释

JS 优化

1. 减少文件请求个数

  • 合并多个 JS 脚本文件
  • 首屏渲染暂不需要且体积大的脚本可进行按需加载(通过script动态创建加载)
  • 合理使用缓存
    • 业务中:
      • 非敏感固定的数据可使用本地存储 localStorage/sessionStorage/IndexedDB
      • 合理缓存 DOM 对象等
    • 构建打包(比如webpack):
      • 第三方模块缓存: hard-source-webpack-plugin、 DLL 动态链接库
      • loader 开启 cache 缓存

2. 减少文件大小

  • 压缩处理:在线压缩/Webpack插件(uglify/gzip)
  • 构建打包减小bundle体积
    • 开启 TreeShaking,剔除 Dead Code
    • 剥离第三方依赖,webpack配置externals
    • 提取公共模块:webpack4.x+ 配置 optimization.splitChunks(相当于webpack旧版本的CommonsChunkPlugin)

3. 编码优化

加载时

  • 位置放<body>底部,让JS不阻塞HTML和CSS的解析
  • 合理选择加载模式(减少重排重绘)
// 1. 正常模式
<script src="index.js"></script>
// 2. async 模式(异步执行)
<script async src="index.js"></script>
// 3. defer 模式(延迟执行)
<script defer src="index.js"></script>

一般当我们的脚本与 DOM 元素和其它脚本之间的依赖关系不强时,我们会选用 async;当脚本依赖于 DOM 元素时,我们会选用 defer。(合理选择 script 加载模式,可以有效地提升性能)

运行时

  • DOM 操作优化
    • 合并多次 DOM 操作,批量执行,减少重排重绘
    • 大数据量渲染优化:分页加载/虚拟列表 virtualList
  • 函数优化
    • 获取 DOM 元素,尽量使用id选择器
    • 尽量避免使用 eval
    • 使用事件节流/防抖函数
    • 使用事件委托
  • JS动画优化
    • 避免添加大量的 JS 动画
    • 简单动画尽量使用 CSS3 动画
    • 复杂动画尽量使用 Canvas 动画
    • 合理使用 requestAnimationFrame 动画代替 setTimeout、setInterval

    requestAnimationFrame 按照浏览器的刷新率(60Hz左右)来调动动画帧,从而实现更加流畅和高性能的动画效果。

  • 执行优化
    • 合理拆分执行任务
    • 大数据计算,可使用 Web Worker 开启独立于主线程的并行计算

图片优化

1.减少图片网络请求

  • 雪碧图CSS sprite
    【前端工程化-性能优化】性能优化系列之用户体验的优化方案(渲染层面)
  • 小图标使用web font字体代替
  • 小体积图片使用base64编码
    【前端工程化-性能优化】性能优化系列之用户体验的优化方案(渲染层面)
  • 阴影、简单动画图效可用CSS3代替
  • 图片懒加载/预加载

2.减小图片大小

  • 图片压缩,可选择如下方式:
    • 在线压缩: tinypng、 tinyjpg
    • 插件压缩:
      • 压缩png:node-pngquant-native(可压缩50-80%左右)
      • 压缩jpg:jpegtran(可压缩10%左右)
      • 压缩gif:gifsicle

3.合理使用图片格式

简介和特性 是否支持透明 支持颜色种数 压缩方式 浏览器兼容性 适用场景
jpg – 最常见、应用最广泛的图片格式
– 体积一般,通常小于 png, gif 等格式
不支持透明 约1600万种颜色 有损压缩 几乎所有浏览器都支持 呈现色彩丰富的图片,比如大背景图、轮播图或Banner图等
png8 – 一种无损压缩的高保真的图片格式
– 8位的png,体积较大
支持透明 256种(2^8) 无损压缩 几乎所有浏览器都支持 呈现小图片,比如小Logo、颜色简单对比强烈小图标
png24 – 一种无损压缩的高保真的图片格式
– 24位的png,体积较大
不支持透明 约1600万种颜色 无损压缩 几乎所有浏览器都支持 呈现颜色较多的图片,比如背景图
png32 – 一种无损压缩的高保真的图片格式
– 32位的png,体积大
支持半透明(8位透明通道) 2^32种 无损压缩 几乎所有浏览器都支持 呈现色彩丰富高清图片,比如海报
svg – 矢量图,任意缩放不影响清晰度
– 体积视内容而定
支持设置透明度 RGB/RGBA/十六进制设置颜色 支持有损和无损压缩 Chrome 4 (2010年1月发布)以上版本支持
caniuse.com/svg
适用任意缩放不失真的场景
gif – 支持动态图片
– 压缩率较高
– 体积较小
支持透明 256种(2^8) 无损压缩 Chrome 58(2017年6月发布)以上版本支持
caniuse.com/gif
适用于色彩较少的动图
webp – 支持动态图片
– 压缩率较高
– 体积较小
支持透明 约1600万种颜色 有损和无损压缩 Chrome 32(2014年1月发布)以上版本支持,兼容性不太好
caniuse.com/webp
兼容性要求不高的多种图片格式场景

4.图片加载优化

  • 懒加载

图片列表一般采用懒加载进行按需加载,滚屏时当图片已将出现在可视区域的时候进行加载。(有效地减轻服务器批量加载图片的压力)

let imgList = [...document.querySelectorAll('img')];
let len = imgList.length;

const lazyLoad = (function(){
  let count = 0;
  return function() {
    let deleteIndexList = [];
    imgList.forEach((img,index)=> {
      let rec = img.getBoundingClientRect();
      if(rec.top < window.innerHeight) {// 元素出现在可视区(window.innerHeight:可视窗口的高度)
        img.src = img.dataset.src; // 将data-src设置成图片src
        deleteIndexList.push(index);
        count++;
        if(count === len) {// 当图片都加载完,移除滚动监听事件
          document.removeEventListener('scroll', lazyLoad)
        }
      }
    })
    imgList = imgList.filter((img, index)=> !deleteIndexList.includes(index))
  }
})()

// 节流函数
const throttle = function(fn, timing = 500) {
  let prev = 0
  return function() {
    let now = +new Date();
    if(now - prev > timing) {
      prev = now;
      fn.apply(this, arguments)
    }
  }
}
// 滚动监听加上节流控制
const _throttle = throttle(lazyLoad)
document.addEventListener('scroll', _throttle)
  • 预加载

预加载preload,在大图片加载完成前先加载小的loading,用于提升用户体验。(该优化思想不仅可以用于图片加载,也能用于异步请求、html标签预加载)

// 创建 img 图片元素
const myImage = (function(){
  let imgNode = document.createElement('img')
  document.body.appendChild( imgNode )
  return {
    setSrc: function(src) {
      imgNode.src = src
    }
  }
})()

/**
 * 预加载
 */
const preLoad = (function(){
  let img = new Image();
  img.onload = function() {
    myImage.setSrc( this.src )// this指向img
  }
  return {
    setImg: function(src) {
      myImage.setSrc('./img/loading.gif')
      img.src = src
    }
  }
})()

preLoad.setImg('./img/bg_gaoqing.jpeg')
  • 渐进式加载

具体实现可参考: juejin.cn/post/703378…

5.响应式图片,随窗口大小变化

  • CSS媒体查询 @media 设置响应式
.bg {
    /* 正常(未缩小屏幕)加载大尺寸图片 */
    background-imageurl('img_flowers.jpg');
}
/* 当屏幕宽度小于400 */
@media screen and (max-width: 400px) {
    .bg {
        background-imageurl('img_smallflower.jpg');
    }
}
  • srcset属性设置响应式
<picture>  
  <source srcset="img_smallflower.jpg" media="(max-width: 400px)">
  <img src="img_flowers.jpg" alt="Flowers">
</picture>

相关专栏文章:

  1. 【前端工程化-性能优化】性能优化系列之用户体验(概要篇)
  2. 【前端工程化-性能优化】性能优化系列之用户体验的问题分析与定位
  3. 【前端工程化-性能优化】性能优化系列之用户体验的优化方案(网络层面)
  4. 【前端工程化-性能优化】性能优化系列之用户体验的优化方案(渲染层面)
  5. 【前端工程化-性能优化】性能优化系列之用户体验的应用案例

原文链接:https://juejin.cn/post/7315846848459440165 作者:小铭子

(0)
我心飞翔我心飞翔
0 0
Math.js:一款 JavaScript 和 Node.js 最强数学库
上一篇 2023年12月26日 上午10:41
百度考题:反复横跳的个性签名
下一篇 2023年12月26日 上午10:51

相关推荐

  • JavaScript的new、Object.create()详解 –每天进步一点点 2021年6月1日
  • Node.js 的架构知识 2024年1月30日
  • (你也不想那个啥也不懂的测试嘲笑你吧)H5开发过程中那些不要碰的CSS选择器 2024年3月19日
  • 用threejs实现人物控制-基础篇 2024年3月30日
  • 项目代码规范-Eslint+ Prettier+ commitlint 2023年6月4日
  • 【three.js系列二】入门教程——几何体 2024年3月2日
  • Leetcode 刷题 92. 反转链表 II 2024年2月10日
  • Django基础教程:被解放的姜戈05 黑面管家 2019年3月6日
  • 从零开始搭建一个高颜值后台管理系统全栈框架(二)——后端框架搭建 2023年5月25日
  • 深入探究 LowCode 与 DSL 技术 2024年1月26日

发表回复

登录后才能评论

近期文章

  • 一文详解比特币的P2PKH地址类型
  • 在 Vue 中实现类似 ahooks useRequest 的异步请求 Hook
  • 使用 nuqs 在 Next.js 中管理 URL 查询字符串状态
  • JavaScript的Iterator和for…of循环
  • 手把手使用Blender+ThreeJS制作跨栏小游戏
  • CSS的三大魔法特性:层叠、继承与优先级,让你的网页设计如虎添翼!
  • docusaurus中引入shiki实现代码高亮
  • 浏览器中如何获取用户网络状态
  • 完全掌握vue全家桶单元测试 : 6. 深入理解组件测试
  • InqureJS:手搓脚手架必备!让你的命令行交互花里胡哨!
  • 【vite.config.ts】(多环境配置)设置环境文件 .env.local
  • 腾讯、阿里、B站最新面经汇总,有的妥妥的凉经
  • 带你深入Vue.js开发实战,从复杂列表的样式到性能优化
  • 『Django』路由urls
  • go语言如何实现协程的抢占式调度的?
  • 字节面试:如何解决MQ消息积压问题?
  • web server apache tomcat11-16-mbean
  • web server apache tomcat11-17-default-servlet
  • ✅MySQL的脏读、幻读、不可重复度是什么
  • tailwindcss Vue项目CSS开发体验
  • 简单的题,内涵不简单
  • AOP使用案例-记录操作日志
  • 计算机基础系列 —— 虚拟机代码翻译器(2)
  • flea-common使用之本地国际化实现
  • 锁、mvcc、隔离级别、(脏读、不可重复读、幻读)理解
  • 【java】使用表达式处理数据 – Aviator
  • python数据类型-字符串
  • 原生桥接方式:深入了解JavaScript Bridge(JsBridge)
  • 邀请函 | Pulsar Meetup 深圳 2024
  • TTFB时间太长怎么办

知识题库

  • 手把手教你vue项目接入漂亮的验证码
  • 校招前端二面经典react面试题及答案_2023-03-13
  • 字节前端二面react面试题(边面边更)_2023-03-13
  • 滴滴前端一面常考vue面试题(持续更新中)_2023-03-13
  • new Vue的时候到底做了什么_2023-03-13
  • 滴滴前端高频vue面试题(边面边更)_2023-03-13
  • 为啥我要选用Element作为wljslmz.cn子系统的UI框架?
  • vue-cli 是怎么配置babel的?
  • 面试官问我按钮级别权限怎么控制,我说v-if,面试官说再见
  • Vue项目迁移小程序,实操干货分享
  • Element ui: form表单使用
  • vue中加入百度统计
  • 前端开发:如何写一手漂亮的 Vue
  • Vue-travel学习笔记
  • 前端开发者不得不知道的18个常用的网站
  • vue-awesome-swiper的用法&同一页面有多个swiper如何使用
  • 结合 Bootstrap + Vue 组件实现 Laravel 异步分页功能
  • 在 Vue.js 中通过计算属性动态设置属性值
  • Vue 组件注册:基本使用和组件嵌套
  • Vue 组件插槽:父子组件间的内容分发和插槽作用域

深圳坪山网站建设公司济宁章丘网站seo优化公司优化网站排名提高桐乡网站关键词优化排名松江区企业网站优化定制方案河南网站全网优化企业网站内容优化机械设备网站优化引流定西网站优化推广公司哪家口碑好怀宁网站优化哪家性价比高嘉定区谷歌网站优化徐汇区企业网站优化方案武侯区网站优化排名公司多图网站优化sem网站优化案例外贸网站推广优化沈阳网站优化代理宁德关键词网站优化排名安阳专业网站优化哪家好网站内部优化公司怎样做网站关键词优化深圳南山区网站seo优化排名品牌网站推广优化涧西网站优化怎么选沧州沧县网站优化网站免费seo优化优化排名网站哪家好郑州网站优化工具都匀网站优化公司电话藁城seo网站优化黄冈低成本网站优化哪家好香港通过《维护国家安全条例》两大学生合买彩票中奖一人不认账让美丽中国“从细节出发”19岁小伙救下5人后溺亡 多方发声卫健委通报少年有偿捐血浆16次猝死汪小菲曝离婚始末何赛飞追着代拍打雅江山火三名扑火人员牺牲系谣言男子被猫抓伤后确诊“猫抓病”周杰伦一审败诉网易中国拥有亿元资产的家庭达13.3万户315晚会后胖东来又人满为患了高校汽车撞人致3死16伤 司机系学生张家界的山上“长”满了韩国人?张立群任西安交通大学校长手机成瘾是影响睡眠质量重要因素网友洛杉矶偶遇贾玲“重生之我在北大当嫡校长”单亲妈妈陷入热恋 14岁儿子报警倪萍分享减重40斤方法杨倩无缘巴黎奥运考生莫言也上北大硕士复试名单了许家印被限制高消费奥巴马现身唐宁街 黑色着装引猜测专访95后高颜值猪保姆男孩8年未见母亲被告知被遗忘七年后宇文玥被薅头发捞上岸郑州一火锅店爆改成麻辣烫店西双版纳热带植物园回应蜉蝣大爆发沉迷短剧的人就像掉进了杀猪盘当地回应沈阳致3死车祸车主疑毒驾开除党籍5年后 原水城县长再被查凯特王妃现身!外出购物视频曝光初中生遭15人围殴自卫刺伤3人判无罪事业单位女子向同事水杯投不明物质男子被流浪猫绊倒 投喂者赔24万外国人感慨凌晨的中国很安全路边卖淀粉肠阿姨主动出示声明书胖东来员工每周单休无小长假王树国卸任西安交大校长 师生送别小米汽车超级工厂正式揭幕黑马情侣提车了妈妈回应孩子在校撞护栏坠楼校方回应护栏损坏小学生课间坠楼房客欠租失踪 房东直发愁专家建议不必谈骨泥色变老人退休金被冒领16年 金额超20万西藏招商引资投资者子女可当地高考特朗普无法缴纳4.54亿美元罚金浙江一高校内汽车冲撞行人 多人受伤

深圳坪山网站建设公司 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化