1.背景介绍
最近有很多企业都在对移动设备进行SEO优化,提高网站流量,但是由于市场份额小,移动端浏览器用户占比远低于PC端,因此需要考虑到移动端的兼容性问题。本文主要针对一些前端开发人员经常遇到的移动端兼容性问题,分享下自己对于解决方案的思路和理解,希望能够帮助到读者们。
2.核心概念与联系
首先,了解一下移动设备上的一些常用设备和软件特征。
- 浏览器类型和版本:移动端浏览器类型众多,包括Android、iOS、微信内置浏览器、UC浏览器等等。这些浏览器各自适用的浏览器内核也不同,例如基于WebKit的浏览器,例如Chrome Mobile、Safari Mobile、QQ浏览器等;而一些新型浏览器内核,如UC浏览器使用了基于Chromium内核,使得它们拥有原生应用级别的交互体验。
- 屏幕分辨率:移动设备的屏幕大小和分辨率都会变化,常见的分辨率有720p(1280x720)、1080p(1920x1080)、2K(2560x1440)。
- 操作系统及版本:目前主流的移动设备操作系统包括Android和iOS,他们分别对应着不同的手机厂商,但其内部也有所不同,比如某些Android手机支持的最低系统版本是5.0 Lollipop,而iOS设备则往往会更加保守一些,仅支持iOS9或更高版本的操作系统。
- 网络环境:移动设备的网络连接速度较慢,甚至会因特殊原因出现断网情况,因此需要设计出应对各种异常情况的相应策略。
知道了以上基本概念后,再来看看我们面临的问题,主要包括以下几点:
- 在移动端渲染性能:移动端的内存空间相对PC端来说要小很多,每一个像素点都需要耗费较大的资源,因此要求尽可能减少页面的重绘和重排,从而提高渲染效率,尤其是在动画和交互方面。
- CSS特性兼容性:CSS一直是前端工程师不可缺少的一环,它提供了丰富的样式属性,可以用来美化网页,但由于移动端设备的硬件条件限制,导致有的CSS属性在移动端并不兼容。例如移动端没有鼠标指针,因此hover事件不会触发;移动端的触摸屏只能识别简单的点击事件,双击缩放等操作不支持。
- 动态图形显示:因为移动端设备的性能和存储能力有限,因此需要合理利用图像压缩技术,尽可能降低图像的质量和文件体积,并且提供相应的图片加载机制,避免卡顿或花屏。
- 消息推送和游戏优化:移动端消息推送和游戏的体验非常重要,因此有必要研究相关技术和优化措施,提升用户的留存率和游戏玩家的游戏体验。
- 用户输入交互:移动端的用户交互方式要灵活,方便快捷,因此设计上要考虑到便利性和可用性,提升用户体验。
综合以上几个方面,可以发现移动端的兼容性问题不是一帆风顺的,我们需要站在巨人的肩膀上,结合当前设备的特性和场景,找寻解决方案,才能取得更好的效果。
3.核心算法原理和具体操作步骤以及数学模型公式详细讲解
本部分我们将分享如何提升移动端兼容性,并通过一些技术细节来阐述我们的思路。
3.1 渲染性能优化
3.1.1 不可见元素渲染优化
不可见元素渲染其实是指一些影响页面结构的标签,例如
3.1.2 使用transform和opacity动画渲染优化
移动端的渲染性能一般来说要比PC端差很多,因此移动端的动画也要尽可能地优化。通常情况下,使用translate、scale、rotate等transform属性来完成动画效果,因为它们都不会引起页面回流,因此动画性能上比setTimeout或setInterval更佳。
另外,我们还可以使用HWAcceleration的canvas渲染技术来提升动画性能。这个技术允许使用GPU加速的API来加速绘制2D图形,目前只有Android和iOS上支持。
3.1.3 避免大型复杂组件渲染
如果页面中有比较大且复杂的组件,那么可能会消耗掉很多的CPU计算资源,导致页面渲染变慢,这时就需要注意一些性能优化技巧,譬如限制组件的层级、缓存数据、减少DOM操作、动画时使用requestAnimationFrame函数来控制刷新频率等。
3.1.4 图片懒加载
移动端图片的数量很多,如果每次都把所有图片都加载过来,会影响页面的响应时间,因此通常我们采用图片懒加载的方式,只加载当前展示的图片,当用户滑动到其他区域才去加载图片。这样就可以实现降低页面加载的时间,提高用户体验。
另外,除了图片懒加载之外,我们还可以通过CSS3里面的object-fit属性来设置图片的缩放模式,可以让图片保持完整比例、拉伸填充,达到最佳的显示效果。
3.1.5 本地缓存
移动端的用户都是有着较强的流量限制的,因此不能依赖于服务端,需要本地缓存来提升页面加载速度,这其中包括图片缓存、模板缓存等等。
为了防止缓存过期失效,我们还可以在离线状态下及时更新缓存,通过CacheStorage/ServiceWorker也可以做到这一点。
3.1.6 滚动性能优化
移动端页面滚动的情况要比PC端复杂很多,这其中包含页面的布局重排和渲染,因此要做好相应的优化工作,譬如减少列表项的个数、使用局部渲染技术、对元素进行缓存等等。
另外,对于手指拖动滚动的页面,我们可以引入惯性滚动来改善用户的感受。
3.1.7 小结
渲染性能优化其实是一门蛮重要的技术,通过一些简单的方法,我们可以提升页面的响应速度和渲染性能,进而提升用户的体验。
3.2 CSS特性兼容性处理
CSS是一种基于样式的语言,它提供了丰富的样式属性,可以用来美化网页,但由于移动端设备的硬件条件限制,导致有的CSS属性在移动端并不兼容。以下是一些常见的CSS兼容性问题及其解决方案。
3.2.1 Flexbox布局
Flexbox是CSS3新增的一个模块,可以方便地进行弹性布局,适用于移动端布局需求。
不过,Flexbox布局在移动端仍然存在一些兼容性问题,例如,不支持min-height、max-height、aspect-ratio、flex-basis、order属性。因此,为了兼容性考虑,我们可以选择使用其他布局方式,如绝对定位+浮动布局,或者inline-block+绝对定位布局。
<!-- flexbox布局 -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Flexbox</title>
<style type="text/css">
.container {
display: flex;
justify-content: center; /* 垂直居中 */
align-items: center; /* 水平居中 */
height: 100vh; /* 设置高度为视窗的高度 */
}
.item {
width: 200px;
height: 200px;
background-color: red;
}
</style>
</head>
<body>
<div class="container">
<div class="item"></div>
<!--... -->
</div>
<!-- 非flexbox布局 -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>非flexbox布局</title>
<style type="text/css">
#container {
position: relative;
}
#item {
float: left;
margin: 0 10px;
width: 200px;
height: 200px;
background-color: red;
}
</style>
</head>
<body>
<div id="container">
<div id="item"></div>
<!--... -->
</div>
</body>
</html>
</body>
</html>
3.2.2 rem单位
rem单位在手机端的兼容性问题较多,不建议使用rem作为单位,建议使用固定像素值作为宽度。
3.2.3 border-radius
border-radius在一些老旧的手机浏览器上兼容性较差,可以考虑用其它替代方案,譬如圆角矩形。
/* 示例 */
.button {
padding: 10px 20px;
color: white;
text-align: center;
background-color: blue;
border-radius: 5px; /* 替换成圆角矩形 */
font-size: 18px;
}
3.2.4 box-shadow
box-shadow在一些老旧的手机浏览器上兼容性较差,可以考虑不使用box-shadow,或对它的半径和颜色进行调整。
/* 示例 */
.card {
box-shadow: none; /* 不使用阴影 */
background-color: white;
}
/* 或对阴影进行微调 */
.card {
box-shadow: 0 2px 5px rgba(0,0,0,.3);
}
3.2.5 transform
transform在一些老旧的手机浏览器上兼容性较差,通常可以考虑不要使用该属性,或只使用transition动画。
/* 不使用transform属性 */
.avatar {
width: 50px;
height: 50px;
}
/* 只使用transition动画 */
.avatar {
transition: all 0.3s ease;
-webkit-transform: scale(1) rotate(0deg);
-moz-transform: scale(1) rotate(0deg);
-ms-transform: scale(1) rotate(0deg);
transform: scale(1) rotate(0deg);
}
.avatar:active {
-webkit-transform: scale(.9) rotate(360deg);
-moz-transform: scale(.9) rotate(360deg);
-ms-transform: scale(.9) rotate(360deg);
transform: scale(.9) rotate(360deg);
}
3.2.6 Webkit tap highlight取消点击高亮
Webkit tap highlight是一个手机端浏览器特有的样式,当用户点击某个元素的时候,会给这个元素添加一个暗淡的半透明遮罩层,模拟系统自带的反馈效果。
虽然这个效果很酷,但实际测试过程中发现,有些元素上手难度太大,而且对用户体验并无明显优势,因此可以考虑取消点击高亮。
a, button {-webkit-tap-highlight-color: transparent;}
input[type=submit] {-webkit-appearance: none;}
3.2.7 小结
CSS兼容性问题是一大块内容,这里只是做了一个概览,更详细的内容建议阅读W3C官方文档和移动端WEB开发相关的书籍。
3.3 JavaScript执行效率优化
JavaScript执行效率也是影响页面性能的关键因素,特别是在移动端。为了提升JavaScript的运行效率,我们需要注意以下几点:
3.3.1 函数的复用
JavaScript中的函数复用是提升运行效率的有效方法。函数复用可以避免重复定义相同的代码,进而减少解析和执行时间。同时,也可以避免多个函数之间命名冲突。
3.3.2 避免过多的DOM访问
在JavaScript中访问DOM节点也会消耗时间,因此需要注意避免过多的DOM访问。可以通过将DOM节点保存起来,一次性读取并修改,或者使用事件代理,即在父容器上绑定事件,子元素响应事件即可。
3.3.3 对象拷贝
在循环中频繁拷贝对象也是耗时操作,因此需要减少对象的拷贝次数。可以采用惰性拷贝的方法,即在需要时才真正拷贝对象。
3.3.4 小心eval函数
eval函数是动态创建代码执行的函数,具有很高的执行效率,但也容易被恶意攻击。为了安全起见,建议不要使用eval函数。
3.3.5 小结
JavaScript执行效率优化是非常重要的一环,只有通过一些优化措施,才能确保移动端web应用的快速、流畅的运行。
3.4 Canvas渲染优化
Canvas渲染技术主要是通过HTML5新增的画布技术,将位图绘制在网页上,对动画的表现力和性能有着极大的提升。为了更好地利用Canvas技术,提升渲染性能,我们需要注意以下几点:
3.4.1 Canvas元素的缓存
Canvas元素是页面中的一个图形元素,绘制的位图数据直接保存在Canvas元素对应的内存空间,因此绘制Canvas元素时,如果需要渲染相同的图形,不需要每次重新生成位图数据,只需通过缓存查找已经生成过的位图数据,这样可以提升性能。
3.4.2 数据缩放
在Canvas元素中绘制图形时,如果数据的大小超过Canvas的大小,就会发生“放大”现象,导致图形模糊。因此在渲染时,我们需要对数据的大小进行缩放,让它刚好适应Canvas的大小。
3.4.3 裁剪区
裁剪区是Canvas技术里面的一个概念,它允许我们在渲染前,先指定一个范围,然后只渲染这个范围内的图形。通过裁剪区的设定,可以提升渲染性能,因为可以减少绘制区域的大小。
3.4.4 小心动画
当我们在Canvas上进行动画绘制时,需要格外注意渲染的性能问题。绘制频繁的动画可能会导致浏览器掉帧,或者渲染失败,因此在渲染动画时,要合理使用动画帧数和动画刷新频率,控制动画的绘制次数。
3.4.5 小结
通过Canvas技术的优化,可以提升动画的渲染性能,进而提升页面的运行流畅性和响应速度。
3.5 网络通信优化
移动端设备的网络状况要比PC端差很多,因此移动端的网络通信也要对性能有比较高的要求。为了提升网络通信的性能,我们需要注意以下几点:
3.5.1 压缩传输数据
在移动端传输的数据越多,对传输速度的影响越大。因此在传输数据时,我们可以采用gzip或deflate算法对数据进行压缩,可以有效减少传输时间。
3.5.2 请求合并
同一个域名下的请求过多会对浏览器和服务器产生负担,因此建议将多个请求合并为一个请求,并对请求结果进行整合处理。
3.5.3 数据预加载
对于首页及其重要的内容页的静态资源,可以提前加载并缓存,以便快速打开页面。
3.5.4 小结
移动端的网络通信也需要考虑性能优化,否则用户体验不好。
4.具体代码实例与详细解释说明
最后,我想给大家分享几个实际项目中的例子,供大家参考。
4.1 SSR(Server-Side Render)与SEO
国内知名的SSP(Server-Side Pages)技术,比如京东、天猫、苏宁、网易等都采用SSR渲染页面,提高用户的访问速度。同时,为了获取更多的搜索引擎收录机会,厂商还通过多种手段去优化SEO,包括设置robots.txt文件、sitemap.xml文件等。
很多SSP公司为了追求SEO效果,会采用一些Hack,比如动态加载JS、静态化路由等。
例如:京东的降低初始加载时间的方法就是延迟加载静态资源,直到页面onload完成之后才加载,以减少对用户的白屏时间。同时,京东会通过HSTS(HTTP Strict Transport Security)协议,使SSL证书的生效时间短一些,以提升用户的访问速度。
另一方面,京东也会将页面的URL和链接转换为短链接,使搜索引擎更容易抓取到有效信息。此外,京东还会通过推送通知、站长中心、搜索管理等方式提升网站的互动性和吸引力,提升SEO效果。
总的来说,在爬虫抓取工具与SSR渲染技术的配合下,通过适当的SEO优化,既可以提升页面的访问速度和命中率,又能获得良好的用户体验。
4.2 Canvas动画
在移动端制作canvas动画,由于性能上的限制,传统的动画技术,如css动画、jQuery动画等无法满足。为了更好的性能体验,我们可以使用requestAnimationFrame来实现动画渲染,因为它可以保证动画平滑运行,并且保证绘制效率。
另外,我们还可以使用CSS3的transform、translate、opacity等属性来实现动画效果,但由于这些属性对canvas的渲染性能有所限制,因此还是推荐使用requestAnimationFrame来实现动画渲染。
举个例子,我们来实现一个简单的跑马灯效果:
<canvas id="fireworks" width="400" height="400"></canvas>
<script>
var canvas = document.getElementById("fireworks");
var context = canvas.getContext("2d");
function randomColor() {
return "rgb(" + Math.floor(Math.random()*255) + "," +
Math.floor(Math.random()*255) + "," +
Math.floor(Math.random()*255) + ")";
}
setInterval(function(){
// 随机清除画布
context.clearRect(0,0,canvas.width,canvas.height);
// 设置文字样式
context.font = '20px Arial';
// 随机写字母
for (var i = 0; i < 5; i++) {
context.fillStyle = randomColor();
context.fillText((String.fromCharCode(65+(i%26))),
Math.floor(Math.random()*(canvas.width-5*context.measureText((String.fromCharCode(65+(i%26)))).width)),
canvas.height-(20+i*30));
};
// 增加烟雾效果
for (var j = 0; j < 50; j++) {
context.beginPath();
context.arc(Math.floor(Math.random() * canvas.width),
Math.floor(Math.random() * canvas.height),
2, 0, Math.PI * 2, true);
context.closePath();
context.strokeStyle = randomColor();
context.stroke();
};
}, 16);
</script>
4.3 SVG渲染优化
SVG(Scalable Vector Graphics),中文可译作可缩放矢量图形,是一种矢量图形格式,它本身由标签及属性组成,可以轻松制作成任何类型的二维图形。移动端的渲染性能也非常差,因此我们需要对SVG进行渲染优化。
4.3.1 降低文件大小
SVG文件本身比较大,因此需要将文件大小降低到最小。有两种方法可以降低SVG文件的大小:
- svgo压缩插件:在webpack等构建工具中集成svgo插件,可以对SVG文件进行压缩。
4.3.2 压缩坐标
SVG文件中的坐标数据量很大,因此我们需要对SVG的坐标数据进行压缩,压缩后的文件大小将会变小。有两种方法可以对坐标进行压缩:
- 抽稀:可以根据屏幕像素密度,对SVG的坐标数据进行抽稀,将多个相邻的坐标点合并为一条直线。
- 变换坐标:通过缩放、旋转等方式对SVG的坐标数据进行变换,得到较为紧凑的SVG文件。
4.3.3 利用缓存
当用户打开同一张SVG文件时,我们需要对文件进行缓存,以提升性能。因此,我们需要在HTTP请求头中添加Etag或Last-Modified字段,以便浏览器可以缓存SVG文件。
4.3.4 小结
SVG渲染优化是一个非常有意义的优化工作。通过对SVG文件进行压缩、压缩坐标、利用缓存等方式,可以有效提升SVG文件的渲染性能,进而提升用户的体验。
5.未来发展方向与挑战
移动端兼容性问题是一个长期存在的话题,在这个领域还有许多值得探索的地方。
5.1 多终端适配
随着智能手机的普及,移动端的用户量也在不断扩大。因此,随着多终端竞争日益激烈,移动端的多终端适配也逐渐成为热议话题。多终端适配是一个具有挑战性的任务,因为它涉及到多个平台,每个平台都有自己的特性,比如屏幕分辨率、触控屏、摄像头、处理能力等等。
值得关注的是,近年来手机厂商陆续出台新品,这些手机会搭载各自的处理器,性能会有显著的差异。因此,我们需要在兼容性方面注重考虑不同平台的差异性,针对不同的平台分别设计优化方案。
5.2 ES6+的特性
越来越多的企业开始采用ES6+/TypeScript等最新技术栈,以期望能带来更加好的编码效率、更好的开发体验和更快的发布速度。这些新特性也会带来兼容性问题,因为一些老旧的浏览器不支持新的语法。因此,在兼容性方面,我们还需要时刻注意浏览器版本的迭代,尽量使用最新的语法特性。
5.3 大前端的冲击
随着移动端Web应用的火爆,越来越多的人开始担忧技术的下一个阶段,那就是大前端时代。对于开发者来说,新的技术革命正在催生一批全新的思维和技术体系,它将使开发者的编程习惯发生翻天覆地的变化。
未来的大前端将带来完全不同的开发模式和架构,为了适应这种开发模式,我们需要反思当前技术与理念,寻找新的突破口。
5.4 更加开放的生态圈
移动端由于受到严格的封闭环境,而这也促进了社区的蓬勃发展。随着人工智能、物联网、区块链、云计算的应用,人们开始越来越关注移动端开发的前景。这样的背景下,我们需要认识到开发者之间的竞争越来越激烈,而为了开发者的创新,我们需要开放更多的生态圈。
未来,移动端的生态将会变得越来越宽阔,我们需要跟上这股潮流,在这个新的生态中寻找突破口,打造一个开放、包容、创新的生态圈。
6.附录常见问题与解答
6.1 为什么要做移动端兼容性处理?
在移动互联网刚刚崛起的年代,移动端设备的市场份额和研发投入却远远落后于PC端。因此,移动端的兼容性问题一直是开发者关注的重点。相信移动端开发者的需求也会越来越多样化,需要开发者对兼容性问题的关注越来越深入。
移动端兼容性问题的根源是设备的软硬件条件的限制,一款产品在不同的设备上都要表现出不同的效果,因此开发者需要关心如何兼容不同设备,从而才能为客户提供令人满意的产品。
6.2 有哪些常见的移动端兼容性问题?
- 不可见元素渲染优化
- CSS特性兼容性处理
- JavaScript执行效率优化
- Canvas渲染优化
- 网络通信优化
6.3 如何提升移动端兼容性?
- 渲染性能优化:减少不必要的重绘和重排,使用transform、opacity、canvas等技术提升渲染效率;使用懒加载、缓存、localstorage等技术减少网络流量;使用事件委托来降低DOM访问;限制动画的层级和频率。
- CSS特性兼容性处理:兼容性处理一般可以分为三个方面,第一是HTML5新增的标签和属性的兼容性,第二是CSS的兼容性,第三是JavaScript的兼容性。
- JavaScript执行效率优化:减少不必要的DOM访问,对象拷贝,使用requestAnimationFrame函数来优化动画渲染;使用web worker等技术优化页面渲染;函数复用,移除eval等技术提升脚本执行效率。
- Canvas渲染优化:使用缓存、缩放、裁剪区、动画帧数优化渲染性能;降低文件大小、压缩坐标、利用缓存等技术提升加载性能。
- 网络通信优化:压缩传输数据,使用XHR2/fetch API优化网络请求;请求合并,数据预加载,利用HTTP缓存机制提升加载速度。
6.4 实战案例分析
- 提升移动端搜索引擎SEO优化:适当的SEO优化可以为移动端搜索引擎的收录提供帮助。通过设置robots.txt文件、sitemap.xml文件、百度主动提交、schema标记、多关键字建站、使用简洁的内容等方式,可以提升搜索引擎的收录,实现SEO优化。
- 播放视频优化:为了提升播放视频的性能,开发者可以减少不必要的重绘和重排,使用硬件加速、使用progressive streaming技术等方式提升播放速度。另外,对于短视频来说,可以考虑选择在应用层进行切割,降低用户等待时间。