Web前端性能优化——如何提高页面加载速度

一、 加载资源优化-- 减少请求资源大小和次数

1、合并css和压缩css、js文件。

原因:

主要是为了减少http请求次数以及减少请求资源的大小

方法:

webpack中mini-css-extract-plugin将css样式抽离到一个文件中;

optimize-css-assets-webpack-plugin压缩css

terser-webpack-plugin压缩js

2、代码分割Code Splitting-为了减少HTTP 请求

把业务代码和第三方库代码分离出来,因为业务代码更新频率大,相反第三方库代码更新迭代相对较慢且可以锁版本,所以可以利用浏览器的缓存来加载这些第三方库。

做法:

1、利用webpack的CommonsChunkPlugin插件自动化分离公共模块,将公共模块单独打包成一个chunk --- 不推荐了,老方法
2、利用webpack4的splitChunksPlugin

webpack4 最核心的特性是 【splitChunks】,splitChunks 最核心的配置是 cacheGroups!

默认配置如下:

模块被重复引用或者来自node_modules中的模块
minSize: 30000,// 引入的模块,只有大于30kb时,才会做代码分割

maxAsyncRequests: 5, 在按需加载时,请求数量小于等于5进行代码分割

 maxInitialRequests: 3, 在初始化加载时,请求数量小于等于3进行代码分割

异步代码分割import(),不需要做任何配置,webpack会自动完成分包。

SplitChunksPlugin有三种模式async,all,initial

默认情况下为async,即只拆分import()动态加载的模块

all 模式下,入口文件(webpack定义的entry)依赖的文件和动态引入文件都会进行拆分打包

initial 模式下,会将入口文件中的依赖包重新切割为一个新的文件,其它文件中动态引入的不会进行拆分

cacheGroups**** - ****缓存组****--****同步代码分割打包必须配置项

按需加载-利用() => [import()] 语法将组件单独打包到一个chunk里,即async chunk 。

场景:

「访问某个路由的时候再去加载对应的组件」,用户不一定会访问所有的路由,所以没必要把所有路由对应的组件都先在开始的加载完;

「某些用户他们的权限只能访问某些页面」,所以没必要把他们没权限访问的页面的代码也加载。

3、采用图片的懒加载(延迟加载) 目的为了,减少页面第一次加载的请求次数;防止并发加载资源过多造成页面阻塞 具体步骤: 1、页面开始加载时不去发送http请求,而是放置一张占位图 2、当页面加载完(window.onload)时,并且图片在可视区域再去请求加载图片信息

具体方案:

vue图片懒加载 —— vue-lazyload的使用;https://blog.csdn.net/halo1416/article/details/81302419

原理:先将img 标签中的src链接设为同一张占位图,将其真正的图片地址存储再在自定义属性中(比如data-src)。当js监听到该图片元素进入可视窗口时,即将自定义属性中的地址存储到src属性中,达到懒加载的效果。

    // 判断图片是否出现在视窗的函数

    function isShow($node) {

      return $node.offset().top <= $(window).height() + $(window).scrollTop();

    }

1、当 window.onload 事件触发时,页面上所有的DOM,样式表,脚本,图片,flash都已经加载完成了。

2、当 DOMContentLoaded 事件触发时,仅当DOM加载完成,不包括样式表,图片,flash。

4、避免引入大量第三方的库

能用css做的效果,不要用js做;能用原生js做的,不要去使用第三方插件。

5、使用雪碧图

为了减少网络请求数量,提高网站的访问速度,我们可以把一些小的图片合并成一张sprite图,然后根据background-position来进行定位

6、使用CDN让静态资源加载更快(CDN能够让你请求最近/最快的服务器)
7、tree shaking

tree shaking 用于移除 JavaScript 中的未引用代码(dead-code)。它依赖于 ES2015 模块module语法的静态结构特性,例如import 和 export,能够编译时就能确定模块的依赖关系,以及输入和输出的变量。

ES6 模块不是对象,而是通过export命令显式指定输出的代码,再通过import命令输入。

配置方法:

在webpack.config.js里添加

 mode: 'development', //production模式下,默认开启

 optimization: {

   usedExports: true,   // 开启Tree Shaking功能

 }

package.json中配置"sideEffects" 属性

"sideEffects": ["./src/some-side-effectful-file.js"] //该文件有副作用,不要进行tree shaking

通过配置副作用文件列表,提示编译器不进行tree shaking

二、 提高渲染效率

1、 尽量所使用的字体图标或者SVG图标来代替传统png图  因为字体图标或者SVG是矢量图,是代码编写出来的,放大不会变形,而且渲染速度快
2、 事件的节流、防抖--提高js运行效率
3、 把css放在head中,把js放在body下面

css放在body标签尾部时, DOMTree构建完成之后便开始构建RenderTree, 并计算布局渲染网页, 等加载解析完css之后, 开始构建CSSOMTree, 并和DOMTree重新构建RenderTree, 重新计算布局渲染网页

css放在head标签中时, 先加载css, 之后解析css构建CSSOMTree, 于此同时构建DOMTree, CSSOMTree和DOMTree都构建完毕之后开始构建RenderTree, 计算布局渲染网页

对比两者, css放在head标签中比css放在body标签尾部少了一次构建RenderTree, 一次计算布局和一次渲染网页, 因此性能会更好; 并且css放在body标签尾部时会在网页中短暂出现"裸奔"的HTML, 这不利于用户体验

4、 基于script标签下载js文件时,可以使用defer或者async来异步加载
5、减少重流、重绘

(1)减少dom操作,多个操作尽量合并到一起执行(浏览器会累积DOM 变动,然后一次性执行。)
(2)可将元素绝对定位脱离文档流,减少对其他元素的影响
(3)不要一项一项地改变样式,而是使用预先定义的CSS class(类名)一次性改变样式。
(4)使用window.requestAnimationFrame(),因为它可以把代码推迟到下一次重绘之前执行,而不是立即要求页面重绘

下面是一个window.requestAnimationFrame()对比效果的例子。

// 重流代价高function doubleHeight(element) {

  var currentHeight = element.clientHeight;

  element.style.height = (currentHeight * 2) + 'px';

}

all_my_elements.forEach(doubleHeight);

// 重绘代价低function doubleHeight(element) {

  var currentHeight = element.clientHeight;

  window.requestAnimationFrame(function () {

    element.style.height = (currentHeight * 2) + 'px';

  });

}

all_my_elements.forEach(doubleHeight);

上面的第一段代码,每读一次DOM,就写入新的值,会造成不停的重排和重流。第二段代码把所有的写操作,都累积在一起,从而 DOM 代码变动的代价就最小化了。

6、首屏内容使用SSR(server side render)服务端渲染

服务端渲染就是在服务端加载执行js,并且将数据直接输出到html,返回给客户端的是渲染好的html;

7、预渲染

通过Webpack 预渲染插件(prerender-spa-plugin)将一些特定静态页面组件 build 时就编译为 html 文件,直接以静态资源的形式输出给搜索引擎。

预渲染不执行js的,只适应于纯静态页面。

三、存储

1、Ajax请求使用缓存

GET请求,是可以(而且默认)在客户端进行缓存的,除非指定了不同的地址,否则同一个地址的AJAX请求,不会重复在服务器执行,而是返回304告诉浏览器去本地拉取数据

2、利用h5的新特性(localStorage、Application Cache)做一些简单数据的存储,避免向后台请求数据或者说在离线状态下做一些数据展示。
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,684评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,143评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,214评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,788评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,796评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,665评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,027评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,679评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,346评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,664评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,766评论 1 331
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,412评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,015评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,974评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,073评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,501评论 2 343

推荐阅读更多精彩内容