Unity优化总结(持续更新)

2023-11-06

工欲善其事,必先利其器。优先利用性能分析工具快速找出性能瓶颈,从瓶颈入手分析性能问题产生原因,可以事半功倍。

尽量减少占用的内存(资源体积)和CPU(计算量),首先着重减少总量才能更好的进行后续细节的优化。总量降低后,性能依旧有问题,那么可以考虑时间空间转换的手段。

一般情况下,GPU比CPU富余,内存比CPU富余,磁盘比内存富余,分线程比主进程富余。所以一般都是GPU换CPU,内存换CPU,磁盘换内存,利用多线程分担主进程的压力。

比如利用GPU Instance可以减少CPU的压力。利用对象池缓存,可以省略加载资源、实例化、销毁实例、卸载资源的步骤,可以明显降低CPU的消耗。

利用Loading进度条按需加载资源,可以减少内存峰值,大量节约内存。利用分线程进行计算,可以分担主进程的压力。

 

根据自己实践优化总结,这个持续更新,遇到新的东西会记录起来


设置相关

1.垂直同步

关闭垂直同步ProjectSetting-> Quality  VSync Count选成Don't Sync

2.帧率设置

设置最高帧率Application.targetFrameRate

3.物理更新

可以设置Fixed timestep减少物理更新

4.分辨率:

适当降低分辨率

很多2k分辨率手机,我们可以动态设置为1080,尤其对那些屏幕分辨率高,cpu,gpu性能差的手机提升明显

5.碰撞层检测

ProjectSetting-> physics里面有个layer collision matrix,根据项目实际情况勾选可生效的层碰撞

6.增量gc

这个是在2019.4版本有,就在playersetting设置,这个gc就会很平缓,不会突然卡一下那种


纹理相关(3d)

1.纹理格式

效果可以的情况下,android使用etc,etc2,ios使用pvrtc

如果效果达很差也不能用rgba32,虽然可以使用rgb16,但是遇到渐变的时候会出问题,这时可以尝试astc这种格式(我项目在用,抛弃了低端机类似5s这些)

2.纹理尺寸:

在移动设备上的贴图最大要控制在1024和512大小,可少量使用2048大小的贴图,以1024、512大小贴图为主。

角色的纹理需要比较精细,可以把头发,衣服,皮肤,武器分离适合的尺寸纹理

可以使用这个工具查看纹理“场景检查工具

3.关闭read/write功能

一般没用到换装功能基本不会用到这个,而且内存会大一倍

4.小物件的纹理合并,并使用同一个材质球

5.Mipmap

Mipmap 会增加游戏包体的大小和占用一定量的内存,但在游戏中Mipmap的渲染可以减少显存带宽,降低渲染压力,随着相机的推远贴图会随之切换成低像素的体贴,从而节省资源开支

5.texture streaming

streaming流加载贴图mipmap,意思就是用到哪一级mipmap只加载这一级的,上面说到使用mipmap会增加内存,也有团队为了减少内存,从而关闭了mipmap。这就会导致另一个问题,美术的贴图非常精细,在UI中近距离观察效果很好,可是一旦摄像机拉远,就会出现“噪点”很难看。 所以mipmap一定要打开。所以unity2018.2中提供了streaming流加载贴图mipmap,意思就是用到哪一级mipmap只加载这一级的,其他级的mipmap不加载具体可以看下面链接mipmap优化

用法:需要动态加载mipmap纹理勾选texture streaming,根据需求动态设置内存大小就ok

6.设置最高质量mipmap

QualitySettings.masterTextureLimit

对于低端机来说可以降低采样率,对于那种ui和场景结合,然后场景模糊的可以设置,这样大大提交性能

//0表示正常尺寸 //1表示降低1/2//2表示降低1/4 //3表示降低1/8//4表示降低1/16

QualitySettings.masterTextureLimit = 4;

7.减少使用透明贴图

透明贴图对gpu消耗大,

具体原理可以看看移动gpu原理性能分析和建议都有,说得很详细,建议看看

https://zhuanlan.zhihu.com/p/112120206


角色场景模型mesh

1.减面

对场景模型减面优化是最常见的优化操作。主要是去掉对模型造型没有影响的面,用尽可能少的面数表达清楚模型的结构和造型。比如:物件非关节点及物件背面、内部不会看见的面删掉,这里提供一个"场景检查工具"

2.合并模型(小范围内才能使用)

合并同一小范围内的非交互类的静态小物件,同时合并小物件的贴图。这样可以减少DRAW CALL的数量。一组大小形状不同的石头,如果同一个物体,然后距离很远,然后合并就没什么意义,可能负优化

3.LOD

建筑和复杂的物件用LOD模型和远处剔除来减少同屏面数。地形的LOD系统也可以对地形的面数做很大的优化。

4.模型的重复利用

相同的多个物件在unity内复制使用,复制的多个物体在引擎计算上算一个物体。但也不可复制太多个,太多会对内存带来很大压力。相同的物件太多,建议把几个合并成一组做为一个Object,多做几组,再进行复制。参考②。

5.地形优化

如果是用unity自带的地形工具制作的地形,可以用T4M插件转化成T4M格式地形,设置一个顶点值转化后可以对地形优化很多。T4M也可以设置lod模型。

6.网格碰撞

尽可能不用mesh collider,要用的时候可以让美术简化一个mesh专做碰撞,而不是再原有基础上加meshcollider

7.关闭模型read/write

粒子系统通常需要动态地修改其粒子的顶点属性,所以用到粒子系统的mesh不能关闭read/write

场景中需要动态合并网格需要read/write

角色中需要换装合并网格需要read/write

8.分场景加载

例如:主界面场景很大可以切割多个场景,通过add方式加载场景,不用的时候卸载


场景相关

1.批处理

Unity提供了三种批次合并的方法,分别是Static Batching,GPU Instancing和Dynamic Batching。它们的原理分别如下:
Static Batching,将静态物体集合成一个大号vbo提交,但是只对要渲染的物体提交其IBO。这么做不是没有代价。比如说,四个物体要静态批次合并前三个物体每个顶点只需要位置,第一套uv坐标信息,法线信息,而第四个物体除了以上信息,还多出来切线信息,则这个VBO会在每个顶点都包括所有的四套信息,毫无疑问组合这个VBO是要对CPU和显存有额外开销的。要求每一次Static Batching使用同样的material,但是对mesh不要求相同。

Dynamic Batching将物体动态组装成一个个稍大的vbo+ibo提交。这个过程不要求使用同样的mesh,但是也一样要求同样的材质。但是,由于每一帧CPU都要将每个物体的顶点从模型坐标空间变换到组装后的模型的坐标空间,这样做会带来一定的计算压力。所以对于Unity引擎,一个批次的动态物体顶点数是有限制的。

GPU Instancing是只提交一个物体的mesh,但是将多个使用同种mesh和material的物体的差异化信息(包括位置,缩放,旋转,shader上面的参数等。shader参数不包括纹理)组合成一个PIA提交。在GPU侧,通过读取每个物体的PIA数据,对同一个mesh进行各种变换后绘制。这种方式相比static和dynamic节约显存,又相比dynamic节约CPU开销。但是相比这两种批次合并方案,会略微给GPU带来一定的计算压力。但这种压力通常可以忽略不计。限制是必须相同材质相同物体,但是不同物体的材质上的参数可以不同。

所以Unity默认策略是优先static,其次gpu instancing,最后dynamic。当然如果顶点数过于巨大(比如渲染它几千颗使用同种mesh的树),那么gpu instancing或许比static batching是一个更加合适的方案。

静态批处理和动态批处理

2.GPU Instancing

提高图形性能的另一个好办法是使用GPU Instancing。GPU Instancing的最大优势是可以减少内存使用和CPU开销。当使用GPU Instancing时,不需要打开批处理,GPU Instancing的目的是一个网格可以与一系列附加参数一起被推送到GPU。要利用GPU Instancing,您必须使用相同的材质,且可以传递额外的参数到着色器,如颜色,浮点数等。

适用于不是静态,没有进行批处理的对象

例如:场景里面有很多箱子,可以被打爆,这种情况可以使用

3.光源“Important”个数

建议1个,一般为方向光。“Important”个数应该越小越少。个数越多,drawcall越多。

4.Pixel Light数目

建议1-2个。

5.场景烘焙

效果可以情况下光照图尽可能小,场景不接受实时光照,实时光照只给主角

6.尽可能地使用prefab

2018版本开始有prefab嵌套的功能,做出prefab防止资源冗余问题,也可以降低内存带宽的负担

7.提高场景资源复用率

动态加载,场景里面所有东西都保存预设,把场景数据保存配置表,加载的时候都是读取配置动态加载预设,唯一好处就是可以实现不同场景公用预设

整个场景打包,把公用的东西都设置标签例如:fbx,材质球

8.场景加载

当前一个场景还未释放的时候,切换到新的场景。这时候由于两个内存叠加很容易达到内存峰值。解决方案是,在屏幕中间遮盖一个Loading场景。在旧的释放完,并且新的初始化结束后,隐藏Loading场景,使之有效的避开内存大量叠加超过峰值

流程:旧场景->空场景(loading场景)->新场景


粒子特效

1.屏幕上的最大粒子数

建议小于200个粒子。

2.每个粒子发射器发射的最大粒子数

建议不超过50个。

3.粒子大小

粒子的size应该尽可能地小。因为Unity的粒子系统的shader无论是alpha test还是alpha blending都是一笔不小的开销。同时,对于非常小的粒子,建议粒子纹理去掉alpha通道。

4.不要开启粒子的碰撞功能

5.粒子特效shader用mobile,特殊需求只能加shader

6.特效显示规则

一个特效里面分开很多部分,根据性能设置来显示部分特效“相关链接

7.贴图和shader选用

能使用Additive和黑色背景的特效图(不透明),取代alpha blend+透明贴图

8.关于粒子制作优化

如果单个粒子其实完全可以不用使用粒子脚本,如果只是简单旋转可以通过脚本进行实现

如果一个特效需要十几张不同的贴图,这就要看看是否真的合理

特效性能是个重灾区

这些很考验特效制作人的功力


动画优化

1.动画压缩格式

Optimal对性能最好,但随着设备的提升,Keyframe Reduction和Optimal的加载效率提升已不十分明显

Optimal压缩方式可能会降低动画的视觉质量,因此,是否最终选择Optimal压缩模式,还需根据最终视觉效果的接受程度来决定。

2.默认不开启Resample Curves选项

Unity官方给的建议是开启,但是开启会增大内存,所以在动画没有问题的情况下建议关闭该选项。

3.减少帧信息的精度

将帧信息精度减少为小数点后四位,网上大多数文章也是给出的是小数点后三位,但是优化到小数点后三位导致我们游戏一些角色的披风抖动时会穿帮,所以精度优化到了小数点后四位。  

4.优化未改变的Rotation、Position序列帧和剔除Scale序列帧

如果需要用到Scale变化就在骨骼节点上加关键字区分。Position、Rotation有很多骨骼节点其实并未发生变化,但是由于我们Animation.Compression这两个优化值设置的比较小,所以这里我们手动优化掉没有变化的Position、Rotation序列帧,只留头尾两帧,保证Position和Rotation初始值正确,这么处理一下会降不少内存

相关工具参考


音频优化

1.格式使用
音效、语音:ogg
背景音乐:mp3

2.导入器设置
ForceToMono:根据项目实际对音乐的效果要求而定,一般语音、音效勾选,长音乐看情况;
CompressionFormat:Vorbis
SampleRateSetting:语音、音效选OverrideSampleRate的22050KHz就足够了,保留初始音质可选PreserveSampleRate

LoadType: 对于内存压力大的项目,首选Streaming

相关链接


UI优化

1.drawcall优化

drawcall不是越少越好,如果ui很多,但是drawcall很少,那就是占用很多显存宽带,也会导致发热

一般都是处理应该合并但是没有合并的ui

优化方向,详细查看这个链接

  • 空的image和透明的image(有自带sprite调颜色透明)都改掉换成EmptyRaycast
  • 尽可能不用mask或者mask2d(有些必须用的没办法),这个会引起drawcall无法合并

  • Ui排版

  • 资源适当冗余可以减少drawcall

  • 图集整理

  • 一些复杂的ui适当加canvas

2.ui重建

什么引起uirebuild,可以理解为整个ui就是一个网格,凡是引起网格改变就要rebuild

例如ui移动位置,大小改变,文字改变这些都会引起rebuild

根据重建的频率来处理,尤其战斗中的小地图,飘字,血条,都是网格重建最多的

这些可以单独抽出一个canvas

3.RayCast

屏蔽没必要的raycast也是性能消耗

4.循环滚动列表

这个参考循环列表加个回调就可以满足大部分需求

参考案例

5.字体相关

字体尽量使用一种,其他特殊字体可以使用图片字

图片字生成工具

6.ui动画优化

用shader实现效果代替animation和dotween,因为dotween和aniamtion都是会引起网格重建,例如旋转,进度条

具体链接

7.尽可能少图集带进战斗里面,战斗中的图集尽量保持两张左右(战斗ui和头像)

8.大图脱离图集使用rawimage(背景图,尺寸偏大的图片)

9.图集尽可能在1024*1024范围内,尽可能使用九宫格

   正常按照1920*1080切图,放到图集里面,整到1024*1024一般问题不大

10.关于冗余图或者图集放的不规范可以使用工具来进行优化

图集工具

11.图集关掉mipmap和read/write功能,这两个都会增大内存

12.图集导入设置相关

 链接

13.运行时动态图集

运行的时候,把需要用到的sprite合成一张图集,这样可以减少宽带,降低drawcall

演示demo

14.ui显示隐藏

1、如果该UI界面开启的频率很低,可考虑直接通过Instantiate/Destroy来进行切换;

2、如果该UI界面使用较为频繁,可尝试通过Active/Deactive来代替Instantiate/Destroy操作,从而降低UI切换时的性能开销;

3、如果该UI界面使用非常频繁,则可尝试直接改变UI界面位置的方式来移进/移出相机视域体,从而来极大提升UI界面的切换效率。

15.ui粒子

使用ui粒子避免层级问题导致不同ui得穿插

ui粒子链接


序列化优化

1.使用protobuf来处理配置表

相对xml,json,lua来说序列化速度快,可以看看这个工具excel转protobuf工具

2.使用性能更好的Json

NewtonJson库的GC量以及耗时最低


效果优化

1.屏幕效果,后处理优化 链接

2.阴影优化,镜面反射优化 链接

3.下雨天效果优化 链接

4.特效扭曲效果  链接

5.深度图优化(景深之类的) 链接


材质球和shader优化

1.pass

减少不必要的pass,单个shader最好不要超过3个

2.减少standard shader

这个shader的变体是个噩梦,占内存,可以考虑根据美术需求写surface shader

如果要使用,只能官网下载对应版本standard,修改一下shader,要关掉没用的shader_feature,比如:_PARALLAXMAP、SHADOWS_SOFT、DIRLIGHTMAP_COMBINED DIRLIGHTMAP_SEPARATE、_DETAIL_MULX2、_ALPHAPREMULTIPLY_ON;另外要去掉多余的pass

3.surface shader

注意关掉不用的功能,比如:noshadow、noambient、novertexlights、nolightmap、nodynlightmap、nodirlightmap、nofog、nometa、noforwardadd等

4.shader变量类型选择

用fixed、half代替float,建立shader统一类型(fixed效率是float的4倍,half是float的2倍)

5.添加宏开关

shader_feature、multi_compile,并将宏开关

如果某些效果真机丢失,其实就是变体丢失,建议使用multi_compile,这个会把变体全部打进去

性能设置的时候可以根据配置开启

6.材质设置属性优化

使用属性块代替直接修改属性 相关链接

7.材质球设置参数会导致材质球无法合并渲染

例如:有个物件爆炸,加入爆炸面片都是单独使用单个相同材质球,这时候如果单个面片执行材质球参数变化会导致全部实例化一个新材质球,导致材质球无法合并

解决方法:实例化一个材质球赋值给所有面片,材质球参数变化只处理实例化的材质球,这样子不会引起材质球不合并问题

8.粒子shader多个pass无法合并

粒子特效上多个pass尽量少用


内存泄漏

资源内存泄漏都是可以找到源头,堆内存泄漏是比较难查,下面是堆内存泄漏的经验

堆内存泄漏


代码优化

1.在Update里面一直new

例子:每次update都new list(keys)来遍历定时器和移除定时器

因为foreach下不能移除字典数据,所以用这种new keys

//错误写法
public class ErrorInvoke
{
    Dictionary<string, InvokeData> dic = new Dictionary<string, InvokeData>();

    void Update()
    {
        List<string> list = new List<string>(dic.Keys);
        for(int i=0;i<list.Count;i++)
        {
            //满足情况就移除字典
        }
    }
}

解决方案:用列表来存储相关定时器,update只遍历列表,字典存储列表的引用就好


//修改之后写法
public class FixInvoke
{
    Dictionary<string, object> dic = new Dictionary<string, object>();
    List<InvokeData> list = new List<InvokeData>();

    void Update()
    {
        for(int i=list.Count;i-->0;)
        {
            //满足条件移除列表移除字典
        }
    }
}

2.太多装箱和拆箱

这个东西不用说太多就是目标类型->object装箱,object->目标类型拆箱

这个用的最多可能就是事件系统,我发送事件里面可以有多个参数,这些参数类型不定,然后到最后消息回调里面进行类型转换,频繁的装箱拆箱会引起内存问题,可以使用避免装箱拆箱的事件系统

我同事写的事件事件系统全部用parma object[],因为战斗和ui之间的通信通过事件来,如果一直update来发送事件,装箱拆箱很频繁,我是不建议这么写事件系统

可以参考这个事件系统https://blog.csdn.net/SnoopyNa2Co3/article/details/84971510

3.遍历列表移除

很多情况我们遍历列表来更新数据,如果数据已经没用的情况要从list移除

很多情况的写法是这样的,把移除的存起来,遍历完再移除

如果数据没有先后顺序问题的情况可以下面优化

存起来移除的代码

public class Temp1
{
    List<datat> list = new List<datat>();

    List<datat> removeList = new List<datat>();

    void Update()
    {
        datat temp;
        for (int i=0;i<list.Count;i++)
        {
            temp = list[i];
            if(temp.Remove)
            {
                removeList.Add(temp);
            }
        }
        if(removeList.Count > 0)
        {
            for(int i=0;i<removeList.Count;i++)
            {
                list.Remove(removeList[i]);
            }
            removeList.Clear();
        }
    }
}

下面是优化过的代码

public class Temp2
{
    List<datat> list = new List<datat>();

    void Update()
    {
        datat temp;
        for (int i = list.Count; i-->0 ;)
        {
            temp = list[i];
            if (temp.Remove)
            {
                list.RemoveAt(i);
            }
        }
    }
}

4.关于反射的使用

反射有什么好处,其实就是少写一些代码,方便一点

就例如:后端返回的协议号和对应的proto,来进行序列化数据

1.游戏初始化的时候进行绑定

2.就是用工具进行绑定代码的生成

反射着东西能不用尽量不用

5.频繁GetComponent

一般来说初始化的时候才会GetComponent,如果在update里面出现GetComponent或者频繁,这代码肯定有问题

尤其UI上面出现这种基本都是要改。拒绝没必要的性能消耗

6.统一update和lateupdate

就是游戏里面只有挂MonoBehaviour脚本,里面的update和lateupdate驱动整个游戏

update里面遍历100次比100个MonoBehaviour脚本 update效率更高

7.尽量减少MonoBehaviour使用

正常游戏逻辑都能代替MonoBehaviour,除非一些用到一些特殊接口,例如onaniamtorik之类的

8.对于不太重要的列表数据,需要update处理,可以用分帧处理

9.关于回调delegate,使用完立刻设null,防止某些写法导致内存泄漏

10.Unity tag对比

if(other.tag == a.tag)改为other.CompareTag(a.tag).因为other.tag为产生180B的GC Allow.

11.对象缓存

我们可以把一些必要的对象缓存起来,在Unity中,类似于GameObject.Find , GetComponent,transform,camera.Main这类的函数,会产生较大的消耗

12.对象池(一般项目都会有)

13.Struct 与 Class 选择

Struct 在栈中不产生 GC,class 在堆中,会产生 GC。对 Struct 的结点修改时,修改完以后记得重新赋值。因为 Struct 赋值是 copy而不是引用,修改完以后,以前的不生效。

 堆栈的空间有限,对于大量的逻辑的对象,创建类要比创建结构好一些。

结构表示轻量对象,并且结构的成本较低,适合处理大量短暂的对象。

在表现抽象和多级别的对象层次时,类是最好的选择。

大多数情况下该类型只是一些数据时,结构是最佳的选择。

14.string的优化

stringbuilder用不习惯,推荐使用zstring零gc,写法简单

传送口https://github.com/871041532/zstring

15.注意log的消耗

debug打印cpu消耗很高,注意加宏或者自己封装一下打印模块

16.应尽量为类或函数声明为sealed

IL2CPP就sealed的类或函数会有优化,变虚函数调用为直接函数调用。详见《IL2CPP OPTIMIZATIONS: DEVIRTUALIZATION》

17.减少Dictionary的冗余访问

我们常习惯编写这样的代码:

if(myDictionary.Contains(oneKey))
{
    MyValue myValue = myDictionary[oneKey];
   // ...
}

但其可减少冗余的哈希次数,优化为:

MyValue myValue;
if(myDictionary.TryGetValue(oneKey, out myValue))
{
    // ...
}

18.应减少UnityEngine.Object的null比较

因为Unity overwrite掉了Object.Equals(),《CUSTOM == OPERATOR, SHOULD WE KEEP IT?》也说过unityEngineObject==null事实上和GetComponent()的消耗类似,都涉及到Engine层面的机制调用,所以UnityEngine.Object的null比较,都会有少许的性能消耗

19.关于实现思路问题

代码实现千千万万种,必须多想想,就怕头脑一热就写代码,需要冷静分析思考

下面给个真实存在的反例,有些代码不看不知道,一看吓一跳

主要功能用管理器管理所有角色部位阴影

看代码就知道又什么问题

1.多了没必要的字符串Contains判断

2.直接update来执行unityaction(用于不同角色阴影位置更新,功能可能不一样)(unityaction性能一般)

改法

管理器只管理阴影面片取出和回收,每个角色都有一个阴影控制器,自己管理自己的东西(可以重载功能)

这样子代码清晰,而且管理方便,这有点类似ecs思想,不过没有狠彻底

    public void RemoveShadow(string roleName)
    {
        List<string> toDelete = new List<string>();
        foreach(KeyValuePair<string,GameObject> pair in shadows)
        {
            if(pair.Key.Contains(roleName))
            {
                if (null != pair.Value)
                {
                    pair.Value.SetActive2(false);
                    notUseShadows.Add(pair.Value);
                }
                toDelete.Add(pair.Key);
            }
        }
        for(int i = 0; i < toDelete.Count; i++)
        {
            shadows.Remove(toDelete[i]);
        }

        updateActions.Remove(roleName);
    }

    public void Update()
    {
        foreach(UnityAction action in updateActions.Values)
        {
            action();
        }
    }

20.使用多线程,线程以及unity交互

可以减少不是非常必要的逻辑在主线程运行

关于线程和unity交互可以看这个链接https://blog.csdn.net/SnoopyNa2Co3/article/details/108546696

21.关于委托Delegate, Action,UnityAction

使用Delegate, Action性能比unityaction快4-5倍,除了UGUI里的EventSystem都是基于unityaction实现的,使用之外,其他地方没有使用的必要

22.关于Input.touches

每次在对其调用时,都会new一个数组touches,从而造成一定的堆内存分配

Allocates temporary variables分配临时变量

避免Input.touches的频繁使用以防造成堆内存的额外占用

23.关于Linq相关函数的调用

Linq在执行过程中会产生一些临时变量,而且会用到委托(lambda 表达式)。如果使用委托作为条件的判定方法,时间开销就会很高,并且会造成一定的堆内存分配。所以在一般的Unity游戏项目开发中不推荐使用Linq相关的函数

24.使用更高效的异步/等待UniTask

Unity中使用协同程序通常是解决某些问题的好方法,但它也带来了一些缺陷:

  • 没有返回值,在处理需要返回值时候,非常容易陷入回调地狱

  • 协调程序使错误处理变得困难

所以在当前的项目中使用了UniTask来代替Unity coroutine使用。

UniTask解决了C#Task异步不能执行某些API的问题,将C# async/awake异步编程模型完美的带入了Unity中(需要Unity2018.3/C#7.0+),在项目中的实践,UniTask带来了简洁高效的体验。

https://github.com/Cysharp/UniTask


 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Unity优化总结(持续更新) 的相关文章

  • 面试:js 延迟加载方式

    相关知识点 js 延迟加载 也就是等页面加载完成之后再加载 JavaScript 文件 js 延迟加载有助于提高页面加载速度 一般有以下几种方式 defer 属性 async 属性 动态创建 DOM 方式 使用 setTimeout 延迟方
  • 《Java性能调优实战》笔记(一)Java编程性能调优、多线程性能优化

    文章目录 一 Java性能调优概述 1 1 性能调优标准 1 2 制定性能调优策略 二 Java编程性能调优 2 1 字符串 2 2 正则表达式 2 3 ArrayList和LinkedList的选择 2 4 使用Stream提高遍历集合效
  • Unity游戏性能分析最终指南 02

    设置每帧时间预算 帧率 fps 并不是衡量游戏稳定体验的理想指标 考虑以下情况 在运行时的前0 75s内渲染了59帧 然后接下来的1帧需要0 25s才能渲染完毕 虽然是60fps 但实际上会让玩家感觉卡顿 这是需要设置帧时间预算的重要原因之
  • 腾讯业务百万数据 6s 响应,APIJSON 性能优化背后的故事

    最近发生了一件大事儿 APIJSON 再也不用担心被人质疑性能问题了哈哈 某周三腾讯 CSIG 某项目组 已经用 APIJSON 做完一期 突然反馈了查询大量数据性能急剧下降的情况 某张表 2 3KW 记录 用 APIJSON 万能通用接口
  • 如何设计一个分布式系统去分析3亿条数据?

    V xin ruyuanhadeng获得600 页原创精品文章汇总PDF 目录 从一个新闻门户网站案例引入 推算一下你需要分析多少条数据 黄金搭档 分布式存储 分布式计算 这篇文章聊一个话题 什么是分布式计算系统 一 从一个新闻门户网站案例
  • 【项目经验】:项目中下拉框数据太多造成页面卡顿(二)

    一 项目需求 下拉框下拉列表数据是由后端返回的 而且他会变化 所以数据不是写死的而且数据量大 上一篇博客http t csdn cn sSNTa我们是用的数据懒加载的方式 这次我们使用远程搜索的方式解决这个问题 二 用到的组件方法介绍 fi
  • Python Performance Matters

    Python Performance Matters cmd 不要重复定义数据类型 yappi cpu yappi cpu by Emery Berger Strange Loop 2022 cmd python3 m cProfile 不
  • WPF性能优化经验总结

    原文地址 WPF性能优化经验总结 痴鸟 博客园 WPF性能优化一 Rendering Tier 1 根据硬件配置的不同 WPF采用不同的Rendering Tier做渲染 下列情况请特别注意 因为在这些情况下 即使是处于Rendering
  • Java 性能优化的 50 个细节

    前言 在JAVA程序中 性能问题的大部分原因并不在于JAVA语言 而是程序本身 养成良好的编码习惯非常重要 能够显著地提升程序性能 1 尽量在合适的场合使用单例 使用单例可以减轻加载的负担 缩短加载的时间 提高加载的效率 但并不是所有地方都
  • DNS 预解析是什么?怎么实现?

    DNS优化 在介绍dns prefetch之前 先要提下当前对于DNS优化主流方法 一般来说 一次DNS解析需要耗费 20 120ms 所以为了优化DNS 我们可以考虑两个方向 减少DNS请求次数 缩短DNS解析时间dns prefetch
  • spark性能优化调优指导性文件

    1 让我们看一下前面的核心参数设置 num executors 10 20 executor cores 1 2 executor memory 10 20 driver memory 20 spark default parallelis
  • 深聊性能测试,从入门到放弃之: Windows系统性能监控(三)任务管理器介绍及使用。

    任务管理器 1 引言 2 任务管理器 2 1 打开方式 2 2 介绍 2 2 1 定义 2 2 2 进程 2 2 3 性能 2 2 4 应用历史记录 2 2 5 启动 2 2 6 用户 2 2 7 详细信息 2 2 8 服务 3 总结 1
  • 最常见的8个Android内存泄漏问题及解决方法

    作者 午后一小憩 在 Android 开发中 内存泄漏是一个常见的问题 这个问题可能会导致应用程序变慢 崩溃或者消耗大量的内存 最终导致设备性能下降 什么是内存泄漏 内存泄漏指的是应用程序中存在一些对象或者资源无法被垃圾回收器回收 导致内存
  • MySQL索引优化(超详细)

    Mysql索引优化 1 索引介绍 1 1 什么时MySQL的索引 MySQL官方对于索引的定义 索引是帮助MySQL高效获取数据的数据结构 MySQL在存储数据之外 数据库系统中还维护着满足特定查找算法的数据结构 这些数据结构以某种引用 指
  • React重新渲染的触发机制及其优化策略

    React是一个用于构建用户界面的JavaScript库 它的核心特点之一是使用虚拟DOM Virtual DOM 来实现高效的组件渲染 那组件重新渲染的机制是如何呢 基于这些机制 如果进行优化呢 虚拟DOM是一个用JavaScript对象
  • 什么是javascript内存泄漏?以及解决方法

    什么是javascript内存泄漏 以及解决方法 一 什么是javascript内存泄漏 二 常见的内存泄漏 1 意外的全局变量 通常是变量未被定义或者胡乱引用了全局变量 2 计时器 3 闭包 4 事件监听未被移除 5 console lo
  • 史上最全Android性能优化方案解析

    Android中的性能优分为以下几个方面 布局优化 网络优化 安装包优化 内存优化 卡顿优化 启动优化 一 布局优化 布局优化的本质就是减少View的层级 常见的布局优化方案如下 在LinearLayout和RelativeLayout都可
  • Android 性能优化系列:崩溃原因及捕获

    文章目录 崩溃的基本原因 抛出异常导致崩溃分析 AMS 如何承接应用的异常信息上报 对于 native crash 系统如何做处理 系统如何处理 ANR 异常数据 addErrorToDropBox DropBoxManager 在 Cra
  • 【性能优化】MySql查询性能优化必知必会

    本文内容主要包括以下几个方面 分析查询SQL MySQL查询优化器 数据库存储结构 索引 索引维护 索引设计 SQL优化 表结构设计 分库分表 查询功能架构设计 分析查询SQL MySQL提供了一个性能分析工具 EXPLAIN 它可以帮助我
  • 性能分析与调优: Linux 内存观测工具

    目录 一 实验 1 环境 2 vmstat 3 PSI 4 swapon 5 sar 6 slabtop 7 numstat 8 ps 9 top 10 pmap 11 perf 12 bpftrace 二 问题 1 接口读写报错 2 sl

随机推荐

  • C++参数传递

    C 参数传递 目录 C 参数传递 1 基本参数传递方式 按值传递 指针传递 引用传递 总结 2 指针与引用区别 3 参数为指针的指针或指针的引用 1 void func char a 2 void func1 char a 3 void f
  • Apache SSHD服务端:ssh2、sftp 登录验证超时时间、连接断开超时时间

    通过ssh2 sftp协议连接基于Apache MINA SSHD的服务时 长时间不用连接会自动断开 我们来看一下默认断开时间和如何修改断开时间 超时报错日志 Disconnecting ServerSessionImpl username
  • ubuntu 服务管理运行程序 sysv-rc-conf

    sysv rc conf是一个强大的服务管理程序 Ubuntu运行级别Linux 系统任何时候都运行在一个指定的运行级上 不同的运行级的程序和服务都不同 所要完成的工作和要达到的目的不同 系统可以在这些运行级之间进行切换 以完成不同的工作
  • socket包长度问题: send recieve(转载)

    一个包没有固定长度 以太网限制在46 1500字节 1500就是以太网的MTU 超过这个量 TCP会为IP数据报设置偏移量进行分片传输 现在一般可允许应用层设置8k NTFS系 的缓冲区 8k的数据由底层分片 而应用看来只是一次发送 win
  • C语言 标识符、合法常量、转义字符

    一 合法标识符 用户定义的合法标识符需满足以下两个要求 标识符只能由字母 数字和下划线组成 标识符不能以数字开头 二 合法常量 整型常量 十进制 10 八进制 017 以0开头 不能出现8 9 十六进制 0xA1 以0x开头 实型常量 强调
  • Mac安装python

    一 下载python 官网地址 https www python org downloads macos 目前主流版本应该是3 7 3 8 3 9 文章以3 8为例 作者已将下载包放到网盘 方便取用 网盘地址 https pan baidu
  • Ngrok 内网穿透

    一 配置Ngrok 准备内网穿透 1 到ngrok官网去注册一个号 国内也有一个sunny ngrok 但是我用来几次全部失败了 所以推荐国外的 网址是 https ngrok com 2 我注册的时候面临验证码刷不出来 所以建议直接用gi
  • MVB通讯机制

    MVB通信只能是主从式通信 主站配置调度表 轮询各从站 从站应答主站命令 采用广播式发送 MVB网络上其他节点过滤地接收网络上的信息 首发 待学习指导
  • elastic-job详解(一):数据分片

    数据分片的目的在于把一个任务分散到不同的机器上运行 既可以解决单机计算能力上限的问题 也能降低部分任务失败对整体系统的影响 elastic job并不直接提供数据处理的功能 框架只会将分片项分配至各个运行中的作业服务器 其实是Job实例 部
  • html表格怎么绑定数据类型,Excel中表格添加数据标签及设置格式的操作方法

    Excel图表以其直观的展示功能深受用户喜爱 但有些初学者对于生成图表后如何添加数据标签有所困扰 今天 学习啦小编就教大家在Excel中表格添加数据标签及设置格式的操作方法 Excel中表格添加数据标签及设置格式的操作步骤如下 1 在Exc
  • Google地图现可按照路况给出出行时间

    在 Google Maps 查询出行路线的时候 不管是公交还是自驾 它都会告诉你一个大概的全部行程需要的时间 不过如果你是在下午 5 点左右从北京出发的话 那个时间显然是痴人说梦 由于 Google Maps 本身在很多城市已经有了交通流量
  • 谷粒商城--整合Elasticsearch和商品的上架

    整合Elasticsearch和商品的上架 一 整合ES ES常用概念 索引 类型 文档是什么 倒排索引 相关度分数score的计算 安装ES和Kibana 快速安装 ES kibana 初步检索 cat ES的增删改查 新增文档 put新
  • 第二天-03-安卓手机的入侵实验

    安卓手机入侵实验 要求 电脑主机与手机模拟器或者真机在当前环境下 网络是畅通的 相互之间可以进行通信 如何进行测试网络环境 我们首先需要确定IP linux通过终端命令 ip a 或者 ifconfig windown下 win加r输入cm
  • Apollo使用404错误问题

    在使用spring项目接入携程 apollo 的时候 报了一个错误 Cause status code 404 Could not find config for namespace appId housing102 cluster def
  • 优化基于FPGA的深度卷积神经网络的加速器设计

    英文论文链接 http cadlab cs ucla edu cong slides fpga2015 chen pdf 翻译 卜居 转载请注明出处 http blog csdn net kkk584520 article details
  • 【开发工具】WebStorm 前端开发神器菜鸟必备,全网最稳定靠谱的安装教程 一镜到底、全程图文并茂、通俗易懂!

    个人主页 极客小俊 作者简介 web开发者 设计师 技术分享博主 希望大家多多支持一下 我们一起进步 如果文章对你有帮助的话 欢迎评论 点赞 收藏 加关注 介绍 WebStorm号称最智能的前端开发IDE 适用于前端开发和相关技术的集成开发
  • Unity世界坐标转换屏幕坐标(详解)

    我们先通过简单的操作实现一下基础的UI跟随物体移动的功能 首先我们在场景中建立一个Canvas并且添加一个图片作为按钮 之后我们添加一个3d物体作为跟随目标 效果如下图所示 我们配置一下UICanvas的属性 书写对应的自定义类并添加至UI
  • 【QT实战】第三章 将类中的成员函数放在多线程中执行

    作者主页 凉开水白菜 作者简介 共同学习 互相监督 热于分享 多加讨论 一起进步 专栏目录 零基础学QT 文章导航篇 专栏资料 https pan baidu com s 192A28BTIYFHmixRcQwmaHw 提取码 qtqt 点
  • css3平移、旋转、倾斜、缩放、动画效果的实现

    HTML代码 div class button div div class canResize esdrtgyjikodrtgujiokpsedtgyhij div div class transition div ul li li li
  • Unity优化总结(持续更新)

    工欲善其事 必先利其器 优先利用性能分析工具快速找出性能瓶颈 从瓶颈入手分析性能问题产生原因 可以事半功倍 尽量减少占用的内存 资源体积 和CPU 计算量 首先着重减少总量才能更好的进行后续细节的优化 总量降低后 性能依旧有问题 那么可以考