当前位置: 首页 > news >正文

next项目页面性能调优

next项目页面性能调优

一般来说性能优化可以分为加载时、运行时两部分的优化。

扩展参考链接:
前端性能优化 24 条建议
Webpack 4进阶–从前的日色变得慢 ,一下午只够打一次包
Webpack 分包优化首屏加载

参考指标

  1. FCP(First Contentful Paint):首次内容绘制时间,白屏时间
  2. LCP(Largest Contentful Paint):最大内容绘制时间,即网站渲染占比最多的元素绘制所花费的时间。
  3. TTL(Time to Interactive):首次可交互时间。
  4. FMP(First Meaningful Paint):首次有意义的渲染帧,从页面加载开始,到大部分或者主要内容已经在首屏上渲染的时间点。

性能测试方式

  1. 本地 / 测试环境 可直接使用google devtool自带的测试工具Lighthouse
  2. 正式环境:
    https://gtmetrix.com/
    https://pagespeed.web.dev/report
    https://www.webpagetest.org/

优化方法

一、开启webpack具体分析&Lighthouse treeMap,减少主包文件大小、代码分割分包

  1. 使用next提供的dynamic组件异步导入依赖,代码分割
    基本上非首屏内容皆可分割出去。是否在服务端渲染可以自行测试,不过经过我的尝试,在服务端渲染过一次、客户端直接拿数据优化效果更好。
import dynamic from 'next/dynamic';
const Component = dynamic(import('./component'));
// const Component = dynamic(import('./component'),{ssr:false});
  1. 代码分割后使用webpack-analyze查看包的大小,主包大小多大,页面打包后大小多大,是否tree-shaking,是否开启压缩,是否关闭source-map。
    以及最重要的是否把重复引入的库合并,不能每个包都打包进去了,那样就浪费资源了。
    可以参考之前的文章,webpack分类下的文章。

参考:
Next.js的Babel及拆包优化
前端小杂记 - 基于 NextJS 的网站构建、优化与发布
Webpack中 SplitChunks 插件用法详解

我的项目中,我发现主包build后有800多k
经过打印next自带的webpack.optimization信息,发现next拆包策略如下:

于是我想把主包里的800多k的包拆出来,仔细查看主包,发现里面有一些公共utils包,比如mobx / antd的内容,还有一些和其他包重复引用的部分,于是我想把这部分包提出来,怎么做呢,参考以前的webpack相关博客,可以使用cacheGroup,所以添加如下分包策略:

// 需判断是否是服务端打包,我们只修改非服务端打包的策略
// framework是next自带的分包策略,里面打包react相关try {if (!isServer && !dev) {const cacheGroups = config.optimization.splitChunks.cacheGroups;// 1.mobxcacheGroups.antd = {name: 'antd',test: /[\\/]node_modules[\\/](antd|@ant-design)[\\/]/,enforce: true,chunks: 'all',};// 2.工具类cacheGroups.vendors = {name: 'vendors',test: /[\\/]node_modules[\\/](mobx|axios|lodash|moment)[\\/]/,enforce: true,chunks: 'all',priority: 20,};// 3.utils&configcacheGroups.utils = {name: 'utils',test: /[\\/]src[\\/]utils[\\/]/,enforce: true,chunks: 'all',priority: 20,};}
} catch (e) {console.log(e);
}

经过本次分包后,主包肉眼可见地从800多k变为了500多k,里面杂乱重复引入的工具包减少了。而总体的打包大小从一开始的10多M变为9.7多M.

但是绝望滴事情发生鸟,当我自信满满地npm start想要看看优化效果时,报了node错误[nodemon] app crashed - waiting for file changes before starting...。。项目启动不了了

问题肯定是出在新加的这一段代码上,于是try / catch一下,提示:Cannot set property 'antd' of undefined,是因为本地dev环境自动配置的splitChunks为false,好吧,因此修改上述代码中增加判断条件:!isServer && !dev

  1. Tree-shaking+sideEffects
    treeshaking应该是自动在生产环境生效的,但是副作用标识我没有启用,虽然启用之后项目文件大小确实小了,但是担心对整个项目产生其他影响,测试不充分。
    参考:
    webpack之sideEffects

webpack4新增了一个sideEffects新特性,它允许我们通过配置的方式,去标识我们的代码是否有副作用,从而为Tree-shaking提供更大的压缩空间。
这里的副作用指的是模块执行时除了导出成员之外所做的事情。
sideEffects一般用于npm包标记是否有副作用。

二、 视频、图片加载优化&懒加载

参考以前的文章怎么优化一个多图多视频的页面

1. next/image做了很多图片加载优化的工作,以及最好使用相关懒加载组件,等图片出现时再加载请求;

从NextJS的封装的Image组件看如何优化图片加载

  • import LazyLoad from ‘react-lazyload’;
  • import Image from ‘next/image’; next提供的图片加载优化组件,也可以实现懒加载的功能。
2. 减少图片大小以及减少请求消耗带宽资源。
  • 可以使用next/image压缩,或者使用webp格式,fontIcon代替svg。
  • 使用CDN缓存图片静态资源,雪碧图合并图片等。
  • 图片可以渐进式加载
    // 我们可以使用webP格式的图片或者分辨率较低的压缩图,再叠加一层清晰的 png 图片,实现快速显示的效果。
    // 叠加 png 图片的目的是防止某些浏览器不支持 webP 格式。
    background-image: url("img/beijing.webp"),url("img/beijing.png");// 使用picture标签,保底img为webp格式
    <picture><source media="(min-width:465px)" srcset="/i/photo/tulip.jpg"><img src="/i/photo/flower.gif" alt="Flowers" style="width:auto;">
    </picture>
    

压缩工具:

  • https://squoosh.app/
  • https://tinypng.com/
  • https://imagecompressor.com/
3. 页面视频 懒加载监听

使用intersectionObserver来监听是否进入页面视野。
提供一份监听全页面视频懒加载工具函数。

/*** @description 视频懒加载* - <video data-src={src} data-poster={poster} autoPlay playsInline loop muted/>*/function VideoLazyLoad(threshold = 300) {function videoLoaded(video) {return video.getAttribute('src');}const lazyVideos = [].slice.call(document.querySelectorAll('video[data-src]'));if ('IntersectionObserver' in window) {let lazyVideoObserver = new IntersectionObserver(function (entries, observer) {entries.forEach(function (_video, _index) {const video = _video.target;const videoPlaying =video.currentTime > 0 && !video.paused && !video.ended && video.readyState > video.HAVE_CURRENT_DATA;if (_video.isIntersecting) {if (videoLoaded(video)) {video.play();} else {video.poster = video.getAttribute('data-poster');video.src = video.getAttribute('data-src');video.load();video.play();}} else {if (videoLoaded(video) && videoPlaying) {video.pause();}}});},{root: document.getElementById('_next'),rootMargin: `${threshold}px 0px`,});lazyVideos.forEach(function (lazyVideo) {lazyVideoObserver.observe(lazyVideo);});} else {lazyVideos.forEach(function (video) {video.src = video.getAttribute('data-src');video.poster = video.getAttribute('data-poster');video.load();});}
}/** 视频懒加载,但是在首次进入视野时加载一次,之后是否暂停、播放由用户手动控制。 */
export function VideoLazyLoadFirst(threshold = 300) {const lazyVideos = [].slice.call(document.querySelectorAll('video[data-src]'));if ('IntersectionObserver' in window) {let lazyVideoObserver = new IntersectionObserver(function (entries, observer) {entries.forEach((_video, _index) => {const video = _video.target;if (_video.isIntersecting && !video.src) {video.poster = video.getAttribute('data-poster');video.src = video.getAttribute('data-src');video.load();video.play();}});},{root: document.getElementById('_next'),rootMargin: `${threshold}px 0px`,});lazyVideos.forEach(function (lazyVideo) {lazyVideoObserver.observe(lazyVideo);});} else {lazyVideos.forEach(function (video) {video.src = video.getAttribute('data-src');video.poster = video.getAttribute('data-poster');video.load();});}
}

组件按需加载

如果一个包不合常理地比较大,可以看源代码里是否引入了其他不需要的代码,需注意lodash / @ant-design/Icon。
比如@ant-design/icons ,最好改成:@ant-design/icons/lib

了解IntersectionObserver&优化懒加载和业务方案思路

Intersection Observer API MDN
IntersectionObserver MDN
IntersectionObserver API可以帮助我们实现“检测一个元素是否可见或者两个元素是否相交”,具体应用于实现图片视频资源懒加载、内容无限滚动、广告曝光埋点等功能。

过去这类边界检测的功能通过​getBoundingClientRect()或者scroll事件监听实现,它们运行在主线程上,频繁的触发会让性能变差,而IntersectionObserver提供了一种更加优雅的检测方式,它在渲染进程上监听交集事件,主线程上异步接受通知并调用回调函数,因此有部分人认为:IntersectionObserver的回调方法里可以随意写高消耗代码,不会影响主线程,这种观点是错误的,JS代码执行是单线程的,因此JS代码的解释执行都在主线程上,因此我们在回调函数中也要注意尽量写的简单一些。

MDN————
请留意,你注册的回调函数将会在主线程中被执行。所以该函数执行速度要尽可能的快。如果有一些耗时的操作需要执行,建议使用 Window.requestIdleCallback() 方法。

API

// 创建实例,创建一个新的 IntersectionObserver(观察器) 对象,当其监听到目标元素的可见部分(的比例)超过了一个或多个阈值(threshold)时,会执行指定的回调函数。
const observer = new IntersectionObserver(callback, option);// 开始观察element1 / 2,如果需要观察多个对象,可以使用observe方法多次,而每个dom节点的交点变动都会触发callback
observer.observe(element1);
observer.observe(element2);
[domsArray].forEach(d=>observer.observe(d));// 返回所有观察目标的 IntersectionObserverEntry 对象数组
IntersectionObserver.takeRecords()// 停止观察
observer.unobserve(element);// 关闭观察器
observer.disconnect();

new IntersectionObserver(callback, options)

可以将这个交集观察构造函数理解到两个对象,一个是根对象(窗口对象),一个是被观察对象(我们要观察的目标),callback的触发时间就是当 我们要观察的目标窗口对象产生交集的时候。

options 对象可用于控制窗口对象的参数。

root
指定根 (root) 元素,用于检查目标的可见性。必须是目标元素的父级元素。如果未指定或者为null,则默认为浏览器视窗。

rootMargin
根 (root) 元素的外边距。类似于 CSS 中的 margin 属性,比如 “10px 20px 30px 40px” (top、right、bottom、left)。如果有指定 root 参数,则 rootMargin 也可以使用百分比来取值。该属性值是用作 root 元素和 target 发生交集时候的计算交集的区域范围,使用该属性可以控制 root 元素每一边的收缩或者扩张。默认值为四个边距全是 0。

threshold
触发的阈值设定。可以是单一的 number 也可以是 number 数组,target 元素和 root 元素相交程度达到该值的时候 IntersectionObserver 注册的回调函数将会被执行。
如果你只是想要探测当 target 元素的在 root 元素中的可见性超过 50% 的时候,你可以指定该属性值为 0.5。如果你想要 target 元素在 root 元素的可见程度每多 25% 就执行一次回调,那么你可以指定一个数组 [0, 0.25, 0.5, 0.75, 1]。默认值是 0 (意味着只要有一个 target 像素出现在 root 元素中,回调函数将会被执行)。该值为 1.0 含义是当 target 完全出现在 root 元素中时候 回调才会被执行。
如果 isIntersecting 为真,target 元素的至少已经达到 thresholds 属性值当中规定的其中一个阈值,如果为假,则 target 元素不在给定的阈值范围内可见。

现在假如我的观察目标对象设置为某个视频,想要让它懒加载,通过这个懒加载方案来理解上述属性吧。

Q1:想要实现每次视频的可见程度75%的时候播放,可见程度25%的时候暂停,这种效果怎么办呢

可见程度75%,则 不可见程度25%,可以将threshold设定在0.25这个点,即可见程度25%或者不可见程度25%的时候它都会触发一次回调函数,具体的判断可以使用观察器对象的intersectionRatio属性,这个属性是当前目标在窗口中的可见比例。
PS:0.25这个属性对左右方向的进入视窗也同样成立。

Q2:我不想在视频进入视窗内才开始加载,能不能提前200px加载呢?

可以。修改rootMargin为200px 0即可,即将视窗口 上下 各加长200px,这时滚轮上下滑动,视频提前了200px触及视窗,也就提前了200px加载。

Q3:threshold和rootMargin是什么关系呢?

我能不能达到:视频在视窗口提前200px加载,而在到达视窗被我们看到的时候播放呢?
答案是:不能。
我经过尝试,发现,当使用rootMargin让视窗扩大的同时,它的交集区域也在扩大,曾经我们rootMargin默认是窗口大小的时候,threshold设置成0,就可以在用户看到的同时调用回调函数。但是rootMargin设置成200px 0时,threshold设置仍然为0,此时触发回调函数的时候,视频还在视窗的上200px呢。所以“视频什么时候达到视窗”的这个阶段也就无法估计了。(无法得知200px和视频大小和视窗长度之间的关系,因此无法算出比例)。
不过想想,就算达到200px时提前加载和播放,实际上也能达到我们想要的效果,大差不差吧。

callback回调函数与使用

其实搞懂了option基本上就搞懂了这个观察API。但是callback中传入给我们的“目标对象”还经过了一些观察者的包装,有很多我们可以用的上的属性。

// 简单使用
const callback = (entries, observer) => {// entries被观察的目标对象数组。entries.forEach(entry => {// Each entry describes an intersection change for one observed target element:// entry.boundingClientRect // 目标对象在视窗内的top / bottom / left / right等距离。// entry.intersectionRect // 同上类似,用的不多没有仔细研究。// entry.intersectionRatio // 目标对象在视窗内的交集比例。(用的比较多)// entry.isIntersecting // 当前目标是否视窗内可见(达到设定的阈值)// entry.rootBounds // 边界检测// entry.target // 当前目标的DOM节点实例。(底下当时传入观察的element1)// entry.time});
};const observer = new IntersectionObserver(callback, option);
observer.observe(element1);

最后,实际使用。

我们重新修改了上面的lazyloadVideo方法,目的在于希望视频在25%这个节点再去播放,不可见75%的时候暂停,这样节省一些内存消耗。
当然,这个函数还有改进的空间:比如一个多视频的页面,当用户快速滑下,上一批视频还未加载完的情况,将阻塞后续的视频加载,这时候需要取消上一批不可见视频的加载,腾出空间给下一批,这个后续再安排吧。

/** * - <video data-src={src} data-poster={poster} autoPlay playsInline loop muted/>* @param {number} rootMarginY 上下方向 视口窗的扩张/收缩距离* @param {number} rootMarginX 左右方向 视口窗的扩张/收缩距离* @param {number|string} threshold 视频的可见程度提醒断点*/function VideoLazyLoad(rootMarginY = 150, rootMarginX = 0, threshold) {function videoLoaded(video) {return video.getAttribute('src');}const lazyVideos = [].slice.call(document.querySelectorAll('video[data-src]'));if ('IntersectionObserver' in window) {let lazyVideoObserver = new IntersectionObserver(function (entries, observer) {entries.forEach(function (_video, _index) {const video = _video.target;const videoPlaying =video.currentTime > 0 && !video.paused && !video.ended && video.readyState > video.HAVE_CURRENT_DATA;if (!_video.isIntersecting && videoLoaded(video) && videoPlaying) {video.pause();}// 可见度0-2 先配置视频封面,视频不允许播放。if (_video.intersectionRatio > 0 && _video.intersectionRatio < 0.25) {if (!video.getAttribute('poster')) {if (video.getAttribute('data-poster')) {video.poster = video.getAttribute('data-poster');} else {video.src = video.getAttribute('data-src');}}if (videoLoaded(video) && videoPlaying) {video.pause();}}if (_video.intersectionRatio >= 0.25) {if (videoLoaded(video)) {video.play();} else {if (!video.getAttribute('poster')) {video.poster = video.getAttribute('data-poster');}video.src = video.getAttribute('data-src');video.load();video.play();}}});},{root: document.getElementById('_next'),rootMargin: `${rootMarginY}px ${rootMarginX}px`,threshold: threshold ?? [0, 0.25],});lazyVideos.forEach(function (lazyVideo) {lazyVideoObserver.observe(lazyVideo);});} else {lazyVideos.forEach(function (video) {video.src = video.getAttribute('data-src');video.poster = video.getAttribute('data-poster');video.load();});}
}

——————————————

下方内容新更新于2024-02-07

——————————————

针对性能分析指标进行项目优化

通过Chrome提供的lightHouse / performace等工具,以及第三方性能检测工具比如gtmetrix等,都可以给到我们一些建议指标。

对于项目的进一步优化,除了之前已经提过很多次的懒加载、媒体资源压缩、webpack分包优化等等,其实我们也可以根据报告对某个指标进行优化。

TTL

一些第三方资源请求太多,阻碍了主要网页资源请求,造成TTL很高,打开列表一看全是第三方资源。
于是有以下几个措施:

  1. 对于第三方资源进行延迟加载,需要用户对页面进行交互才开始下载资源,新增对用户交互行为的监听以及创建变量,一些非首屏的懒加载方案同样可以使用。
  2. 合理分包减少请求大小、合并小资源请求减少请求数量。
  3. 做好缓存处理。
CLS
  1. 查看是什么DOM节点造成的页面重排,CLS指标偏高。
  2. 图片设置好宽高。

相关文章:

next项目页面性能调优

next项目页面性能调优 一般来说性能优化可以分为加载时、运行时两部分的优化。 扩展参考链接&#xff1a; 前端性能优化 24 条建议 Webpack 4进阶–从前的日色变得慢 &#xff0c;一下午只够打一次包 Webpack 分包优化首屏加载 参考指标 FCP&#xff08;First Contentful P…...

性能评测|虚拟化和裸金属 K8s 哪个性能更好?

本文重点 整体而言&#xff0c;SKS&#xff08;虚拟机 Kubernetes&#xff09;可以达到裸金属 Kubernetes 性能的 82% – 96%&#xff0c;满足绝大部分场景下生产容器应用的性能需求。更多虚拟化与裸金属 Kubernetes 架构、特性、适用场景与性能对比&#xff0c;欢迎阅读文末电…...

【大厂AI课学习笔记】【1.6 人工智能基础知识】(1)人工智能、机器学习、深度学习之间的关系

6.1 人工智能、机器学习与深度学习的关系 必须要掌握的内容&#xff1a; 如上图&#xff1a;人工智能>机器学习>深度学习。 机器学习是人工智能的一个分支&#xff0c;该领域的主要研究对象是人工智能&#xff0c;特别是如何在经验学习中改进具体算法的性能。 深度学习…...

计算机毕业设计基于的农村蔬菜销售系统SSM

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; vue mybatis Maven mysql5.7或8.0等等组成&#xff0c;B…...

【Chrono Engine学习总结】3-地型terrain

由于Chrono的官方教程在一些细节方面解释的并不清楚&#xff0c;自己做了一些尝试&#xff0c;做学习总结。 1、关于物体材质 在介绍地型之前&#xff0c;要初步了解chrono中关于材质的一些基本概念。 首先&#xff0c;最基本的材质类是ChMaterialSurface,其进一步包括&…...

【Linux】构建模块

&#x1f525;博客主页&#xff1a;PannLZ &#x1f38b;系列专栏&#xff1a;《Linux系统之路》 &#x1f94a;不要让自己再留有遗憾&#xff0c;加油吧&#xff01; 文章目录 构建第一个模块1模块的makefile2内核树内构建3内核树外构建 构建第一个模块 可以在两个地方构建模…...

vscode远程连接失败

目录 解决方案尝试1解决方案尝试2 解决方案尝试1 最近通过vscode一直使用腾讯云的服务器作为远程开发环境&#xff0c;以前一直很好用。 直到最近重装了系统之后&#xff0c;发现vscode没法对云服务器进行连接了&#xff0c;即使在远程主机添加了本地的公钥也不行。直接报错:…...

C#系列-C#访问FTP服务器实现上传下载(8)

FTP Server是什么&#xff1f; FTP Server&#xff08;File Transfer Protocol Server&#xff09;&#xff0c;即文件传输协议服务器&#xff0c;是在互联网上提供文件存储和访问服务的计算机。它依照FTP协议提供服务&#xff0c;专门用来传输文件。 FTP Server允许不同的客…...

django中实现登录

Django中实现登录功能&#xff0c;通常涉及以下几个步骤&#xff1a; 一&#xff1a;实现步骤 1&#xff1a;创建用户模型&#xff1a;Django自带了一个用户认证系统&#xff0c;通常使用内置的User模型来管理用户。你也可以根据需要自定义用户模型。 2&#xff1a;创建登录表…...

【安卓操作系统——讲解】

安卓操作系统 安卓操作系统 安卓操作系统 安卓&#xff08;Android&#xff09;是一种基于Linux内核和其他开源软件的移动操作系统&#xff0c;主要用于触屏移动设备如智能手机和平板电脑。由Andy Rubin等人开发&#xff0c;最初的目的是创建一个先进的操作系统&#xff0c;用…...

Linux发行版全景:选择、使用和未来趋势

1. 引言 Linux操作系统的简介 Linux是一种自由和开源的操作系统内核&#xff0c;由Linus Torvalds在1991年首次发布。随着时间的发展&#xff0c;Linux已经成为世界上最流行的操作系统之一&#xff0c;广泛用于服务器、桌面电脑、移动设备以及嵌入式系统。Linux的主要特点是其…...

STM32 与 ARM 的联系

STM32 和 ARM 是两个不同的概念&#xff0c;但它们之间存在一定的联系。 STM32是一种微控制器产品&#xff0c;由意法半导体&#xff08;STMicroelectronics&#xff09;推出&#xff0c;其内核采用了 ARM Cortex-M 核。ARM 是一家英国芯片设计公司&#xff0c;专注于设计和许可…...

每日五道java面试题之java基础篇(二)

第一题. 为什么说 Java 语⾔“编译与解释并存”&#xff1f; ⾼级编程语⾔按照程序的执⾏⽅式分为编译型和解释型两种。 简单来说&#xff0c;编译型语⾔是指编译器针对特定的操作系统将源代码⼀次性翻译成可被该平台执⾏的机器码&#xff1b;解释型语⾔是指解释器对源程序逐…...

【Linux】Shell编程

Shell编程 目录 Shell编程1.shell基础1.输入重定向 & 输出重定向2.管道3.特殊字符(3.1)通配符(3.2)引号(3.3)注释符(#) 4.别名5.命令历史history 2.Shell脚本Shell脚本的执行方式(1)为脚本文件加上可执行权限,然后在命令行直接输入shell脚本文件名执行。(2)sh shell脚本名(…...

斯巴鲁Subaru EDI需求分析

斯巴鲁Subaru是日本运输集团斯巴鲁公司&#xff08;前身为富士重工&#xff09;的汽车制造部门&#xff0c;以性能而闻名&#xff0c;曾赢得 3 次世界拉力锦标赛和 10 次澳大利亚拉力锦标赛。 斯巴鲁Subaru EDI 需求分析 企业与斯巴鲁Subaru建立EDI连接&#xff0c;首先需要确…...

golang 集成sentry:PostgreSQL

本文介绍通过 pgx库集成sentry&#xff0c; pgx 特点是速度快&#xff0c;可以完全控制&#xff0c;并且支持所有 postgres 数据类型。 pgx地址&#xff1a; https://github.com/jackc/pgx 最简单的接入方式是自定义一个logger&#xff0c; 然后注入到pgx&#xff0c; 完整示…...

ubuntu20.04 安装mysql(8.x)

安装mysql命令 sudo apt-get install mysql-server安装完毕后&#xff0c;立即初始化密码 sudo mysql -u root # 初次进入终端无需密码ALTER USER rootlocalhost IDENTIFIED WITH caching_sha2_password BY yourpasswd; # 设置本地root密码设置mysql远程登录 设置远程登录账…...

ChatGPT升级至GPT-4 Turbo:性能升级同时更为经济

ChatGPT升级至GPT-4 Turbo&#xff1a;性能升级同时更为经济 随着技术的进步&#xff0c;ChatGPT迎来了其最新的迭代版本——GPT-4 Turbo。这一最新版本不仅在性能上得到了显著提升&#xff0c;而且在成本效益上也更加引人注目。 性能提升 GPT-4 Turbo带来了诸多改进&#x…...

Android 粒子喷泉动效

一、前言&#xff1a; 在学习open gl es实现动效的时候&#xff0c;打算回顾了一下用普通的2D坐标系实现粒子效果和 open gl 3d 坐标系的区别&#xff0c;以及难易程度&#xff0c;因此本篇以Canvas 2D坐标系实现了一个简单的demo。 粒子动效原理&#xff1a; 粒子动效本质上…...

fast.ai 深度学习笔记(一)

深度学习 2&#xff1a;第 1 部分第 1 课 原文&#xff1a;medium.com/hiromi_suenaga/deep-learning-2-part-1-lesson-1-602f73869197 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 来自 fast.ai 课程的个人笔记。随着我继续复习课程以“真正”理解它&#xff0c;这…...

【机器学习】Ubuntu系统下CUDA驱动卸载及重装

目录 背景 驱动卸载 驱动安装 CUDA驱动安装 安装nvidia-smi 背景 这里包含显卡驱动和CUDA驱动&#xff0c;在如下场景下&#xff0c;我们需要卸载显卡驱动并重新安装。 在某些情况下需要对显卡驱动进行升级某些情况下&#xff08;如重启&#xff0c;或者调整系统配置等&a…...

相机图像质量研究(8)常见问题总结:光学结构对成像的影响--工厂调焦

系列文章目录 相机图像质量研究(1)Camera成像流程介绍 相机图像质量研究(2)ISP专用平台调优介绍 相机图像质量研究(3)图像质量测试介绍 相机图像质量研究(4)常见问题总结&#xff1a;光学结构对成像的影响--焦距 相机图像质量研究(5)常见问题总结&#xff1a;光学结构对成…...

【MySQL】数据库基础 -- 详解

一、什么是数据库 存储数据用文件就可以了&#xff0c;为什么还要弄个数据库? 一般的文件确实提供了数据的存储功能&#xff0c;但是文件并没有提供非常好的数据&#xff08;内容&#xff09;的管理能力&#xff08;用户角度&#xff09;。 文件保存数据有以下几个缺点&…...

零基础学Python之整合MySQL

Python 标准数据库接口为 Python DB-API&#xff0c;Python DB-API为开发人员提供了数据库应用编程接口。 不同的数据库你需要下载不同的DB API模块&#xff0c;例如你需要访问Oracle数据库和Mysql数据&#xff0c;你需要下载Oracle和MySQL数据库模块。 DB-API 是一个规范. 它…...

股票均线的使用方法和实战技术,看涨看空的均线形态与案例教学

一、教程描述 本套教程讲解了14种均线的特殊形态&#xff0c;通过直观图形以及大量案例的教学&#xff0c;将深奥、繁琐的均线变得生动与具体&#xff0c;广大投资者在认真学习以后&#xff0c;可以学会均线的使用方法&#xff0c;掌握最强的均线应用实战技术。本套教程不仅适…...

服务器被黑,安装Linux RootKit木马

前言 疫情还没有结束&#xff0c;放假只能猫家里继续分析和研究最新的攻击技术和样本了&#xff0c;正好前段时间群里有人说服务器被黑&#xff0c;然后扔了个样本在群里&#xff0c;今天咱就拿这个样本开刀&#xff0c;给大家研究一下这个样本究竟是个啥&#xff0c;顺便也给…...

【数据结构与算法】【腾讯阿里链表面试题】算法题--链表易懂版讲解

&#x1f389;&#x1f389;欢迎光临&#x1f389;&#x1f389; &#x1f3c5;我是苏泽&#xff0c;一位对技术充满热情的探索者和分享者。&#x1f680;&#x1f680; &#x1f31f;特别推荐给大家我的最新专栏《Spring 狂野之旅&#xff1a;底层原理高级进阶》 &#x1f680…...

3d渲染100农场如何使用?渲染100邀请码1a12

3d渲染农场通常用于电影、动画或视觉效果的渲染&#xff0c;本文以广受好评的渲染100农场为例&#xff0c;来讲解它的使用方法。 1、注册账号 前往渲染100官网(http://www.xuanran100.com/?ycode1a12)注册账号&#xff0c; 新用户注册记得填邀请码1a12&#xff0c;有30元大礼…...

【数据结构和算法】--- 基于c语言排序算法的实现(2)

目录 一、交换排序1.1 冒泡排序1.2 快速排序1.2.1 hoare法1.2.2 挖坑法1.2.3 前后指针法 1.3 快速排序优化1.3.1 三数取中法选key1.3.2 递归到小的子区间使用插入排序 1.4 快排非递归版 二、归并排序2.1 归并排序2.1.1 递归版2.1.2 非递归版 一、交换排序 基本思想&#xff1a…...

ORACLE的 软 软 软 解析!

在海鲨数据库架构师精英群里,有位朋友说ORACLE 有 软软软解析. 就是把执行计划缓存在客户端里,从而避免去服务端找执行计划. 他给了个设置方法, Weblogic console->datasource->connectionPool Statement Cache Type >LRU Statement Cache Size100 CURSOR_NUMBER …...

【模板】k 短路 / [SDOI2010] 魔法猪学院

题目背景 注&#xff1a;对于 k k k 短路问题&#xff0c;A* 算法的最坏时间复杂度是 O ( n k log ⁡ n ) O(nk \log n) O(nklogn) 的。虽然 A* 算法可以通过本题原版数据&#xff0c;但可以构造数据&#xff0c;使得 A* 算法在原题的数据范围内无法通过。事实上&#xff0c…...

【Make编译控制 08】CMake动静态库

目录 一、编译动静态库 二、链接静态库 三、链接动态库 前情提示&#xff1a;【Make编译控制 07】CMake常用命令-CSDN博客 有些时候我们编写的源代码并不需要将他们编译生成可执行程序&#xff0c;而是生成一些静态库或动态库提供给第三方使用&#xff0c;所以我们需要用到…...

05 06 Verilog基础语法与应用讲解

05. 1. 位操作 计数器实验升级&#xff0c;设计8个LED灯以每个0.5s的速率循环闪烁&#xff08;跑马灯&#xff09; 1.1 方法1&#xff1a;使用移位操作符<<来控制led灯的循环亮灭 设计代码 Verilog中&#xff0c;判断操作的时候不加位宽限定是可以的&#xff0c;比如i…...

css2复合选择器

一.后代&#xff08;包含&#xff09;选择器&#xff08;一样的标签可以用class命名以分别&#xff09; 空格表示 全部后代 应用 二.子类选择器 >表示 只要子不要孙 应用 三.并集选择器 &#xff0c;表示 代表和 一般竖着写 应用 四.伪类选择器&#xff08;包括伪链接…...

新版MQL语言程序设计:键盘快捷键交易的设计与实现

文章目录 一、什么是快捷键交易二、使用快捷键交易的好处三、键盘快捷键交易程序设计思路四、键盘快捷键交易程序具体实现1.界面设计2.键盘交易事件机制的代码实现 一、什么是快捷键交易 操盘中按快捷键交易是指在股票或期货交易中&#xff0c;通过使用快捷键来进行交易操作的…...

数据结构之基数排序

基数排序的思想是按组成关键字的各个数位的值进行排序&#xff0c;它是分配排序的一种。在该排序方法中把一个关键字 Ki看成一个 d 元组&#xff0c;即       K1i,K2i,,Kdi 其中&#xff0c;0≤ Kji<r&#xff0c;i1~ n&#xff0c;j1~d。这里的r 称为基数。若关键字是…...

区间dp 笔记

区间dp一般是先枚举区间长度&#xff0c;再枚举左端点&#xff0c;再枚举分界点&#xff0c;时间复杂度为 环形石子合并 将 n 堆石子绕圆形操场排放&#xff0c;现要将石子有序地合并成一堆。 规定每次只能选相邻的两堆合并成新的一堆&#xff0c;并将新的一堆的石子数记做该…...

MySQL-SQL优化

文章目录 1. SQL性能分析1.1 SQL执行频率1.2 慢查询日志1.3 profile详情1.4 explain 2. SQL优化2.1 Insert 优化2.2 Group By 优化2.3 Order By 优化2.4 Limit 优化2.5 Count() 优化2.6 Update 优化 3. 拓展3.1 请你说一下MySQL中的性能调优的方法&#xff1f;3.2 执行 SQL 响应…...

详细了解ref和reactive.

这几天看到好多文章标题都是类似于&#xff1a; 不用 ref 的 xx 个理由不用 reactive 的 xx 个理由历数 ref 的 xx 宗罪 我就很不解&#xff0c;到底是什么原因导致有这两批人&#xff1a; 抵触 ref 的人抵触 reactive 的人 看了这些文章&#xff0c;我可以总结出他们的想法…...

使用Linux docker方式快速安装Plik并结合内网穿透实现公网访问

文章目录 1. Docker部署Plik2. 本地访问Plik3. Linux安装Cpolar4. 配置Plik公网地址5. 远程访问Plik6. 固定Plik公网地址7. 固定地址访问Plik 本文介绍如何使用Linux docker方式快速安装Plik并且结合Cpolar内网穿透工具实现远程访问&#xff0c;实现随时随地在任意设备上传或者…...

Redis Centos7 安装到启动

文章目录 安装Redis启动redis查看redis状况连接redis服务端 安装Redis 1.下载scl源 yum install centos-release-scl-rh2.下载redis yum install rh-redis5-redis 3. 创建软连接 1.cd /usr/bin 2. In -s /opt/rh/rh-redis5/root/usr/bin/redis-server ./redis-server 3. …...

「数据结构」二叉搜索树1:实现BST

&#x1f387;个人主页&#xff1a;Ice_Sugar_7 &#x1f387;所属专栏&#xff1a;Java数据结构 &#x1f387;欢迎点赞收藏加关注哦&#xff01; 实现BST &#x1f349;二叉搜索树的性质&#x1f349;实现二叉搜索树&#x1f34c;插入&#x1f34c;查找&#x1f34c;删除 &am…...

可达鸭二月月赛——基础赛第六场(周五)题解,这次四个题的题解都在这一篇文章内,满满干货,含有位运算的详细用法介绍。

姓名 王胤皓 T1 题解 T1 题面 T1 思路 样例输入就是骗人的&#xff0c;其实直接输出就可以了&#xff0c;输出 Hello 2024&#xff0c;注意&#xff0c;中间有一个空格&#xff01; T1 代码 #include<bits/stdc.h> using namespace std; #define ll long long int …...

ELFK日志采 - QuickStart

文章目录 架构选型ELKEFLK ElasticsearchES集群搭建常用命令 Filebeat功能介绍安装步骤Filebeat配置详解filebeat常用命令 Logstash功能介绍安装步骤Input插件Filter插件Grok Filter 插件Mutate Filter 插件常见的插件配置选项&#xff1a;Mutate Filter配置案例&#xff1a; O…...

微信小程序的图片色彩分析,窃取网络图片的主色调

1、安装 Mini App Color Thief 包 包括下载包&#xff0c;简单使用都有&#xff0c;之前写了&#xff0c;这里就不写了 网址&#xff1a;微信小程序的图片色彩分析&#xff0c;窃取主色调&#xff0c;调色板-CSDN博客 2、 问题和解决方案 问题&#xff1a;由于我们的窃取图片的…...

Leetcode 121 买卖股票的最佳时机

题意理解&#xff1a; 给定一个数组 prices &#xff0c;它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。 你只能选择 某一天 买入这只股票&#xff0c;并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。 返回你可以从这笔交…...

SQL语言复习-----1

1&#xff0c;前言 SQL是计算机的一门基础语言&#xff0c;无论在开发还是数据库管理上都是非常重要&#xff0c;最近总结归纳了一下相关知识&#xff0c;记录如下。 2&#xff0c;归纳 SQL是结构化查询语言。 关系数据库有三级模式结构。 基本表和视图一样都是关系。 举例…...

爬虫2—用爬虫爬取壁纸(想爬多少张爬多少张)

先看效果图&#xff1a; 我这个是爬了三页的壁纸60张。 上代码了。 import requests import re import os from bs4 import BeautifulSoupcount0 img_path "./壁纸图片/"#指定保存地址 if not os.path.exists(img_path):os.mkdir(img_path) headers{ "User-Ag…...

学习Android的第九天

目录 Android Button 按钮 基本的按钮 StateListDrawable 范例 使用颜色值绘制圆角按钮 自制水波纹效果 Android ImageButton 图片按钮 ImageButton 不同状态下的 ImageButton Android RadioButton 单选按钮 RadioButton 获得选中的值 Android Button 按钮 在 And…...

课时21:内置变量_脚本相关

2.4.1 脚本相关 学习目标 这一节&#xff0c;我们从 基础知识、简单实践、小结 三个方面来学习 基础知识 脚本相关的变量解析 序号变量名解析1$0获取当前执行的shell脚本文件名2$n获取当前执行的shell脚本的第n个参数值&#xff0c;n1…9&#xff0c;当n为0时表示脚本的文…...