资源的合并与压缩
- 核心
- 减少http请求数量
- 减少请求资源大小
- html压缩
- 在HTML中不显示的字符,包括空格、制表符、换行符等,还有一些其他意义的字符,如HTML注释也可以被压缩
- 压缩方法
- 使用在线网站进行压缩
- nodejs提供了html-minifier工具(构建时进行压缩)
- 后端模板引擎渲染压缩
- css压缩
- 无效代码删除(无意义字符)
- css语义合并(语义重复,需要进行合并)
- 压缩方法
- 使用在线网站进行压缩
- html中css使用html-minifier对html进行压缩
- 使用clean-css对css进行压缩
- JS压缩与混乱
- 无效字符的删除
- 剔除注释
- 代码语义的缩减和优化
- 代码保护
- 压缩和混乱方法
- 使用在线网站进行压缩
- 使用html-minifier对html中的js进行压缩
- 使用uglifyjs2对js进行压缩
- 文件合并
- 文件合并存在的问题
- 首屏渲染问题
- 缓存失效问题
- 合并方法
- 使用在线网站进行文件合并
- 使用nodejs实现文件合并
- 文件合并存在的问题
图片相关优化
- png8/png24/png32之间的区别
- png8: 256色+支持透明
- png24: 224色+不支持透明
- png32: 224色+支持透明
- 每种图片格式都有自己的特定,根据不同的业务场景选择不同的图片格式很重要
- 不同格式图片常用的业务场景
- jpg有损压缩,压缩率高,不支持透明(应用于大部分不需要透明图片的业务场景)
- png支持透明,浏览器兼容好(应用于大部分需要透明图片的业务场景)
- webp压缩程度更好,在ios webview有兼容性问题(应用于安卓全部)
- svg矢量图,代码内嵌,相对较小,图片样式相对简单的场景(应用于图片样式相对简单的业务场景,如iconfont)
- 图片压缩:针对真实图片情况,舍弃一些相对无关紧要的色彩信息
css和js加载与执行
-
一个网站在浏览器端是如何进行渲染的
- html通过网址请求回来,由字节流转换为字符流
- 浏览器进行词法分析,将html文档从上到下依次转换为词法token并添加到DOM树中
- script/link标签中的外部资源浏览器进行请求
- 浏览器V8执行引擎来执行
- css资源解析为CSSOM
- CSSOM+DOM TREE形成渲染树,再进行绘制
-
HTML渲染过程特点
- 顺序执行、并发加载
- 词法分析对html标签从上到下依次解析
- 并发加载:HTML中外部资源并发请求
- 并发上限:对某个域名下并发请求的数量是有限制的,因此需要托管到多个cdn
- 是否阻塞
- 依赖关系
- 引入方式
- 顺序执行、并发加载
-
css阻塞
- css head中阻塞页面的渲染(css通过link方式在head中引用,加载完再进行渲染)
- css不阻塞资源的的加载
- css阻塞js执行(因为js执行可能依赖css的样式)
-
js阻塞
- 直接引入的js(不用defer/async)阻塞页面的渲染
- js不阻塞资源的加载
- js顺序执行,阻塞后续js逻辑的执行
懒加载与预加载
- 懒加载
- 图片进入可视区域之后请求图片资源
- 对于电商等图片很多、页面很长的业务场景适用
- 减少无效资源的加载
- 并发加载的资源过多会阻塞js的加载,影响网站的正常使用
- 预加载
- 图片等静态资源在使用之前的提前请求
- 资源使用到时能从缓存中加载,提升用户体验
- 页面展示的依赖关系维护
- 懒加载和预加载使用场景
- 懒加载:电商网站图片很多,进入可视区域再加载图片
- 把图片的src置为空
- 图片的data-image属性存放图片真正地址
- 监听scroll事件,在scroll的回调中判断图片是否进入进入可视区(可视区高度clientHeight,图片当前位置通过getBoundingClientRect()来获取),如果在可视区,将data-image的值放入src中
- 预加载:抽奖页面图片的选中态和非选中态是两张图片,将两种图片预加载,需要时从缓存中加载;还有活动页是很多图片组成的动画,将所有动画帧加载完再进行播放
- 方法一:通过标签加载,并设置display:none,在需要时修改display
- 方法二:使用Image对象,new一个image对象,并且src为所需要预加载的资源
- 方法三:通过XMLHttpRequest对象。open所需的资源,再send,在callback中处理
- 方法四:使用preLoad库
- 懒加载:电商网站图片很多,进入可视区域再加载图片
重绘与重排
-
原理
- 浏览器一个线程=》Javascript解析,一个线程=》UI渲染,这两个线程是互斥的
- 频繁触发重绘与重排,会导致UI频繁渲染,阻塞JS
-
重排
- 当render tree中的一部分(或全部)因为元素的规模尺寸、布局、隐藏等改变而需要重新构建,这就称为重排(reflow)
- 当页面布局和几何属性改变时就需要重排
-
重绘
- 当render tree中的一些元素需要更新属性,而这些属性只是影响元素的外观、风格,而不影响布局的,比如background-color,就称为重绘(repaint)
- 重排必定引起重绘,重绘未必引发重排
-
避免重绘重排的方法
- 触发页面布局的属性
- 盒子模型相关属性会触发重布局
- 定位属性及浮动也会触发重布局
-
改变节点内部文字结构也会触发重布局
-
只触发重绘的属性
- 方法
- 避免使用触发重绘、重排的css属性
-
将频繁重绘重排的DOM元素作为一个单独的图层,那么这个DOM元素的重绘和重排的影响只会在这个图层中
- 触发页面布局的属性
利用Chrome的performance进行性能分析
-
常见优化点
- 用translate替代top/left等(translate不会触发重排 )
- 用opacity替代visibilitiy(opacity不会触发重排重绘,visibility会触发重绘 )
- 不要一条条修改DOM样式,预先定义好class,然后修改DOM的className
- 把DOM离线后在修改,比如讲DOM先display:none,进行一系列操作修改后,再把它显示出来
- 不要把DOM节点的属性值(如offsetHeight/offsetWidth)放在一个循环里当初循环里的变量
- 不要使用table布局,可能很小的改动会造成整个table的重新布局
- 动画实现速度的选择,动画频率过高导致频繁重排重绘,会阻塞js线程
- 对于动画新建图层(重排重绘减小影响面,will-change:transform;transform:translateZ(0))
- 启用GPU硬件加速
浏览器存储
- 浏览器存储
- cookie
- 因为HTTP请求无状态,所以需要cookie去维持客户端状态
- http response header中set-cookie放入浏览器cookie中(cookie由服务端生成,客户端存储)
- js中可通过document.cookie来读写cookie
- cookie存储的限制
- 作为浏览器存储,大小4kb左右
- 需要设置过期时间expire
- cookie是域名维度下的概念,所有这个域名都会携带cookie,造成cdn的流量损耗(cdn域名和主站域名区分开,cdn存放静态文件,这样请求静态页面就不会携带cookie)
- localStorage
- html5设计出来专门用于浏览器存储的
- 大小为5M左右
- 仅在客户端使用,不和服务端进行通信
- 接口封装较好
- 浏览器本地缓存方案
- sessionStorage
- 会话级别的浏览器存储
- 大小为5M左右
- 仅在客户端使用,不和服务端进行通信
- 接口封装较好
- 浏览器本地缓存方案
- indexedDB
- 用于客户端存储大量结构化数据,使用索引来实现对该数据的高性能搜索
- 为应用创建离线版本
- cookie
- PWA
- 一种Web App新模型(Progressive Web Apps)
- 可靠:在没有网络的环境中也能提供基本的页面访问,而不会出现“未连接到互联网”的页面
- 快速:针对网页渲染及网络数据访问有较好优化
- 融入:应用可以被增加到手机卓明,并且和普通应用一样有全屏、推送等特性
- Service Worker
- Service Worker是一个脚本,浏览器独立于当前网页,将其在后台运行,为实现一些不依赖页面或者用户交互的特性打开了一扇大门。
- 拦截和处理网络请求,实现一个离线应用
- 使用Serviece Worker 在后台运行同时能和页面通信的能力,去实现大规模后台数据的处理
缓存策略
-
强缓存(浏览器端缓存策略)——服务器端改变,客户端无感知
- cache_control
- max-age:指定缓存最大有效时间
- s-maxage:指定pubilc缓存设备(如cdn)缓存有效时间
- no-cache:搭配max-age=0使用,发请求到服务端,从服务端的last-modifiy等信息来判断是否使用缓存
- no-store:不使用任何缓存策略
- expires
- 缓存过期时间,用来指定资源到期的时间,是服务器端的具体时间点
- 告诉浏览器在过期时间前浏览器可以直接从浏览器缓存取数据,无需再次请求
- cache_control
-
协商缓存(取到服务器端最新的版本)
- Last-Modified/If-Modified-Since(响应头/请求头)
- 基于客户端和服务端协商的缓存机制
- last-modified——响应头
- if-modified-since——请求头
- 需要与cache-control共同使用
- 缺点
- 某些服务端不能获取精确的修改时间
- 文件修改时间改了,但文件内容没有变
- Etag/If-None-Match
- 文件内容的hash值
- etag——响应头
- if-none-match——请求头
- 需要与cache-control共同使用
- Last-Modified/If-Modified-Since(响应头/请求头)
-
浏览器优先走强缓存,若过期,再看协商缓存
用chrome://cache查看缓存
-
浏览器缓存流程图
-
cache-control参数图
服务器端性能优化
- vue渲染有什么问题
- 先下载vue.js
- 执行vue.js代码
- 生成html页面
- 首屏性能不好
- 没有前端框架时,用jsp/php在服务器端进行数据的填充,发送给客户端就是已经充填好数据的html
- 优化方案
- 构建层模板编译
- 数据无关的prerender的方式
- 服务器端渲染