JavaScript相关优化
把脚本放在页面底部
放在前面js加载会造成阻塞,影响后面dom的加载使用外部JavaScript和CSS
在现实环境中使用外部文件通常会产生较快的页面,因为 JavaScript 和 CSS 有机会被浏览器缓存起来。对于内联的情况,由于 HTML 文档通常不会被配置为可以进行缓存的,所以每次请求 HTML 文档都要下载 JavaScript 和 CSS。所以,如果 JavaScript 和 CSS 在外部文件中,浏览器可以缓存它们,HTML 文档的大小会被减少而不必增加 HTTP 请求数量。压缩JavaScript和CSS
压缩文件是为了降低网络传输量,减少页面请求的响应时间。减少DOM操作
操作dom会产生几种动作,极大的影响渲染的效率。其中layout(布局)和paint(绘制)是最大的。-
js开销缩短解析时间
开销:加载-》解析和编译-》执行
js的解析和编译,执行要花很长时间(谷歌开发工具中的performance中可以查看。选中main主线程中的某一段。)
解决方案:- 代码拆分按需加载
- tree shaking代码减重
- 避免长任务
- requestAnimationFrame和repuestIdleCallback进行时间调度
-
v8编译原理(代码优化)
- 解析js代码成抽象语法树-》字节码-》机器码
编译过程会进行优化
运行时可能会发生反优化 - v8内部优化
脚本流:边下载边解析
字节码缓存:常用的字节码会存起来(这个文件用到其他的文件也用到的参数)
函数懒解析:先解析用到的 - 对象优化(迎合v8进行优化)
保证对象初始化顺序一致(对象初始化时v8会生成隐藏属性以便后续复用并且是按照顺序排序的)
不要直接赋值对象新属性(追加的属性需要通过描述数组间接查找)
使用数组代替类数组(v8会对数组进行优化)比如先将类数组转化成数组
避免读取数组越界(比如for循环多查找1个下标会照成性能相差6倍)
- 解析js代码成抽象语法树-》字节码-》机器码
造成undefined和数字比较
数组也是对象,当找不到对应下标的时候回沿着原型链向上找造成额外开销
业务上无效
- js内存,避免造成内存泄漏
通过变量是否能被访问到来判断内存是否释放。
- 局部变量: 函数执行完没有闭包引用会被标记回收
- 全局变量: 直到浏览器被卸载页面释放
- 回收机制:
引用计数:每调用一次加一,当计数为0的时候进行回收。缺点是不能解决循环引用(例如a对象依赖于b对象,标记清除(垃圾回收): 从根节点去访问,当访问到不能被访问的对象就进行标记然后进行垃圾回收。(当a对象
解决:避免意外的全局变量;避免反复运行引发的闭包;避免脱离的dom元素没有被回收(所以react有ref这个api)。
CSS 相关优化
- 把样式表放在<head>标签中
css放在head标签中比css放在body标签尾部少了一次构建RenderTree, 一次计算布局和一次渲染网页, 因此性能会更好。 - 不要使用CSS样式表
- 使用<link>替代@import
- 不要使用filter
- 避免元素类型转化(数组中放多种类型不利于v8引擎优化代码)
- 降低css对渲染的阻塞(按需加载,放在dom前面加载)
- 利用pu完成动画(前面讲到的复合)
- 使用contain进行优化(优化强度大。例如: contan:layout告诉浏览器这个节点内部的子元素和外面的使用font-display进行优化:让文字更早的显示在页面上,减轻文字闪动的问题
html 相关优化
- 减少iframes使用
- 压缩空白符
- 避免嵌套层次太深
- 避免使用table布局
- 减少没必要的注释
- 删除元素默认属性(比如默认checkbox等)
开发内容相关优化
- 减少HTTP请求数
- 减少DNS重定向
- 缓存AJax请求
- 延迟加载
- 预加载
- 减少DOM元素的数量
- 划分内容到不同域名
- 尽量减少使用iframe
- 避免404错误
服务器相关优化
- 使用CDN
- 添加Expires或Cache-Control响应头
- 启用Gzip
- 配置Etag
- 尽早输出缓冲
- Ajax请求使用GET方法
- 避免图片src为空
- 传输加载优化
服务器启用gzip - keep Alive(持久TCP连接)
keepalive_requests 100;请求100次后开启http的keepAlive有keepalive_timeout 65;65秒后关闭。 - http缓存
最好是用no-cache(要用的时候需要在服务器那边Etag验证下) - service workers
- 加速重复访问
- 离线支持
Cookie相关优化
- 减少cookie大小
- 静态资源使用无cookie域名
首屏加载优化
- 资源压缩、传输压缩、代码拆分、tree shaking、http缓存
- 路由懒加载、预渲染、inlineCss、虚拟列表
- prefetch和preload调整加载顺序js内存管理