可以用到项目的优化网站加载速度方案

本文深入探讨了前端性能优化的各种策略,包括合并图标减少网络请求、使用base64替代小图片、图片懒加载与压缩、JS/CSS按需打包与加载、gzip压缩、webp格式优化等,旨在提升网页加载速度和用户体验。
1、合并图标,减少网络请求

合并图标是减少网络请求的常见的优化手段,网页中的小图标特征是体积小、数量多,而浏览器同时发起的并行请求数量又是有限制的,所以这些小图标会严重的影响网页的加载速度,阻碍关键内容的请求和呈现

sprite图

合并sprite图是慢工细活儿,并没有特别大的技术含量,但却是每个前端开发都必须掌握的技术。gulp.spritesmith插件。

// 构建视图文件
gulp.task('sprites', function() {
    var spriteData = gulp.src(config.src)
        .pipe(plumber(handleErrors))
        .pipe(newer(config.imgDest))
        .pipe(logger({ showChange: true }))
        .pipe(spritesmith({
            cssName: 'sprites.css',
            imgName: 'sprites.png',
            cssTemplate: path.resolve('./gulp/lib/template.css.handlebars')
        }));
        var imgStream = spriteData.img
        .pipe(buffer())
        .pipe(gulp.dest(config.imgDest));    
        var cssStream = spriteData.css
        .pipe(gulp.dest(config.cssDest));    
        return merge([imgStream, cssStream]);
});

sprite图不适合移动端的响应式场景。

iconfont字体文件

iconfont字体文件是用字体编码的形式来实现图标效果,既然是文字,那就可以随意设置颜色设置大小,相对来说比sprite方案更好。但是它只适用于纯色图标。推荐使用 阿里巴巴矢量图标库

2、用base64代替图片

场景:适用于图片大小小于2KB,页面上引用图片总数不多的情况 原理:将图片转换为base64编码字符串inline到页面或css中 优势:减少http的请求次数,并可以放到后台数据库中,只传输字符串,有较多的构建工具可以直接实现 劣势:这种方法仅限于图片总数较少,而且图片大小小于2KB的情况。否则图片字符串会变得很长很长

3、图片处理

1.图片懒加载

图片是网页中流量占比最多的部分,也是需要重点优化的部分。

2.图片压缩

好用的网站:

https://tinypng.com/

https://zhitu.isux.us/

http://alloyteam.github.io/gopng/

4、JS/CSS按需打包

按需打包是webpack独特的优势,如果有需要通过此种方式来管理模块之间的依赖关系,强烈推荐引入!

插件化:webpack本身非常灵活,提供了丰富的插件接口。基于这些接口,webpack开发了很多插件作为内置功能。速度快:webpack使用异步IO以及多级缓存机制。所以webpack的速度是很快的,尤其是增量更新。丰富的Loaders:loaders用来对文件做预处理。这样webpack就可以打包任何静态文件。高适配性:webpack同时支持AMD/CommonJs/ES6模块方案。webpack会静态解析你的代码,自动帮你管理他们的依赖关系。此外,webpack对第三方库的兼容性很好。代码拆分:webpack可以将你的代码分片,从而实现按需打包。这种机制可以保证页面只加载需要的JS代码,减少首次请求的时间。优化:webpack提供了很多优化机制来减少打包输出的文件大小,不仅如此,它还提供了hash机制,来解决浏览器缓存问题。开发模式友好:webpack为开发模式也提供了很多辅助功能。比如SourceMap、热更新等。使用场景多:webpack不仅适用于web应用场景,也适用于WebworkersNode.js场景

webpack 如何最佳配置?

webpack官方提供的配置方法是通过module.exports返回一个json,但是这种场景不灵活,不能适配多种场景。webpack.config.production.js/webpack.config.development.js,然后不同场景下,使用不同的配置文件。

相对来说,第一种更简单,但是重复配置多;第二种更灵活,推荐第二种方式。

module.exports = function(env) {
    return {
        context: config.context,
        entry: config.src,
        output: {
            path: path.join(config.jsDest, project),
            filename: '[name].js',
            chunkFilename: '[name].[chunkhash:8].js',
            publicPath: '/assets/' + project + '/'
        },
        devtool: "eval",
        watch: false,
        profile: true,
        cache: true,
        module: {
            loaders: getLoaders(env)
        },
        resolve: {
            alias: getAlias(env)
        },
        plugins: getPlugins(env)
    };
}

其中关键的配置这儿简单介绍如下,后续的系列博客会根据每个点详细介绍。context:上下文。entry:入口文件,是所有依赖关系的入口,webpack从这个入口开始静态解析,分析模块之间的依赖关系。output:打包输出的配置。devtools:SourceMap选项,便于开发模式下调试。watch:监听模式,增量更新,开发必备!profile:优化。cache:webpack构建的过程中会生成很多临时的文件,打开cache可以让这些临时的文件缓存起来,从而更快的构建。module.loaders:如前文介绍,loaders用来对文件做预处理。这样webpack就可以打包任何静态文件。resolve.alias:模块别名,这样可以更方便的引用模块。plugins:如前文介绍,webpack的一些内置功能均是以插件的形式提供。

webpack和gulp区别:

gulp是基于流的构建工具:all in one的打包模式,输出一个js文件和一个css文件,优点是减少http请求,万金油方案。

如何减小请求大小?

1、JS/CSS/HTML压缩

这也是常规手段,就不介绍太多,主要的方式有:

简单介绍一下JS/CSS/HTML压缩方式和一些注意事项

JS压缩

JS压缩:使用webpack的UglifyJsPlugin插件,同时做一些代码检测。

new webpack.optimize.UglifyJsPlugin({
    mangle: {
        except: ['$super''$''exports''require']
    }
})
CSS压缩

CSS压缩:使用cssnano压缩,同时使用postcss做一些自动化操作,比如自动加前缀、属性fallback支持、语法检测等。

var postcss = [
    cssnano({
        autoprefixer: false,
        reduceIdents: false,
        zindex: false,
        discardUnused: false,
        mergeIdents: false
    }),
    autoprefixer({
        browers: ['last 2 versions''ie >= 9''> 5% in CN']
    }),
    will_change,
    color_rgba_fallback,
    opacity,
    pseudoelements,
    sorting
];
HTML压缩

HTML压缩:使用htmlmin压缩HTML,同时对不规范的HTML写法纠正。

// 构建视图文件-build版本
gulp.task('build:views', ['clean:views'], function() {
    return streamqueue({ objectMode: true },
            gulp.src(config.commonSrc, { base: 'src' }),
            gulp.src(config.layoutsSrc, { base: 'src' }),
            gulp.src(config.pagesSrc, { base: 'src/pages' }),
            gulp.src(config.componentsSrc, { base: 'src' })
        )
        .pipe(plumber(handleErrors))
        .pipe(logger({ showChange: true }))
        .pipe(preprocess({ context: { PROJECT: project } }))
        .pipe(gulpif(function(file) {
            if (file.path.indexOf('.html') != -1) {
                return true;
            else {
                return false;
            }
        }, htmlmin({
            removeComments: true,
            collapseWhitespace: true,
            minifyJS: true,
            minifyCSS: true,
            ignoreCustomFragments: [/<%[\s\S]*?%>/, 
                                    /<\?[\s\S]*?\?>/, 
                                    /<meta[\s\S]*?name="viewport"[\s\S]*?>/]
        })))
        .pipe(gulp.dest(config.dest));
});

2、gzip压缩

gzip压缩也是比较常规的优化手段。前端并不需要做什么实际的工作,后台配置下服务器就行,效果非常明显。如果你发现你的网站还没有配置gzip,那么赶紧行动起来吧。

gzip压缩效果

那么gzip压缩的效果有多明显呢?保守估计,在已经完成JS/CSS/HTML压缩的基础上,还能降低60-80%左右的大小。

但需要注意,gzip压缩会消耗服务器的性能,不能过度压缩。所以推荐只对JS/CSS/HTML等资源做gzip压缩。图片的话,托管到第三方的图片建议开启gzip压缩,托管到自己应用服务器的图片不建议开启gzip压缩。

3、JS/CSS按需加载

和前面提到的按需打包不同。JS/CSS按需打包是预编译发生的事情,保证只打包当前页面相关的逻辑。JS/CSS按需加载是运行时发生的事情,保证只加载当前页面第一时间使用到的逻辑。

那么怎么实现按需加载呢?好奇心日报使用webpack提供的requirerequire.ensure方法来实现按需加载,值得一提的是,除了指定的按需加载文件列表,webpack还会自动解析回调函数的依赖及指定列表的深层次依赖,并最终打包成一个文件。

0?wx_fmt=png

webpack按需加载

上诉代码的实现效果是:只有当点击登录按钮的时候,才会去加载登录相关的JS/CSS资源。资源在加载成功后自动执行。

4、图片压缩,jpg优化
托管到应用服务器的图片压缩

可以手动处理,也可以通过gulp子任务来处理。tinypng ,压缩效果极好。gulp-imagemin插件,自动化处理,效果也还不错。

// 图片压缩
gulp.task('images', function() {
    return gulp.src(config.src)
            .pipe(plumber(handleErrors))
            .pipe(newer(config.dest))
            .pipe(logger({ showChange: true }))
            .pipe(imagemin()) // 压缩
        .pipe(gulp.dest(config.dest));
});
托管到第三方平台的图片压缩

比如七牛云平台,他们会有一套专门的方案来对图片压缩,格式转换,裁剪等。只需要在url后面加上对应的参数即可,虽然偶尔会有一些小bug,但整体来说,托管方案比用自家应用服务器方案更优。

0?wx_fmt=png

改变参数,实现不同程度的压缩

jpg优化

除了对图片进行压缩之外,对透明图床没有要求的场景,强烈建议将png转换为jpg,效果很明显!

0?wx_fmt=png

png转jpg,体积相差八倍

5、webp优化 & srcset优化
webp优化

粗略看一眼,卧槽,兼容性这么差,也就安卓浏览器及chrome浏览器对它的支持还算给力。

0?wx_fmt=png

webp兼容性

另一方面,webp优化能在jpg的基础上再降低近50%的大小。其优化效果明显。此外,如果浏览器支持webpanimation,还能对gif做压缩!

0?wx_fmt=png

普通图片webp优化

0?wx_fmt=png

gif图片优化

兼容性差,但效果好!最终好奇心决定尝试一下。

鉴于浏览器对webp的支持比较局限,我们采用渐进升级的方式来优化:对于不支持webp的浏览器,不做处理;对于支持webp的浏览器,将图片src替换成webp格式。

// 检测浏览器是否支持webp
// 之所以没写成回调,是因为即使isSupportWebp=false也无大碍,但却可以让代码更容易维护
(function() {
    function webpTest(src, name) {
        var img = new Image(),
            isSupport = false,
            className, cls;
 
        img.onload = function() {
            isSupport = !!(img.height > 0 && img.width > 0);
 
            cls = isSupport ? (' ' + name) : (' no-' + name);
            className = document.querySelector('html').className
            className += cls;
 
            document.querySelector('html').className = className.trim();
        };
        img.onerror = function() {
            cls = (' no-' + name);
            className = document.querySelector('html').className
            className += cls;
 
            document.querySelector('html').className = className.trim();
        };
 
        img.src = src;
    }
 
    var webpSrc = 'data:image/webp;base64,UklGRiQAAABXRUJQVlA4IBgAAAAwAQCdASoB\
                AAEAAwA0JaQAA3AA/vuUAAA=',
        webpanimationSrc = 'data:image/webp;base64,UklGRlIAAABXRUJQVlA4WAoAAAA\
                            SAAAAAAAAAAAAQU5JTQYAAAD/////AABBTk1GJgAAAAAAAAAAAA\
                            AAAAAAAGQAAABWUDhMDQAAAC8AAAAQBxAREYiI/gcA';
 
    webpTest(webpSrc, 'webp');
    webpTest(webpanimationSrc, 'webpanimation');
})();

借鉴modernizr,实现了检测webp/webpanimation兼容性的函数,从代码中可以看出,检测原理就是模拟下载对应格式的图片,在异步函数中可以得到兼容性结果。

接下来就是替换url为webp格式

// 获取webp格式的src
function _getWebpSrc(src) {
    var dpr = Math.round(window.devicePixelRatio || 1),
        ratio = [1, 1, 1.5, 2, 2, 2],
        elHtml = document.querySelector('html'),
        isSupportWebp = (/(^|\s)webp(\s|$)/i).test(elHtml.className),
        isSupportWebpAnimation = (/(^|\s)webpanimation(\s|$)/i).test(elHtml.className),
        deviceWidth = elHtml.clientWidth,
        isQiniuSrc = /img\.qdaily\.com\//.test(src),
        format = _getFormat(src),
        isGifWebp, isNotGifWebp, regDetailImg;
 
    if (!src || !isQiniuSrc || !format || format == 'webp') {
        return src;
    }
 
    isNotGifWebp = (format != 'gif' && isSupportWebp);
    isGifWebp = (format == 'gif' && isSupportWebpAnimation);
 
    // 根据屏幕分辨率计算大小
    src = src.replace(/\/(thumbnail|crop)\/.*?(\d+)x(\d+)[^\/]*\//ig, function(match, p0, p1, p2) {
        if(dpr > 1){
            p1 = Math.round(p1 * ratio[dpr]);
            p2 = Math.round(p2 * ratio[dpr]);
 
            match = match.replace(/\d+x\d+/, p1 + 'x' + p2)
        }
 
        return match;
    });
 
    if(isNotGifWebp || isGifWebp) {
       // 替换webp格式,首页/列表页
        src = src.replace(/\/format\/([^\/]*)/ig, function(match, p1) {
            return '/format/webp';
        });
    }
}
注意事项

1、window的屏幕像素密度不一定是整数,mac浏览器缩放之后,屏幕像素密度也不是整数。所以获取dpr一定要取整:dpr = Math.round(window.devicePixelRatio || 1);ratio = [1, 1, 1.5, 2, 2, 2]表示:1倍屏使用1倍图,2倍屏使用1.5倍图,3倍屏以上都用2倍图。这儿的规则可以按实际情况来设置。

0?wx_fmt=png

devicePixelRatio兼容性

srcset兼容性

0?wx_fmt=png

srcset兼容性

如上所述,在对webp优化的时候,我们顺道模拟实现了srcset:根据屏幕像素密度来设置最适合的图片宽高。

知识点

整体来说,涉及的知识面比较广:包括webpack & gulp的构建系统、图片的webp优化、服务器的gzip配置、浏览器的加载顺序、图片延迟加载方案等等。

推荐公众号:前端达人专注分享当下最实用的的前端技术!640?wx_fmt=jpeg
长按二维码点选(识别图中二维码)

提供了基于BP(Back Propagation)神经网络结合PID(比例-积分-微分)控制策略的Simulink仿真模型。该模型旨在实现对杨艺所著论文《基于S函数的BP神经网络PID控制器及Simulink仿真》中的理论进行实践验证。在Matlab 2016b环境下开发,经过测试,确保能够正常运行,适合学习和研究神经网络在控制系统中的应用。 特点 集成BP神经网络:模型中集成了BP神经网络用于提升PID控制器的性能,使之能更好地适应复杂控制环境。 PID控制优化:利用神经网络的自学习能力,对传统的PID控制算法进行了智能调整,提高控制精度和稳定性。 S函数应用:展示了如何在Simulink中通过S函数嵌入MATLAB代码,实现BP神经网络的定制化逻辑。 兼容性说明:虽然开发于Matlab 2016b,但理论上兼容后续版本,可能会需要调整少量配置以适配不同版本的Matlab。 使用指南 环境要求:确保你的电脑上安装有Matlab 2016b或更高版本。 模型加载: 下载本仓库到本地。 在Matlab中打开.slx文件。 运行仿真: 调整模型参数前,请先熟悉各模块功能和输入输出设置。 运行整个模型,观察控制效果。 参数调整: 用户可以自由调节神经网络的层数、节点数以及PID控制器的参数,探索不同的控制性能。 学习和修改: 通过阅读模型中的注释和查阅相关文献,加深对BP神经网络与PID控制结合的理解。 如需修改S函数内的MATLAB代码,建议有一定的MATLAB编程基础。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值