web性能优化指南

前端性能优化,是每个前端必备的技能,优化自己的代码,使自己的网址可以更加快速的访问打开,减少用户等待,今天就会从几个方面说起前端性能优化的方案,

看下面的一张图,经常会被面试官问,从输入URL到页面加载完成,发生了什么?

1.用户输入www.baidu.com
2.浏览器通过DNS。吧url解析ip
3.和ip地址建立TCP连接,发送HTTP请求
4.服务器接收请求,查库,读文件等,拼接好 返回的HTTP响应
5.浏览器收到首屏html,开始渲染,
6.解析html位dom
7.解析css为css-tree
8.dom+css生成render-tree绘图
9.加载script的js文件
10.执行js文件

DNS缓存

 DNS是“域名系统”的缩写,它的工作是将域名和主机名转化为服务器主机的 IP 地址;

  DNS查找流程:浏览器缓存 — 本地hosts文件 — 本地DNS解析器缓存 — 本地DNS服务器 — 本地DNS服务器设置(是否设置转发器)— 根DNS服务器

 浏览器缓存之客户端缓存

    无需请求的memory cache,disk cache;

    需要发请求验证的Etag、Last-Modified304;

    H5新增的 localStorage、sessionStorage;

  合理利用以上缓存,可以很大程度上提高前端性能。

 网站存在缓存怎么解决?

  1.文件加哈希

  1.上线之后,要求用户强刷新,这种问题,用文件名加指纹方式解决

  2. a.hash.js  hash是整个a.js文件的md5值,文件内容不变,hash不变,缓存生效

  2.缓存文件怎么解决

   1.加时间戳 <script src="/a.js?_t=xx">
   2.加版本号 <script src="/a.js?_v=1.6"> 比如jq,vue公用库,内容没有改变 重新加载
   3.加指纹 但是不产生新文件 <script src="/a.js?h=abcd12sa"> 不能清除Cdn缓存,但是生成新文件,会有问题(html,js那个先上)
   4.最终,诞生最优的产生文件<script src="/a.abcd12sa.js">先上js,在上html webpack build 打包

优化策略

 1.长连接

  2.减少文件体积   

   1.js打包压缩

      1.无效字符的删除、剔除注释、代码语义的缩减与优化、代码保护

      2.使用在线网站压缩、使用 html-minifier 对html 中的 js 进行压缩、使用uglifyjs2 对 js 进行压缩

  2.图片压缩

      1.把网站上用到的一些图片整合到一张单独的图片中

  3.css压缩

     1.无效代码删除、css语义合并

      2.使用在线网站压缩、使用 html-minifier 对html 中的 css 进行压缩、使用clean-css 对 css 进行压缩

   4.html 压缩

     1.压缩在文本文件中有意义但是在HTML中不显示的字符,包括空格、制表符、换行符、注释等

      2.使用在线网站压缩、nodejs提供了html-minifier 工具、后端模板引擎渲染压缩

   5.开启 gzip

   6.文件合并

    1.如果不合并 === > 文件与文件之间有插入的上行请求,增加了N - 1 个网络延迟;受丢包问题影响更严重;经过代理服务器时可能会被断开

    2.如果合并 === > 首屏渲染时间变长; 文件缓存大面积失效

    3.公共库合并、不同页面的合并

    4.使用在线网站进行文件合并、使用 nodejs 实现文件合并

 3.减少文件请求次数

  1.雪碧图

  2.js,css打包

  3.缓存控制

  4.懒加载

 4.减少用户和服务器的距离

  (地理位置)

   1.cdn  js可以推到cdn缓存上

 5.本地存储

 

 浏览器缓存机制

  通过网络获取内容及速度缓存慢有开销巨大,较大相应需要在客户端与服务器之间进行多次往返通信,这回延迟浏览器获得处理内容的时间,还会增加访问者流量的费用,因此,缓存重复利用之前获取的资源能力成为性能优化的一个关键方面

  广义的缓存,可以分为四个,大家对httpcache比较熟悉

  1.Http Cache

  2.Service Worker Cache

  3.Memory Cache

  4.Push Cache

  Http Cache

   浏览器大佬:需要获取main.js,看下强缓存里有没有

  1.Expires和Cache-Control两个header来控制强缓存

   2.expires: Mon, 16 Mar 2020 09:50:27 GMT

   3.last-modified: Thu, 15 Feb 2018 14:17:52 GMT

  Memory Cache

    内存缓存,短命,比如常用数据js里,浏览器也有自己的策略,base64图片,体积小的静态资源

  Service Worker Cache

    是一种独立于主干线程之外的javascript线程,它脱离于浏览器窗体,算是幕后工作,可以实现离线缓存,网络代理等

图片优化

  图片通常是最占用流量的,pc端加载平均图片大小是600k,简直比js打包后的文件还大,所以针对图片的优化,不同场景,使用不同文化的类型

  1. jpg   

    1.有压缩

   2.体积小,不支持透明

     3.用于背景图,轮播图

  2.png

   1.无压缩,质量高,支持透明

   2.色彩线条更丰富,小图,比如logo,商品icon

  3.svg

   1.文本,体积小,矢量图

   2.渲染成本,学习成本

  4.图片打成雪碧图,减少http请求次数

gzip

  Http压缩就是以缩小体积为目的,对HTTP内容进行重新编码的过程

  Gzip压缩背后的原理,是在一个文本文件中找出一些重复出现的字符串,临时替换他们,从而、使整个文件变小,根据这个原理,文件找那个代码重复率越高,那么压缩的效率越高,使用Gzip收益就越大,反之亦然基本来说Gzip都是服务器干的活,比如nginx

本地存储

  常见本地存储格式有 cookie  localstroage sessionStroage  indexDB

   1.cookie

   最早,体积先定。性能浪费,所有请求都带上所有的当前域名的。

    因为 http 请求无状态,所以需要 cookie 去维持客户端状态

    cookie 生成方式:http response header 中的 set-cookie; js 中可以通过document.cookie读写cookie

    使用:用于浏览器端和服务器端的交互;客户端自身数据的存储

    过期时间:expire

    存储限制:作为浏览器存储,大小4kb左右;需要设置过期时间 expire

    cookie 存储能力被 localstorage 代替

    httponly 不允许 js 读写

    cookie 中在相关域名下面 --- cdn的流量损耗 。 解决:cdn 的域名和主站的域名要分开

  2.Web Storage

  1.存储量大,不自动发个服务器,js控制

   2.localstroage

     HTML5 设计出来专门用于浏览器存储的

       大小为 5M 左右

     仅在客户端使用,不和服务端进行通信

     接口封装较好

     浏览器本地缓存方案

   3.sessionStroage

    会话级别的浏览器存储

    大小为 5M 左右

    仅在客户端使用,不和服务端进行通信

    接口封装较好

    对于标表单信息的维护

  3.indexDB

  运行在浏览器上的非关系型数据库

  4.pwa

   基于缓存技术的应用模型

     可靠:在没有网络的环境中也能提供基本的页面访问

    快速:针对网页渲染及网络数据访问有较好的优化

融入:应用可以被增加到手机桌面,并且和普通应用一样有全屏、推送等特性

重绘与回流

  回流:当我们对DOM修改引发了DOM几何尺寸的变化(比如修改元素的宽,高度或者隐藏元素等)时,浏览器需要重新计算元素的几何属性,(其他元素的几何属性和位置也会因此受到影响),然后再将计算的结果绘制出来,这个过程就是回流(也加重排)

  重绘:当我们对DOM的修改导致了样式的变化,却并未影响几何属性,(比如修改了颜色和背景色)时,浏览器不需要重新计算元素的几何属性,直接为该元素绘制新的样式,(跳过了上图所示的回流环节)。这个过程叫做重绘

  由此我们可以看出,重绘不一定导致回流,回流一定导致重绘

  回流是影响最大的

  1.窗体,字体大小

  2.增加样式表

  3.内容变化

  4.class属性

  5.offserWidth和offsetHeight

  6.fixed

节流和防抖

  节流

    预定一个函数只有在大于等于执行周期时才执行,周期内调用不执行

// 函数节流  每隔多少时间执行一次
        const throttle = (func ,wait = 100) =>{
            // 无论调用多少次,函数都是100毫秒执行一次
            let lastTime =0;
            return(...args) =>{
                let now = new Date().getTime()
                if(now - lastTime >wait) {
                    func.apply(this.args)
                    lastTime = now
                }
            }
        }

        let i =1;
        window.addEventListener(‘scroll‘,throttle(()=>{
            // 使用做图片懒加载
            console.log(i)
            i+=1
        },350)) 

  

  防抖

    在函数需要频繁触发时,只有当有足够空闲的时间时,才执行一次


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

/*

            校验用户是不是重复,用户输入完,向后端发送请求

            如果用户每次输入,都发生请求,造成请求过多

            用户停止输入字符串350毫秒,在发出

        */

        const debounce = (func,wait = 350) =>{

            let timer =0;

            return (...args)=>{

                if(timer) {

                    clearInterval(timer)

                }

                timer = setTimeout(() => {

                    func.apply(this,args)

                }, wait);

            }

        }

        let i =1;

        window.addEventListener(‘scroll‘,debounce(()=>{

            // 验证

            console.log(i)

            i+=1

        },350))

  lazy-load

  对于一些图片多,页面长的网页来说,如果每次打开页面加载全部的网页内容,页面加载速度势必会受到影响,如果每次打开网页只将网页可视区域的内容加载给用户 ,将大大提高网页浏览速度,同时也减轻服务器负载,我们可以使用lazyload.js来实现对图片的延迟加载,当网页图片进入到浏览器可视区域时,才会去请求服务器加载图片。

  

// 获取所有的图片
        const img = document.getElementsByTagName(‘img‘)
        // 获取可视区域的高度
        const viewHeight = window.innerHeight || document.documentElement.clientHeight;
        // num用于计算当前显示到那一张图片,避免每次都是从第一张开始检查是否漏出
        let num =0;
        function lazyload() {
            for(let i=num;i<img.length;i++) {
                // 用可是区域高度减去元素顶部距离可视区域顶部的高度
                let distance = viewHeight - img[i].getBoundingClientRect().top
                // 如果可视区域高度大于等于元素顶部距离可视区域顶部的高度,说明元素露出
                if(distance >=0) {
                    // 给元素写入真实的src,展示图片
                    img[i].src = img[i].getAttribute(‘data-src‘)
                    // 前i张图片已经加载完毕,,下次从第i+1张开始检查是否露出
                    num = i+1
                }
            }
        }
        // 监听scroll
        window.addEventListener(‘scroll‘,lazyload,false)

performance.getEntriesByType(‘navigation‘)  性能检测

  通过在浏览器控制台输入这个命令,就可以检测到网页加载数据,检测网页加载性能

  

  列入:

  DNS查询耗时 通过使用domainLookupEnd - domainLookupStart  就等于dns查询的时间

   TCP链接耗时  通过 connectEnd - connectStart

  HTTP请求耗时 通过 responseEnd - responseStart

   解析dom树耗时  通过 domComplete -  domInteractive

  白屏时间 通过 responseStart  - navigationStart

  DOMready时间 通过 domContentLoadedEventEnd - navigationStart

  onload时间 通过 loadEventEnd -  navigationStart 也即是onload回调函数执行的时间

Lighthouse插件

Lighthouse分析web应用程序和web页面,收集关于开发人员最佳实践的现代性能指标和见解,让开发人员根据生成的评估页面,来进行网站优化和完善,提高用户体验。

  1.可以在谷歌商店安装一个Lighthouse一个插件就可以了,下面我是检测github网站的数据

  2.使用node全局安装

npm install -g lighthouse

  安装完之后运行,也是找的github网址,运行成功之后,会弹出一个生成的html页面。

生成一个html文件,找到然后直接打开就行

 浏览器渲染

  

  1.在这一步浏览器执行了所有的加载解析逻辑,在解析HTML的过程中发出了页面渲染所需要的各种外部资源请求

  2.浏览器将识别并加载所有的css样式信息与dom树合并,最终胜出页面render树,(:after :brfore这样的伪元素在这个环节被构建到DOM树中)

  3.页面中所有元素相对位置信息,大小等信息均在这一步得到计算

  4.在这一步浏览器会根据我们的DOM代码结果,把每一个页面图层转换为像素,并对所有的媒体文件进行解码

  5.最后一步浏览器会合并各个图层,讲数据有CPU输给GPU最终绘制在屏幕上,(复杂的视图会给这个阶段GPU计算带来一些压力,在实际中是为了优化动画性能,我们有时候会手动区分各个视图)

  渲染过程说白了,首先是基于HTML构建一个DOM树,这颗DOM树与css解析器解析除的CSSOM相结合,就有了布局渲染树,最后浏览器以布局渲染树为蓝本,去计算布局并绘制图像,我们页面初次渲染就大功告成了。

  

  之后每当一个新元素加入到这个DOM树中,浏览器便会通过css引擎查遍css样式表,找到符合该元素的样式应用到这个元素上,然后在重新去绘制他

原文地址:https://www.cnblogs.com/adolfmc/p/12065776.html

时间: 2024-10-19 21:37:26

web性能优化指南的相关文章

web 性能优化指南阅读笔记

1.关于拥塞预防算法 PRR-比例降速,RFC6937 规定的一个新算法,其目标是改进丢包后的恢复速度,谷歌测量结果:该算法改进丢包造成的平均连接延迟减少了3%-10%.PRR是linux 3.2+内核默认的用赛预防算法. 2.关于拥塞窗口 把服务器的初始CWND值增大到RFC 6928新规定的10段,是提升用户体验以及所有TCP 应用性能的最简单方式.Linux上,IW10是2.6.39以上版本内核的新默认值. web 性能优化指南阅读笔记

Spark性能优化指南——高级篇

Spark性能优化指南--高级篇 [TOC] 前言 继基础篇讲解了每个Spark开发人员都必须熟知的开发调优与资源调优之后,本文作为<Spark性能优化指南>的高级篇,将深入分析数据倾斜调优与shuffle调优,以解决更加棘手的性能问题. 数据倾斜调优 调优概述 有的时候,我们可能会遇到大数据计算中一个最棘手的问题--数据倾斜,此时Spark作业的性能会比期望差很多.数据倾斜调优,就是使用各种技术方案解决不同类型的数据倾斜问题,以保证Spark作业的性能. 数据倾斜发生时的现象 绝大多数tas

Spark性能优化指南——基础篇

前言 在大数据计算领域,Spark已经成为了越来越流行.越来越受欢迎的计算平台之一.Spark的功能涵盖了大数据领域的离线批处理.SQL类处理.流式/实时计算.机器学习.图计算等各种不同类型的计算操作,应用范围与前景非常广泛.在美团•大众点评,已经有很多同学在各种项目中尝试使用Spark.大多数同学(包括笔者在内),最初开始尝试使用Spark的原因很简单,主要就是为了让大数据计算作业的执行速度更快.性能更高. 然而,通过Spark开发出高性能的大数据计算作业,并不是那么简单的.如果没有对Spar

移动H5前端性能优化指南

概述 1. PC优化手段在Mobile侧同样适用2. 在Mobile侧我们提出三秒种渲染完成首屏指标3. 基于第二点,首屏加载3秒完成或使用Loading4. 基于联通3G网络平均338KB/s(2.71Mb/s),所以首屏资源不应超过1014KB5. Mobile侧因手机配置原因,除加载外渲染速度也是优化重点6. 基于第五点,要合理处理代码减少渲染损耗7. 基于第二.第五点,所有影响首屏加载和渲染的代码应在处理逻辑中后置8. 加载完成后用户交互使用时也需注意性能优化指南 [加载优化] 加载过程

移动web性能优化笔记

移动web性能优化 最近看了一些文章,对移动web性能优化方法,做一个简单笔记 笔记内容主要出自 移动H5前端性能优化指南和移动前端系列——移动页面性能优化

美团Spark性能优化指南——基础篇

http://tech.meituan.com/spark-tuning-basic.html 前言 在大数据计算领域,Spark已经成为了越来越流行.越来越受欢迎的计算平台之一.Spark的功能涵盖了大数据领域的离线批处理.SQL类处理.流式/实时计算.机器学习.图计算等各种不同类型的计算操作,应用范围与前景非常广泛.在美团?大众点评,已经有很多同学在各种项目中尝试使用Spark.大多数同学(包括笔者在内),最初开始尝试使用Spark的原因很简单,主要就是为了让大数据计算作业的执行速度更快.性

【转载】 Spark性能优化指南——基础篇

前言 开发调优 调优概述 原则一:避免创建重复的RDD 原则二:尽可能复用同一个RDD 原则三:对多次使用的RDD进行持久化 原则四:尽量避免使用shuffle类算子 原则五:使用map-side预聚合的shuffle操作 原则六:使用高性能的算子 原则七:广播大变量 原则八:使用Kryo优化序列化性能 原则九:优化数据结构 资源调优 调优概述 Spark作业基本运行原理 资源参数调优 写在最后的话 前言 在大数据计算领域,Spark已经成为了越来越流行.越来越受欢迎的计算平台之一.Spark的

前端性能优化指南(含移动端)

概述 1. PC优化手段在Mobile侧同样适用2. 在Mobile侧我们提出三秒种渲染完成首屏指标3. 基于第二点,首屏加载3秒完成或使用Loading4. 基于联通3G网络平均338KB/s(2.71Mb/s),所以首屏资源不应超过1014KB5. Mobile侧因手机配置原因,除加载外渲染速度也是优化重点6. 基于第五点,要合理处理代码减少渲染损耗7. 基于第二.第五点,所有影响首屏加载和渲染的代码应在处理逻辑中后置8. 加载完成后用户交互使用时也需注意性能优化指南 [加载优化] 加载过程

Spark性能优化指南——基础篇转

前言 在大数据计算领域,Spark已经成为了越来越流行.越来越受欢迎的计算平台之一.Spark的功能涵盖了大数据领域的离线批处理.SQL类处理.流式/实时计算.机器学习.图计算等各种不同类型的计算操作,应用范围与前景非常广泛.在美团•大众点评,已经有很多同学在各种项目中尝试使用Spark.大多数同学(包括笔者在内),最初开始尝试使用Spark的原因很简单,主要就是为了让大数据计算作业的执行速度更快.性能更高. 然而,通过Spark开发出高性能的大数据计算作业,并不是那么简单的.如果没有对Spar