让前端飞

由移动端浏览器上QQ定制化分享,引发的性能优化

2018-12-07  本文已影响8人  尤小小

在移动端浏览器上分享微找找寻人给QQ好友

产品提了个新需求,要求在移动端浏览器上打开微找找寻人页面后,可以分享给QQ好友。这个需求提的合情合理,没毛病。那就开工吧。

腾讯移动WEB开发平台 上了解到可以使用他们的api来定制化分享,但是存在系统和设备型号的限制。另外还可以使用 meta 同样可以达到该接口的作用,这个方法甚好。

官网的demo:

 <meta itemprop="name" content="这是分享的标题"/>
 <meta itemprop="image" content="http://imgcache.qq.com/qqshow/ac/v4/global/logo.png" />
 <meta name="description" itemprop="description" content="这是要分享的内容" />

结合实际情况搞起来

在我们微找找寻人的项目里,目前配置了微信朋友、朋友圈分享,我们针对专题页、详情页这种特殊页面可以自定义分享,其它页面可以走默认分享。这次要增加的QQ分享,我考虑统一放到这个分享插件里处理,可以通过区分环境来决定是否要执行QQ分享的代码。

当前的项目是个单页面应用,定制化的分享最好通过动态插入的形式会好些。

实现:

    let doc = document;
    let head = doc.head || (doc.getElementsByTagName("head")[0] || doc.documentElement);
    function setShareMata(itemprop, content, name) {
        
        
        let node = doc.createElement("meta");
        node.setAttribute("itemprop", itemprop);
        node.content = content;
        node.name = name;
    
        head.appendChild(node);
    }    

    // 设置qq分享mate标签
    setShareMata('name', self.share.title, 'title');
    setShareMata('description', self.share.desc.substr(0, 50), 'description');
    setShareMata('image', self.share.imgUrl, 'img');                  

self 是经过处理的分享对象

给DOM提提速

从浏览器的性能优化上分析,浏览器渲染引擎和JS引擎是分开执行的,并且JS 的运行速度比DOM快的多这个特征,我们尽量减少对DOM的操作,让JS去给DOM分压。

DocumentFragment 接口表示一个没有父级文件的最小文档对象。它被当做一个轻量版的 Document 使用,用于存储已排好版的或尚未打理好格式的XML片段。最大的却别是因为 DocumentFragment 不是真实DOM树的一部分,它的变化不会引起DOM树的重新渲染的操作,且不会导致性能等问题。

上面我们直接用appendChild去往 head 标签去拼接目标内容,这样做当然可以,但却不够优雅。相比之下,DOM Fragment可以在维护性能的同时用更加结构化的方法去达成。
现在我们使用DOM Fragment 来改写上面的例子:

    let doc = document;
    let head = doc.head || (doc.getElementsByTagName("head")[0] || doc.documentElement);
    // 创建一个DOM Fragment对象作为容器
    let createContent = doc.createDocumentFragment();

    // 设置qq分享mate标签
    setShareMata('name', self.share.title, 'title');
    setShareMata('description', self.share.desc.substr(0, 50), 'description');
    setShareMata('image', self.share.imgUrl, 'img');

    function setShareMata(itemprop, content, name) {
        // meta此时可以通过DOM API去创建
        let node = doc.createElement("meta");

        node.setAttribute("itemprop", itemprop);
        node.content = content;
        node.name = name;
        // 像操作真实DOM一样操作DOM Fragment对象
        createContent.appendChild(node)
    }                        

    // 内容处理好了,最后再触发真实DOM的更改
    head.appendChild(createContent)

这两种写法都可以运行出同样的结果。可以看出如果是大批量的去从操作真实的DOM,使用DOM Fragment对象的性能会更好。这种结构化的特征,在优秀框架中jQuery、Vue的源码中也在使用。

到此QQ分享的功能就大功告成了,QQ定制化分享和DOM Fragment的操作get到了没有?

上一篇 下一篇

猜你喜欢

热点阅读