前端h5开发--性能优化小结

381 阅读6分钟

前言

性能优化那么重要吗?目前为止,开发移动端活动h5页面有快一年的时间,发现当用户打开你的活动,如果白屏很久首屏加载很慢,用户在漫长的等待中依旧看不到活动页面,直接就会退出去。在这个快准狠的时代,折损率是必须要考虑的问题。而性能的好坏直接影响到用户的体验。

2020年应届,目前开发了多种类型的活动。最开始只是图片处理,但是经过快一年时间,解决问题的思路有所改变。比如前端优化,应该从全局思考每个阶段做了什么,找到是否有可以提高性能的手段。目前总结出比较常用且通用的方法。

思考

1.地址栏中输入url,敲击回车到一个网页呈现在你眼中,到底发生了什么?

2.浏览器从加载到渲染到底做了什么?

3.如何全链路优化性能?

4.优化的参考指标有哪些?

内容

一、输入url的流程

1.DNS发起域名解析,会在缓存里先去查找是否有改域名的对应ip信息,如果没有,会递归的方式层层递归,直到找到需要的ip地址。

2.获得到对应的ip地址后,发送http请求。这里不得不提到CDN(内容分发网络),CDN就是就近访问。DNS服务可以根据LDNS来进行定位,调度服务器判断是来自某地的LDNS的服务器,调度服务器就会去访问该地的CDN服务。这样就能让用户访问到最优的cdn节点。CDN有缓存,责任直接返回资源。如果没有则向上访问直到找到文件会到达源站。并缓存该资源。服务器响应http请求,并返回对应的资源(html)

3.根据渲染树,浏览器或者是移动端的webView,绘制页面也最终呈现给用户。

图片1.png

二、加载到渲染的流程

图片2.png

三、性能优化:

1.网络请求

1)http2的多路复用

http1.1 中华人民共和国外交部网站

http2.0 天猫官网

对比HTTP/1.0 http/1.1 http/2.01)文件大小

代码的压缩,构建时比如空格、注释\console.log;减少文件体积

http/1.0: 每个TCP链接只能发送一个请求。数据发送完毕后,立即断开链接。如果需要请求其他资源就需重新建立新的链接。

http/1.1 引用了持久链接,TCP默认不关闭,可以多个请求复用。同时还引入了管道机制,允许一个TCP链接里面,同时发送多个请求。

但是,数据的通讯是有顺序的。必须一个处理完,才会进行下一个的回应。

http/2.0 帧与流。同时发送多个请求和响应,对同一个请求或响应的所有数据包做了一个独一无二的标识,所以可以不用等待发送。两端会根据标识组装数据流。

2)gzip资源上传

前端打包压缩可以减少服务器压缩的时间,减少服务器的开销。在webpack中可以配置,开启构建时打包

const FileManagerPlugin = require('filemanager-webpack-plugin'); // webpack zip

3)减少http请求的次数(精灵图)

4)上传到CDN

5)按需加载

使用webpack将第三方引入分开打包,改用末端js直接引入

//告知第三方引用库不加入webpack打包, 在webpack的配置文件中   
externals: {       
    'phaser': 'Phaser'  
}

6)预加载与懒加载

第二屏的预加载 以及第一屏非首屏部分懒加载

预加载:在App.vue mouted中直接使用

function preLoading(arr,delay,callback) {    
    setTimeout(() => { 
        for(let imgUrl of arr) { 
                let im = new Image();            
                im.src = imgUrl;           
                im.onload = () => {       
                    callback()           
                };          
            }       
    }, delay); 
} 
 //调用预加载 
 preLoading([ '//a.com/again/one.png.webp', '/a.com/again/two.png.webp'],1000,()=>{console.count()})

js懒加载:使用vue-lazyLoad:当滚动条滚动到视口可以展示出元素的时候,再请求该图片资源

2.文件加载

1)文件大小

代码的压缩,构建时比如空格、注释\console.log;减少文件体积

webpackconfig = 
{   ...
    plugins: [
        new HtmlWebpackPlugin({
        template: 'src/index.html',
        minify: {
            removeComments: true, //移除注释
            collapseWhitespace: true, //移除空格
            removeAttributeQuotes: true //移除属性上的引号     
        },   
        }),   
    ] 
} 
//去掉console.log 
webpackconfig = {
... 
optimization: { 
    minimize: true, 
    minimizer: [   
        ...           
        new TerserPlugin({ 
            terserOptions: { 
            sourceMap: true,
            compress: {                      
                drop_console: process.env.NODE_ENV === 'production' 
                //生产环境删除console.log           
           }, 
            format: {
                comments: false //构件时去除注释   
            }               
        }, 
        extractComments: false //单独剥离注释           
        })       
    ], 
} 
}

2)图片大小

TinyPNG压缩(tinypng.com/) webp后缀、移动端使用设计稿75%展示、背景图片重复单元平铺使用

注明:webp是一种图片的格式,可以在保证图片的质量,根据一定的算法,将图片的大小压缩,在移动端是很好一种图片处理的方式。

3)首屏资源大小

移动端首屏资源最好打包后控制1M

3.页面渲染

1)js滞后

第三方引用js放在main.js 尾部

2)模糊图片先渲染后清晰图片替换

img.src = blur.png;
img.onload = ()=>{ 
    img.src = null; 
    //替换成清晰图片 
    loadClearPic(img,clearPic);
} 
const loadClearPic = (obj,clearUrl)=>{ 
    let imgObj = new Image(); 
    imgObj.src = clearUrl;
    imgObj.onload = function () {
        obj.src = clearUrl;
    };
}

3)减少DOM的嵌套

4)防止多次渲染(防抖与节流)

防抖:比如监听滚动的时候会一直执行scroll函数,采用防抖,在执行滚动的一定时间后再进行打印(应用场景:疯狂点击,滚动页面)

function debounce(fn, delay) {
    let timer = null; //借助闭包   
    return function () {
        if (timer) {
            clearTimeout(timer);
        } 
        timer = setTimeout(fn, delay);
    };
}
function showTop() {
    var scrollTop = document.body.scrollTop || document.documentElement.scrollTop;       
    console.log("滚动条位置:" + scrollTop); 
 } 
window.onscroll = debounce(showTop, 1000);

节流:当用户一直在滚动页面,也会在控制台中定时间执行scroll函数(应用场景: 搜索框实时查询,浏览器页面resize)

function showTop() {
var scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
console.log("滚动条位置:" + scrollTop); }
//节流
function throttle(fn,delay) {
    let timer = true; 
    return function() { 
        if(!timer) {            
            return false;     
        }     
        timer = false;   
        setTimeout(()=>{   
            fn();      
            timer = true;  
        },delay)   
    } 
}
window.onscroll = throttle(showTop,1000)

5)服务器渲染

服务端直接渲染生成页面上的内容,浏览器直接显示服务端返回的html

4.代码书写

1)样式优化

a.样式继承、采用类名增删而不是逐一更改样式

b.避免回流减少重绘

回流:更改布局后就会造成回流

重绘:例如颜色背景的修改,不涉及布局

注意: 一般自适应布局,多使用display:flex,比float性能好

c.使用css3动画代替帧动画

d.复杂动画在不影响视觉的时候可以减帧展示

2)脚本优化

a.先处理数据后一次性修改Dom

b.减少对Dom的频繁操作,比如Vue是数据驱动的框架

四、性能指标参考

1.lighthouse

chrome插件,一般优化在评分为80以上,是一个有消耗性能的页面

2.report.js

webpack中可以实现构建时生成性能报告,后续针对哪个包体大,逐一优化。

const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;

3.performance

总结

以上是一些h5页面的优化方式,但是具体的问题还需要具体分析。

然,目前学习还是很浅显的,很多时候还是处在一种会使用,遇到问题就百度的阶段。虽然可以快速处理遇到的问题,但是整体的知识体系还是很零散。所以利用一些时间,重新回顾一下自己。

最后想说,学习是一个循序渐进的过程,不能急于求成。很多时候,我们是需要一个停下来并回头看看的过程的。